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 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 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__':
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)
2153 prefix = env.scope_prefix
2154 entry.func_cname = \
2155 Naming.pyfunc_prefix + prefix + name
2156 entry.pymethdef_cname = \
2157 Naming.pymethdef_prefix + prefix + name
2158 if Options.docstrings:
2159 entry.doc = embed_position(self.pos, self.doc)
2161 Naming.funcdoc_prefix + prefix + name
2162 if entry.is_special:
2163 if entry.name in TypeSlots.invisible or not entry.doc or (entry.name in '__getattr__' and env.directives['fast_getattr']):
2164 entry.wrapperbase_cname = None
2166 entry.wrapperbase_cname = Naming.wrapperbase_prefix + prefix + name
2170 def declare_lambda_function(self, env):
2172 prefix = env.scope_prefix
2174 Naming.lambda_func_prefix + u'funcdef' + prefix + self.lambda_name
2175 entry = env.declare_lambda_function(func_cname, self.pos)
2176 entry.pymethdef_cname = \
2177 Naming.lambda_func_prefix + u'methdef' + prefix + self.lambda_name
2178 entry.qualified_name = env.qualify_name(self.lambda_name)
2182 def declare_arguments(self, env):
2183 for arg in self.args:
2185 error(arg.pos, "Missing argument name")
2187 env.control_flow.set_state((), (arg.name, 'source'), 'arg')
2188 env.control_flow.set_state((), (arg.name, 'initialized'), True)
2189 if arg.needs_conversion:
2190 arg.entry = env.declare_var(arg.name, arg.type, arg.pos)
2191 if arg.type.is_pyobject:
2192 arg.entry.init = "0"
2193 arg.entry.init_to_none = 0
2195 arg.entry = self.declare_argument(env, arg)
2197 arg.entry.is_self_arg = arg.is_self_arg
2199 if arg.is_self_arg or arg.is_type_arg or \
2200 (arg.type.is_extension_type and not arg.hdr_type.is_extension_type):
2201 arg.entry.is_declared_generic = 1
2202 self.declare_python_arg(env, self.star_arg)
2203 self.declare_python_arg(env, self.starstar_arg)
2205 def declare_python_arg(self, env, arg):
2207 if env.directives['infer_types'] != False:
2208 type = PyrexTypes.unspecified_type
2210 type = py_object_type
2211 entry = env.declare_var(arg.name, type, arg.pos)
2214 entry.init_to_none = 0
2215 entry.xdecref_cleanup = 1
2217 env.control_flow.set_state((), (arg.name, 'initialized'), True)
2219 def analyse_expressions(self, env):
2220 self.local_scope.directives = env.directives
2221 self.analyse_default_values(env)
2222 if self.needs_assignment_synthesis(env):
2223 # Shouldn't we be doing this at the module level too?
2224 self.synthesize_assignment_node(env)
2226 def needs_assignment_synthesis(self, env, code=None):
2227 # Should enable for module level as well, that will require more testing...
2228 if self.entry.is_lambda:
2230 if env.is_module_scope:
2232 return env.directives['binding']
2234 return code.globalstate.directives['binding']
2235 return env.is_py_class_scope or env.is_closure_scope
2237 def synthesize_assignment_node(self, env):
2240 while genv.is_py_class_scope or genv.is_c_class_scope:
2241 genv = genv.outer_scope
2243 if genv.is_closure_scope:
2244 rhs = ExprNodes.InnerFunctionNode(
2245 self.pos, pymethdef_cname = self.entry.pymethdef_cname)
2247 rhs = ExprNodes.PyCFunctionNode(
2248 self.pos, pymethdef_cname = self.entry.pymethdef_cname, binding = env.directives['binding'])
2250 if env.is_py_class_scope:
2251 if not self.is_staticmethod and not self.is_classmethod:
2254 self.assmt = SingleAssignmentNode(self.pos,
2255 lhs = ExprNodes.NameNode(self.pos, name = self.name),
2257 self.assmt.analyse_declarations(env)
2258 self.assmt.analyse_expressions(env)
2260 def generate_function_header(self, code, with_pymethdef, proto_only=0):
2262 sig = self.entry.signature
2263 if sig.has_dummy_arg or self.self_in_stararg:
2264 arg_code_list.append(
2265 "PyObject *%s" % Naming.self_cname)
2266 for arg in self.args:
2267 if not arg.is_generic:
2268 if arg.is_self_arg or arg.is_type_arg:
2269 arg_code_list.append("PyObject *%s" % arg.hdr_cname)
2271 arg_code_list.append(
2272 arg.hdr_type.declaration_code(arg.hdr_cname))
2273 if not self.entry.is_special and sig.method_flags() == [TypeSlots.method_noargs]:
2274 arg_code_list.append("CYTHON_UNUSED PyObject *unused")
2275 if sig.has_generic_args:
2276 arg_code_list.append(
2277 "PyObject *%s, PyObject *%s"
2278 % (Naming.args_cname, Naming.kwds_cname))
2279 arg_code = ", ".join(arg_code_list)
2280 dc = self.return_type.declaration_code(self.entry.func_cname)
2281 mf = " ".join(self.modifiers).upper()
2283 header = "static %s%s(%s)" % (mf, dc, arg_code)
2284 code.putln("%s; /*proto*/" % header)
2287 if (Options.docstrings and self.entry.doc and
2288 not self.entry.scope.is_property_scope and
2289 (not self.entry.is_special or self.entry.wrapperbase_cname)):
2290 docstr = self.entry.doc
2291 if docstr.is_unicode:
2292 docstr = docstr.utf8encode()
2294 'static char %s[] = "%s";' % (
2295 self.entry.doc_cname,
2296 split_string_literal(escape_byte_string(docstr))))
2297 if self.entry.is_special:
2299 "struct wrapperbase %s;" % self.entry.wrapperbase_cname)
2302 "static PyMethodDef %s = " %
2303 self.entry.pymethdef_cname)
2304 code.put_pymethoddef(self.entry, ";", allow_skip=False)
2305 code.putln("%s {" % header)
2307 def generate_argument_declarations(self, env, code):
2308 for arg in self.args:
2309 if arg.is_generic: # or arg.needs_conversion:
2310 if arg.needs_conversion:
2311 code.putln("PyObject *%s = 0;" % arg.hdr_cname)
2312 elif not arg.entry.in_closure:
2313 code.put_var_declaration(arg.entry)
2315 def generate_keyword_list(self, code):
2316 if self.signature_has_generic_args() and \
2317 self.signature_has_nongeneric_args():
2319 "static PyObject **%s[] = {" %
2320 Naming.pykwdlist_cname)
2321 for arg in self.args:
2323 pystring_cname = code.intern_identifier(arg.name)
2324 code.put('&%s,' % pystring_cname)
2327 def generate_argument_parsing_code(self, env, code):
2328 # Generate PyArg_ParseTuple call for generic
2329 # arguments, if any.
2330 if self.entry.signature.has_dummy_arg and not self.self_in_stararg:
2331 # get rid of unused argument warning
2332 code.putln("%s = %s;" % (Naming.self_cname, Naming.self_cname))
2334 old_error_label = code.new_error_label()
2335 our_error_label = code.error_label
2336 end_label = code.new_label("argument_unpacking_done")
2338 has_kwonly_args = self.num_kwonly_args > 0
2339 has_star_or_kw_args = self.star_arg is not None \
2340 or self.starstar_arg is not None or has_kwonly_args
2342 for arg in self.args:
2343 if not arg.type.is_pyobject:
2344 done = arg.type.create_from_py_utility_code(env)
2345 if not done: pass # will fail later
2347 if not self.signature_has_generic_args():
2348 if has_star_or_kw_args:
2349 error(self.pos, "This method cannot have * or keyword arguments")
2350 self.generate_argument_conversion_code(code)
2352 elif not self.signature_has_nongeneric_args():
2353 # func(*args) or func(**kw) or func(*args, **kw)
2354 self.generate_stararg_copy_code(code)
2357 positional_args = []
2359 for arg in self.args:
2360 arg_entry = arg.entry
2363 if not arg.is_self_arg and not arg.is_type_arg:
2365 kw_only_args.append(arg)
2367 positional_args.append(arg)
2369 kw_only_args.append(arg)
2370 elif not arg.is_self_arg and not arg.is_type_arg:
2371 positional_args.append(arg)
2373 self.generate_tuple_and_keyword_parsing_code(
2374 positional_args, kw_only_args, end_label, code)
2376 code.error_label = old_error_label
2377 if code.label_used(our_error_label):
2378 if not code.label_used(end_label):
2379 code.put_goto(end_label)
2380 code.put_label(our_error_label)
2381 if has_star_or_kw_args:
2382 self.generate_arg_decref(self.star_arg, code)
2383 if self.starstar_arg:
2384 if self.starstar_arg.entry.xdecref_cleanup:
2385 code.put_var_xdecref(self.starstar_arg.entry)
2387 code.put_var_decref(self.starstar_arg.entry)
2388 code.putln('__Pyx_AddTraceback("%s");' % self.entry.qualified_name)
2389 # The arguments are put into the closure one after the
2390 # other, so when type errors are found, all references in
2391 # the closure instance must be properly ref-counted to
2392 # facilitate generic closure instance deallocation. In
2393 # the case of an argument type error, it's best to just
2394 # DECREF+clear the already handled references, as this
2395 # frees their references as early as possible.
2396 for arg in self.args:
2397 if arg.type.is_pyobject and arg.entry.in_closure:
2398 code.put_var_xdecref_clear(arg.entry)
2399 if self.needs_closure:
2400 code.put_decref(Naming.cur_scope_cname, self.local_scope.scope_class.type)
2401 code.put_finish_refcount_context()
2402 code.putln("return %s;" % self.error_value())
2403 if code.label_used(end_label):
2404 code.put_label(end_label)
2406 def generate_arg_assignment(self, arg, item, code):
2407 if arg.type.is_pyobject:
2409 item = PyrexTypes.typecast(arg.type, PyrexTypes.py_object_type, item)
2411 code.putln("%s = %s;" % (entry.cname, item))
2412 if entry.in_closure:
2413 code.put_var_incref(entry)
2415 func = arg.type.from_py_function
2417 code.putln("%s = %s(%s); %s" % (
2421 code.error_goto_if(arg.type.error_condition(arg.entry.cname), arg.pos)))
2423 error(arg.pos, "Cannot convert Python object argument to type '%s'" % arg.type)
2425 def generate_arg_xdecref(self, arg, code):
2427 code.put_var_xdecref(arg.entry)
2429 def generate_arg_decref(self, arg, code):
2431 code.put_var_decref(arg.entry)
2433 def generate_stararg_copy_code(self, code):
2434 if not self.star_arg:
2435 code.globalstate.use_utility_code(raise_argtuple_invalid_utility_code)
2436 code.putln("if (unlikely(PyTuple_GET_SIZE(%s) > 0)) {" %
2438 code.put('__Pyx_RaiseArgtupleInvalid("%s", 1, 0, 0, PyTuple_GET_SIZE(%s)); return %s;' % (
2439 self.name, Naming.args_cname, self.error_value()))
2442 code.globalstate.use_utility_code(keyword_string_check_utility_code)
2444 if self.starstar_arg:
2446 kwarg_check = "unlikely(%s)" % Naming.kwds_cname
2448 kwarg_check = "%s" % Naming.kwds_cname
2450 kwarg_check = "unlikely(%s) && unlikely(PyDict_Size(%s) > 0)" % (
2451 Naming.kwds_cname, Naming.kwds_cname)
2453 "if (%s && unlikely(!__Pyx_CheckKeywordStrings(%s, \"%s\", %d))) return %s;" % (
2454 kwarg_check, Naming.kwds_cname, self.name,
2455 bool(self.starstar_arg), self.error_value()))
2457 if self.starstar_arg:
2458 code.putln("%s = (%s) ? PyDict_Copy(%s) : PyDict_New();" % (
2459 self.starstar_arg.entry.cname,
2462 code.putln("if (unlikely(!%s)) return %s;" % (
2463 self.starstar_arg.entry.cname, self.error_value()))
2464 self.starstar_arg.entry.xdecref_cleanup = 0
2465 code.put_gotref(self.starstar_arg.entry.cname)
2467 if self.self_in_stararg:
2468 # need to create a new tuple with 'self' inserted as first item
2469 code.put("%s = PyTuple_New(PyTuple_GET_SIZE(%s)+1); if (unlikely(!%s)) " % (
2470 self.star_arg.entry.cname,
2472 self.star_arg.entry.cname))
2473 if self.starstar_arg:
2475 code.put_decref_clear(self.starstar_arg.entry.cname, py_object_type)
2476 code.putln("return %s;" % self.error_value())
2479 code.putln("return %s;" % self.error_value())
2480 code.put_gotref(self.star_arg.entry.cname)
2481 code.put_incref(Naming.self_cname, py_object_type)
2482 code.put_giveref(Naming.self_cname)
2483 code.putln("PyTuple_SET_ITEM(%s, 0, %s);" % (
2484 self.star_arg.entry.cname, Naming.self_cname))
2485 temp = code.funcstate.allocate_temp(PyrexTypes.c_py_ssize_t_type, manage_ref=False)
2486 code.putln("for (%s=0; %s < PyTuple_GET_SIZE(%s); %s++) {" % (
2487 temp, temp, Naming.args_cname, temp))
2488 code.putln("PyObject* item = PyTuple_GET_ITEM(%s, %s);" % (
2489 Naming.args_cname, temp))
2490 code.put_incref("item", py_object_type)
2491 code.put_giveref("item")
2492 code.putln("PyTuple_SET_ITEM(%s, %s+1, item);" % (
2493 self.star_arg.entry.cname, temp))
2495 code.funcstate.release_temp(temp)
2496 self.star_arg.entry.xdecref_cleanup = 0
2498 code.put_incref(Naming.args_cname, py_object_type)
2499 code.putln("%s = %s;" % (
2500 self.star_arg.entry.cname,
2502 self.star_arg.entry.xdecref_cleanup = 0
2504 def generate_tuple_and_keyword_parsing_code(self, positional_args,
2505 kw_only_args, success_label, code):
2506 argtuple_error_label = code.new_label("argtuple_error")
2508 min_positional_args = self.num_required_args - self.num_required_kw_args
2509 if len(self.args) > 0 and (self.args[0].is_self_arg or self.args[0].is_type_arg):
2510 min_positional_args -= 1
2511 max_positional_args = len(positional_args)
2512 has_fixed_positional_count = not self.star_arg and \
2513 min_positional_args == max_positional_args
2515 code.globalstate.use_utility_code(raise_double_keywords_utility_code)
2516 code.globalstate.use_utility_code(raise_argtuple_invalid_utility_code)
2517 if self.num_required_kw_args:
2518 code.globalstate.use_utility_code(raise_keyword_required_utility_code)
2520 if self.starstar_arg or self.star_arg:
2521 self.generate_stararg_init_code(max_positional_args, code)
2523 # --- optimised code when we receive keyword arguments
2524 if self.num_required_kw_args:
2525 likely_hint = "likely"
2527 likely_hint = "unlikely"
2528 code.putln("if (%s(%s)) {" % (likely_hint, Naming.kwds_cname))
2529 self.generate_keyword_unpacking_code(
2530 min_positional_args, max_positional_args,
2531 has_fixed_positional_count,
2532 positional_args, kw_only_args, argtuple_error_label, code)
2534 # --- optimised code when we do not receive any keyword arguments
2535 if (self.num_required_kw_args and min_positional_args > 0) or min_positional_args == max_positional_args:
2536 # Python raises arg tuple related errors first, so we must
2537 # check the length here
2538 if min_positional_args == max_positional_args and not self.star_arg:
2542 code.putln('} else if (PyTuple_GET_SIZE(%s) %s %d) {' % (
2543 Naming.args_cname, compare, min_positional_args))
2544 code.put_goto(argtuple_error_label)
2546 if self.num_required_kw_args:
2547 # pure error case: keywords required but not passed
2548 if max_positional_args > min_positional_args and not self.star_arg:
2549 code.putln('} else if (PyTuple_GET_SIZE(%s) > %d) {' % (
2550 Naming.args_cname, max_positional_args))
2551 code.put_goto(argtuple_error_label)
2552 code.putln('} else {')
2553 for i, arg in enumerate(kw_only_args):
2555 pystring_cname = code.intern_identifier(arg.name)
2556 # required keyword-only argument missing
2557 code.put('__Pyx_RaiseKeywordRequired("%s", %s); ' % (
2560 code.putln(code.error_goto(self.pos))
2563 elif min_positional_args == max_positional_args:
2564 # parse the exact number of positional arguments from the
2566 code.putln('} else {')
2567 for i, arg in enumerate(positional_args):
2568 item = "PyTuple_GET_ITEM(%s, %d)" % (Naming.args_cname, i)
2569 self.generate_arg_assignment(arg, item, code)
2570 self.generate_arg_default_assignments(code)
2573 # parse the positional arguments from the variable length
2575 code.putln('} else {')
2576 self.generate_arg_default_assignments(code)
2577 code.putln('switch (PyTuple_GET_SIZE(%s)) {' % Naming.args_cname)
2579 code.putln('default:')
2580 reversed_args = list(enumerate(positional_args))[::-1]
2581 for i, arg in reversed_args:
2582 if i >= min_positional_args-1:
2583 if min_positional_args > 1:
2584 code.putln('case %2d:' % (i+1)) # pure code beautification
2586 code.put('case %2d: ' % (i+1))
2587 item = "PyTuple_GET_ITEM(%s, %d)" % (Naming.args_cname, i)
2588 self.generate_arg_assignment(arg, item, code)
2589 if min_positional_args == 0:
2590 code.put('case 0: ')
2591 code.putln('break;')
2593 if min_positional_args:
2594 for i in range(min_positional_args-1, -1, -1):
2595 code.putln('case %2d:' % i)
2596 code.put_goto(argtuple_error_label)
2598 code.put('default: ')
2599 code.put_goto(argtuple_error_label)
2604 if code.label_used(argtuple_error_label):
2605 code.put_goto(success_label)
2606 code.put_label(argtuple_error_label)
2607 code.put('__Pyx_RaiseArgtupleInvalid("%s", %d, %d, %d, PyTuple_GET_SIZE(%s)); ' % (
2608 self.name, has_fixed_positional_count,
2609 min_positional_args, max_positional_args,
2611 code.putln(code.error_goto(self.pos))
2613 def generate_arg_default_assignments(self, code):
2614 for arg in self.args:
2615 if arg.is_generic and arg.default:
2619 arg.calculate_default_value_code(code)))
2621 def generate_stararg_init_code(self, max_positional_args, code):
2622 if self.starstar_arg:
2623 self.starstar_arg.entry.xdecref_cleanup = 0
2624 code.putln('%s = PyDict_New(); if (unlikely(!%s)) return %s;' % (
2625 self.starstar_arg.entry.cname,
2626 self.starstar_arg.entry.cname,
2627 self.error_value()))
2628 code.put_gotref(self.starstar_arg.entry.cname)
2630 self.star_arg.entry.xdecref_cleanup = 0
2631 code.putln('if (PyTuple_GET_SIZE(%s) > %d) {' % (
2633 max_positional_args))
2634 code.put('%s = PyTuple_GetSlice(%s, %d, PyTuple_GET_SIZE(%s)); ' % (
2635 self.star_arg.entry.cname, Naming.args_cname,
2636 max_positional_args, Naming.args_cname))
2637 code.put_gotref(self.star_arg.entry.cname)
2638 if self.starstar_arg:
2640 code.putln("if (unlikely(!%s)) {" % self.star_arg.entry.cname)
2641 code.put_decref(self.starstar_arg.entry.cname, py_object_type)
2642 code.putln('return %s;' % self.error_value())
2645 code.putln("if (unlikely(!%s)) return %s;" % (
2646 self.star_arg.entry.cname, self.error_value()))
2647 code.putln('} else {')
2648 code.put("%s = %s; " % (self.star_arg.entry.cname, Naming.empty_tuple))
2649 code.put_incref(Naming.empty_tuple, py_object_type)
2652 def generate_keyword_unpacking_code(self, min_positional_args, max_positional_args,
2653 has_fixed_positional_count, positional_args,
2654 kw_only_args, argtuple_error_label, code):
2655 all_args = tuple(positional_args) + tuple(kw_only_args)
2656 max_args = len(all_args)
2658 code.putln("Py_ssize_t kw_args = PyDict_Size(%s);" %
2660 # the 'values' array collects borrowed references to arguments
2661 # before doing any type coercion etc.
2662 code.putln("PyObject* values[%d] = {%s};" % (
2663 max_args, ','.join('0'*max_args)))
2665 # assign borrowed Python default values to the values array,
2666 # so that they can be overwritten by received arguments below
2667 for i, arg in enumerate(all_args):
2668 if arg.default and arg.type.is_pyobject:
2669 default_value = arg.calculate_default_value_code(code)
2670 code.putln('values[%d] = %s;' % (i, arg.type.as_pyobject(default_value)))
2672 # parse the args tuple and check that it's not too long
2673 code.putln('switch (PyTuple_GET_SIZE(%s)) {' % Naming.args_cname)
2675 code.putln('default:')
2676 for i in range(max_positional_args-1, -1, -1):
2677 code.put('case %2d: ' % (i+1))
2678 code.putln("values[%d] = PyTuple_GET_ITEM(%s, %d);" % (
2679 i, Naming.args_cname, i))
2680 code.putln('case 0: break;')
2681 if not self.star_arg:
2682 code.put('default: ') # more arguments than allowed
2683 code.put_goto(argtuple_error_label)
2686 # now fill up the positional/required arguments with values
2688 if self.num_required_args or max_positional_args > 0:
2689 last_required_arg = -1
2690 for i, arg in enumerate(all_args):
2692 last_required_arg = i
2693 if last_required_arg < max_positional_args:
2694 last_required_arg = max_positional_args-1
2695 num_required_args = self.num_required_args
2696 if max_positional_args > 0:
2697 code.putln('switch (PyTuple_GET_SIZE(%s)) {' % Naming.args_cname)
2698 for i, arg in enumerate(all_args[:last_required_arg+1]):
2699 if max_positional_args > 0 and i <= max_positional_args:
2700 if self.star_arg and i == max_positional_args:
2701 code.putln('default:')
2703 code.putln('case %2d:' % i)
2704 pystring_cname = code.intern_identifier(arg.name)
2707 # handled separately below
2709 code.putln('if (kw_args > 0) {')
2710 code.putln('PyObject* value = PyDict_GetItem(%s, %s);' % (
2711 Naming.kwds_cname, pystring_cname))
2712 code.putln('if (value) { values[%d] = value; kw_args--; }' % i)
2715 num_required_args -= 1
2716 code.putln('values[%d] = PyDict_GetItem(%s, %s);' % (
2717 i, Naming.kwds_cname, pystring_cname))
2718 code.putln('if (likely(values[%d])) kw_args--;' % i);
2719 if i < min_positional_args:
2721 # special case: we know arg 0 is missing
2723 code.put_goto(argtuple_error_label)
2725 # print the correct number of values (args or
2726 # kwargs) that were passed into positional
2727 # arguments up to this point
2728 code.putln('else {')
2729 code.put('__Pyx_RaiseArgtupleInvalid("%s", %d, %d, %d, %d); ' % (
2730 self.name, has_fixed_positional_count,
2731 min_positional_args, max_positional_args, i))
2732 code.putln(code.error_goto(self.pos))
2735 code.putln('else {')
2736 code.put('__Pyx_RaiseKeywordRequired("%s", %s); ' %(
2737 self.name, pystring_cname))
2738 code.putln(code.error_goto(self.pos))
2740 if max_positional_args > 0:
2743 if kw_only_args and not self.starstar_arg:
2744 # unpack optional keyword-only arguments
2745 # checking for interned strings in a dict is faster than iterating
2746 # but it's too likely that we must iterate if we expect **kwargs
2748 for i, arg in enumerate(all_args[max_positional_args:]):
2749 if not arg.kw_only or not arg.default:
2751 optional_args.append((i+max_positional_args, arg))
2753 # this mimics an unrolled loop so that we can "break" out of it
2754 code.putln('while (kw_args > 0) {')
2755 code.putln('PyObject* value;')
2756 for i, arg in optional_args:
2757 pystring_cname = code.intern_identifier(arg.name)
2759 'value = PyDict_GetItem(%s, %s);' % (
2760 Naming.kwds_cname, pystring_cname))
2762 'if (value) { values[%d] = value; if (!(--kw_args)) break; }' % i)
2763 code.putln('break;')
2766 code.putln('if (unlikely(kw_args > 0)) {')
2767 # non-positional/-required kw args left in dict: default args,
2768 # kw-only args, **kwargs or error
2770 # This is sort of a catch-all: except for checking required
2771 # arguments, this will always do the right thing for unpacking
2772 # keyword arguments, so that we can concentrate on optimising
2773 # common cases above.
2774 if max_positional_args == 0:
2777 code.putln("const Py_ssize_t used_pos_args = (PyTuple_GET_SIZE(%s) < %d) ? PyTuple_GET_SIZE(%s) : %d;" % (
2778 Naming.args_cname, max_positional_args,
2779 Naming.args_cname, max_positional_args))
2780 pos_arg_count = "used_pos_args"
2782 pos_arg_count = "PyTuple_GET_SIZE(%s)" % Naming.args_cname
2783 code.globalstate.use_utility_code(parse_keywords_utility_code)
2785 'if (unlikely(__Pyx_ParseOptionalKeywords(%s, %s, %s, values, %s, "%s") < 0)) ' % (
2787 Naming.pykwdlist_cname,
2788 self.starstar_arg and self.starstar_arg.entry.cname or '0',
2791 code.putln(code.error_goto(self.pos))
2794 # convert arg values to their final type and assign them
2795 for i, arg in enumerate(all_args):
2796 if arg.default and not arg.type.is_pyobject:
2797 code.putln("if (values[%d]) {" % i)
2798 self.generate_arg_assignment(arg, "values[%d]" % i, code)
2799 if arg.default and not arg.type.is_pyobject:
2800 code.putln('} else {')
2804 arg.calculate_default_value_code(code)))
2807 def generate_argument_conversion_code(self, code):
2808 # Generate code to convert arguments from signature type to
2809 # declared type, if needed. Also copies signature arguments
2810 # into closure fields.
2811 for arg in self.args:
2812 if arg.needs_conversion:
2813 self.generate_arg_conversion(arg, code)
2814 elif arg.entry.in_closure:
2815 code.putln('%s = %s;' % (arg.entry.cname, arg.hdr_cname))
2816 if arg.type.is_pyobject:
2817 code.put_var_incref(arg.entry)
2819 def generate_arg_conversion(self, arg, code):
2820 # Generate conversion code for one argument.
2821 old_type = arg.hdr_type
2823 if old_type.is_pyobject:
2825 code.putln("if (%s) {" % arg.hdr_cname)
2827 code.putln("assert(%s); {" % arg.hdr_cname)
2828 self.generate_arg_conversion_from_pyobject(arg, code)
2830 elif new_type.is_pyobject:
2831 self.generate_arg_conversion_to_pyobject(arg, code)
2833 if new_type.assignable_from(old_type):
2835 "%s = %s;" % (arg.entry.cname, arg.hdr_cname))
2838 "Cannot convert 1 argument from '%s' to '%s'" %
2839 (old_type, new_type))
2841 def generate_arg_conversion_from_pyobject(self, arg, code):
2843 func = new_type.from_py_function
2844 # copied from CoerceFromPyTypeNode
2846 lhs = arg.entry.cname
2847 rhs = "%s(%s)" % (func, arg.hdr_cname)
2848 if new_type.is_enum:
2849 rhs = PyrexTypes.typecast(new_type, PyrexTypes.c_long_type, rhs)
2850 code.putln("%s = %s; %s" % (
2853 code.error_goto_if(new_type.error_condition(arg.entry.cname), arg.pos)))
2856 "Cannot convert Python object argument to type '%s'"
2859 def generate_arg_conversion_to_pyobject(self, arg, code):
2860 old_type = arg.hdr_type
2861 func = old_type.to_py_function
2863 code.putln("%s = %s(%s); %s" % (
2867 code.error_goto_if_null(arg.entry.cname, arg.pos)))
2868 code.put_var_gotref(arg.entry)
2871 "Cannot convert argument of type '%s' to Python object"
2874 def generate_argument_type_tests(self, code):
2875 # Generate type tests for args whose signature
2876 # type is PyObject * and whose declared type is
2877 # a subtype thereof.
2878 for arg in self.args:
2879 if arg.needs_type_test:
2880 self.generate_arg_type_test(arg, code)
2881 elif not arg.accept_none and arg.type.is_pyobject:
2882 self.generate_arg_none_check(arg, code)
2884 def error_value(self):
2885 return self.entry.signature.error_value
2887 def caller_will_check_exceptions(self):
2890 class OverrideCheckNode(StatNode):
2891 # A Node for dispatching to the def method if it
2900 child_attrs = ['body']
2904 def analyse_expressions(self, env):
2905 self.args = env.arg_entries
2906 if self.py_func.is_module_scope:
2911 self.func_node = ExprNodes.RawCNameExprNode(self.pos, py_object_type)
2912 call_tuple = ExprNodes.TupleNode(self.pos, args=[ExprNodes.NameNode(self.pos, name=arg.name) for arg in self.args[first_arg:]])
2913 call_node = ExprNodes.SimpleCallNode(self.pos,
2914 function=self.func_node,
2915 args=[ExprNodes.NameNode(self.pos, name=arg.name) for arg in self.args[first_arg:]])
2916 self.body = ReturnStatNode(self.pos, value=call_node)
2917 self.body.analyse_expressions(env)
2919 def generate_execution_code(self, code):
2920 interned_attr_cname = code.intern_identifier(self.py_func.entry.name)
2921 # Check to see if we are an extension type
2922 if self.py_func.is_module_scope:
2923 self_arg = "((PyObject *)%s)" % Naming.module_cname
2925 self_arg = "((PyObject *)%s)" % self.args[0].cname
2926 code.putln("/* Check if called by wrapper */")
2927 code.putln("if (unlikely(%s)) ;" % Naming.skip_dispatch_cname)
2928 code.putln("/* Check if overriden in Python */")
2929 if self.py_func.is_module_scope:
2930 code.putln("else {")
2932 code.putln("else if (unlikely(Py_TYPE(%s)->tp_dictoffset != 0)) {" % self_arg)
2933 func_node_temp = code.funcstate.allocate_temp(py_object_type, manage_ref=True)
2934 self.func_node.set_cname(func_node_temp)
2935 # need to get attribute manually--scope would return cdef method
2936 err = code.error_goto_if_null(func_node_temp, self.pos)
2937 code.putln("%s = PyObject_GetAttr(%s, %s); %s" % (
2938 func_node_temp, self_arg, interned_attr_cname, err))
2939 code.put_gotref(func_node_temp)
2940 is_builtin_function_or_method = "PyCFunction_Check(%s)" % func_node_temp
2941 is_overridden = "(PyCFunction_GET_FUNCTION(%s) != (void *)&%s)" % (
2942 func_node_temp, self.py_func.entry.func_cname)
2943 code.putln("if (!%s || %s) {" % (is_builtin_function_or_method, is_overridden))
2944 self.body.generate_execution_code(code)
2946 code.put_decref_clear(func_node_temp, PyrexTypes.py_object_type)
2947 code.funcstate.release_temp(func_node_temp)
2950 class ClassDefNode(StatNode, BlockNode):
2953 class PyClassDefNode(ClassDefNode):
2954 # A Python class definition.
2956 # name EncodedString Name of the class
2957 # doc string or None
2958 # body StatNode Attribute definition code
2959 # entry Symtab.Entry
2960 # scope PyClassScope
2961 # decorators [DecoratorNode] list of decorators or None
2963 # The following subnodes are constructed internally:
2965 # dict DictNode Class dictionary or Py3 namespace
2966 # classobj ClassNode Class object
2967 # target NameNode Variable to assign class object to
2969 child_attrs = ["body", "dict", "metaclass", "mkw", "bases", "classobj", "target"]
2971 py3_style_class = False # Python3 style class (bases+kwargs)
2973 def __init__(self, pos, name, bases, doc, body, decorators = None,
2974 keyword_args = None, starstar_arg = None):
2975 StatNode.__init__(self, pos)
2979 self.decorators = decorators
2981 if self.doc and Options.docstrings:
2982 doc = embed_position(self.pos, self.doc)
2983 doc_node = ExprNodes.StringNode(pos, value = doc)
2986 if keyword_args or starstar_arg:
2987 self.py3_style_class = True
2989 self.metaclass = None
2990 if keyword_args and not starstar_arg:
2991 for i, item in list(enumerate(keyword_args.key_value_pairs))[::-1]:
2992 if item.key.value == 'metaclass':
2993 if self.metaclass is not None:
2994 error(item.pos, "keyword argument 'metaclass' passed multiple times")
2995 # special case: we already know the metaclass,
2996 # so we don't need to do the "build kwargs,
2997 # find metaclass" dance at runtime
2998 self.metaclass = item.value
2999 del keyword_args.key_value_pairs[i]
3000 if starstar_arg or (keyword_args and keyword_args.key_value_pairs):
3001 self.mkw = ExprNodes.KeywordArgsNode(
3002 pos, keyword_args = keyword_args, starstar_arg = starstar_arg)
3004 self.mkw = ExprNodes.NullNode(pos)
3005 if self.metaclass is None:
3006 self.metaclass = ExprNodes.PyClassMetaclassNode(
3007 pos, mkw = self.mkw, bases = self.bases)
3008 self.dict = ExprNodes.PyClassNamespaceNode(pos, name = name,
3009 doc = doc_node, metaclass = self.metaclass, bases = self.bases,
3011 self.classobj = ExprNodes.Py3ClassNode(pos, name = name,
3012 bases = self.bases, dict = self.dict, doc = doc_node,
3013 metaclass = self.metaclass, mkw = self.mkw)
3015 self.dict = ExprNodes.DictNode(pos, key_value_pairs = [])
3016 self.metaclass = None
3019 self.classobj = ExprNodes.ClassNode(pos, name = name,
3020 bases = bases, dict = self.dict, doc = doc_node)
3021 self.target = ExprNodes.NameNode(pos, name = name)
3023 def as_cclass(self):
3025 Return this node as if it were declared as an extension class
3027 if self.py3_style_class:
3028 error(self.classobj.pos, "Python3 style class could not be represented as C class")
3030 bases = self.classobj.bases.args
3032 base_class_name = None
3033 base_class_module = None
3034 elif len(bases) == 1:
3037 from ExprNodes import AttributeNode, NameNode
3038 while isinstance(base, AttributeNode):
3039 path.insert(0, base.attribute)
3041 if isinstance(base, NameNode):
3042 path.insert(0, base.name)
3043 base_class_name = path[-1]
3045 base_class_module = u'.'.join(path[:-1])
3047 base_class_module = None
3049 error(self.classobj.bases.args.pos, "Invalid base class")
3051 error(self.classobj.bases.args.pos, "C class may only have one base class")
3054 return CClassDefNode(self.pos,
3055 visibility = 'private',
3057 class_name = self.name,
3058 base_class_module = base_class_module,
3059 base_class_name = base_class_name,
3060 decorators = self.decorators,
3065 def create_scope(self, env):
3067 while genv.is_py_class_scope or genv.is_c_class_scope:
3068 genv = genv.outer_scope
3069 cenv = self.scope = PyClassScope(name = self.name, outer_scope = genv)
3072 def analyse_declarations(self, env):
3073 self.target.analyse_target_declaration(env)
3074 cenv = self.create_scope(env)
3075 cenv.directives = env.directives
3076 cenv.class_obj_cname = self.target.entry.cname
3077 self.body.analyse_declarations(cenv)
3079 def analyse_expressions(self, env):
3080 if self.py3_style_class:
3081 self.bases.analyse_expressions(env)
3082 self.metaclass.analyse_expressions(env)
3083 self.mkw.analyse_expressions(env)
3084 self.dict.analyse_expressions(env)
3085 self.classobj.analyse_expressions(env)
3086 genv = env.global_scope()
3088 self.body.analyse_expressions(cenv)
3089 self.target.analyse_target_expression(env, self.classobj)
3091 def generate_function_definitions(self, env, code):
3092 self.generate_lambda_definitions(self.scope, code)
3093 self.body.generate_function_definitions(self.scope, code)
3095 def generate_execution_code(self, code):
3096 code.pyclass_stack.append(self)
3098 if self.py3_style_class:
3099 self.bases.generate_evaluation_code(code)
3100 self.mkw.generate_evaluation_code(code)
3101 self.metaclass.generate_evaluation_code(code)
3102 self.dict.generate_evaluation_code(code)
3103 cenv.namespace_cname = cenv.class_obj_cname = self.dict.result()
3104 self.body.generate_execution_code(code)
3105 self.classobj.generate_evaluation_code(code)
3106 cenv.namespace_cname = cenv.class_obj_cname = self.classobj.result()
3107 self.target.generate_assignment_code(self.classobj, code)
3108 self.dict.generate_disposal_code(code)
3109 self.dict.free_temps(code)
3110 if self.py3_style_class:
3111 self.mkw.generate_disposal_code(code)
3112 self.mkw.free_temps(code)
3113 self.metaclass.generate_disposal_code(code)
3114 self.metaclass.free_temps(code)
3115 self.bases.generate_disposal_code(code)
3116 self.bases.free_temps(code)
3117 code.pyclass_stack.pop()
3119 class CClassDefNode(ClassDefNode):
3120 # An extension type definition.
3122 # visibility 'private' or 'public' or 'extern'
3123 # typedef_flag boolean
3125 # module_name string or None For import of extern type objects
3126 # class_name string Unqualified name of class
3127 # as_name string or None Name to declare as in this scope
3128 # base_class_module string or None Module containing the base class
3129 # base_class_name string or None Name of the base class
3130 # objstruct_name string or None Specified C name of object struct
3131 # typeobj_name string or None Specified C name of type object
3132 # in_pxd boolean Is in a .pxd file
3133 # decorators [DecoratorNode] list of decorators or None
3134 # doc string or None
3135 # body StatNode or None
3136 # entry Symtab.Entry
3137 # base_type PyExtensionType or None
3138 # buffer_defaults_node DictNode or None Declares defaults for a buffer
3139 # buffer_defaults_pos
3141 child_attrs = ["body"]
3142 buffer_defaults_node = None
3143 buffer_defaults_pos = None
3144 typedef_flag = False
3146 objstruct_name = None
3150 def analyse_declarations(self, env):
3151 #print "CClassDefNode.analyse_declarations:", self.class_name
3152 #print "...visibility =", self.visibility
3153 #print "...module_name =", self.module_name
3156 if self.buffer_defaults_node:
3157 buffer_defaults = Buffer.analyse_buffer_options(self.buffer_defaults_pos,
3158 env, [], self.buffer_defaults_node,
3159 need_complete=False)
3161 buffer_defaults = None
3163 if env.in_cinclude and not self.objstruct_name:
3164 error(self.pos, "Object struct name specification required for "
3165 "C class defined in 'extern from' block")
3166 self.base_type = None
3167 # Now that module imports are cached, we need to
3168 # import the modules for extern classes.
3169 if self.module_name:
3171 for module in env.cimported_modules:
3172 if module.name == self.module_name:
3173 self.module = module
3174 if self.module is None:
3175 self.module = ModuleScope(self.module_name, None, env.context)
3176 self.module.has_extern_class = 1
3177 env.add_imported_module(self.module)
3179 if self.base_class_name:
3180 if self.base_class_module:
3181 base_class_scope = env.find_module(self.base_class_module, self.pos)
3183 base_class_scope = env
3184 if self.base_class_name == 'object':
3185 # extension classes are special and don't need to inherit from object
3186 if base_class_scope is None or base_class_scope.lookup('object') is None:
3187 self.base_class_name = None
3188 self.base_class_module = None
3189 base_class_scope = None
3190 if base_class_scope:
3191 base_class_entry = base_class_scope.find(self.base_class_name, self.pos)
3192 if base_class_entry:
3193 if not base_class_entry.is_type:
3194 error(self.pos, "'%s' is not a type name" % self.base_class_name)
3195 elif not base_class_entry.type.is_extension_type and \
3196 not (base_class_entry.type.is_builtin_type and \
3197 base_class_entry.type.objstruct_cname):
3198 error(self.pos, "'%s' is not an extension type" % self.base_class_name)
3199 elif not base_class_entry.type.is_complete():
3200 error(self.pos, "Base class '%s' of type '%s' is incomplete" % (
3201 self.base_class_name, self.class_name))
3202 elif base_class_entry.type.scope and base_class_entry.type.scope.directives and \
3203 base_class_entry.type.scope.directives['final']:
3204 error(self.pos, "Base class '%s' of type '%s' is final" % (
3205 self.base_class_name, self.class_name))
3207 self.base_type = base_class_entry.type
3208 has_body = self.body is not None
3209 if self.module_name and self.visibility != 'extern':
3210 module_path = self.module_name.split(".")
3211 home_scope = env.find_imported_module(module_path, self.pos)
3217 if self.visibility == 'extern':
3218 if self.module_name == '__builtin__' and self.class_name in Builtin.builtin_types:
3219 warning(self.pos, "%s already a builtin Cython type" % self.class_name, 1)
3221 self.entry = home_scope.declare_c_class(
3222 name = self.class_name,
3224 defining = has_body and self.in_pxd,
3225 implementing = has_body and not self.in_pxd,
3226 module_name = self.module_name,
3227 base_type = self.base_type,
3228 objstruct_cname = self.objstruct_name,
3229 typeobj_cname = self.typeobj_name,
3230 visibility = self.visibility,
3231 typedef_flag = self.typedef_flag,
3233 buffer_defaults = buffer_defaults)
3234 if home_scope is not env and self.visibility == 'extern':
3235 env.add_imported_entry(self.class_name, self.entry, self.pos)
3236 self.scope = scope = self.entry.type.scope
3237 if scope is not None:
3238 scope.directives = env.directives
3240 if self.doc and Options.docstrings:
3241 scope.doc = embed_position(self.pos, self.doc)
3244 self.body.analyse_declarations(scope)
3248 scope.implemented = 1
3249 env.allocate_vtable_names(self.entry)
3251 def analyse_expressions(self, env):
3253 scope = self.entry.type.scope
3254 self.body.analyse_expressions(scope)
3256 def generate_function_definitions(self, env, code):
3258 self.generate_lambda_definitions(self.scope, code)
3259 self.body.generate_function_definitions(self.scope, code)
3261 def generate_execution_code(self, code):
3262 # This is needed to generate evaluation code for
3263 # default values of method arguments.
3265 self.body.generate_execution_code(code)
3267 def annotate(self, code):
3269 self.body.annotate(code)
3272 class PropertyNode(StatNode):
3273 # Definition of a property in an extension type.
3276 # doc EncodedString or None Doc string
3279 child_attrs = ["body"]
3281 def analyse_declarations(self, env):
3282 entry = env.declare_property(self.name, self.doc, self.pos)
3284 entry.scope.directives = env.directives
3285 self.body.analyse_declarations(entry.scope)
3287 def analyse_expressions(self, env):
3288 self.body.analyse_expressions(env)
3290 def generate_function_definitions(self, env, code):
3291 self.body.generate_function_definitions(env, code)
3293 def generate_execution_code(self, code):
3296 def annotate(self, code):
3297 self.body.annotate(code)
3300 class GlobalNode(StatNode):
3301 # Global variable declaration.
3307 def analyse_declarations(self, env):
3308 for name in self.names:
3309 env.declare_global(name, self.pos)
3311 def analyse_expressions(self, env):
3314 def generate_execution_code(self, code):
3318 class ExprStatNode(StatNode):
3319 # Expression used as a statement.
3323 child_attrs = ["expr"]
3325 def analyse_declarations(self, env):
3327 if isinstance(self.expr, ExprNodes.GeneralCallNode):
3328 func = self.expr.function.as_cython_attribute()
3329 if func == u'declare':
3330 args, kwds = self.expr.explicit_args_kwds()
3332 error(self.expr.pos, "Variable names must be specified.")
3333 for var, type_node in kwds.key_value_pairs:
3334 type = type_node.analyse_as_type(env)
3336 error(type_node.pos, "Unknown type")
3338 env.declare_var(var.value, type, var.pos, is_cdef = True)
3339 self.__class__ = PassStatNode
3341 def analyse_expressions(self, env):
3342 self.expr.analyse_expressions(env)
3344 def generate_execution_code(self, code):
3345 self.expr.generate_evaluation_code(code)
3346 if not self.expr.is_temp and self.expr.result():
3347 code.putln("%s;" % self.expr.result())
3348 self.expr.generate_disposal_code(code)
3349 self.expr.free_temps(code)
3351 def generate_function_definitions(self, env, code):
3352 self.expr.generate_function_definitions(env, code)
3354 def annotate(self, code):
3355 self.expr.annotate(code)
3358 class AssignmentNode(StatNode):
3359 # Abstract base class for assignment nodes.
3361 # The analyse_expressions and generate_execution_code
3362 # phases of assignments are split into two sub-phases
3363 # each, to enable all the right hand sides of a
3364 # parallel assignment to be evaluated before assigning
3365 # to any of the left hand sides.
3367 def analyse_expressions(self, env):
3368 self.analyse_types(env)
3370 # def analyse_expressions(self, env):
3371 # self.analyse_expressions_1(env)
3372 # self.analyse_expressions_2(env)
3374 def generate_execution_code(self, code):
3375 self.generate_rhs_evaluation_code(code)
3376 self.generate_assignment_code(code)
3379 class SingleAssignmentNode(AssignmentNode):
3380 # The simplest case:
3384 # lhs ExprNode Left hand side
3385 # rhs ExprNode Right hand side
3386 # first bool Is this guaranteed the first assignment to lhs?
3388 child_attrs = ["lhs", "rhs"]
3390 declaration_only = False
3392 def analyse_declarations(self, env):
3395 # handle declarations of the form x = cython.foo()
3396 if isinstance(self.rhs, ExprNodes.CallNode):
3397 func_name = self.rhs.function.as_cython_attribute()
3399 args, kwds = self.rhs.explicit_args_kwds()
3401 if func_name in ['declare', 'typedef']:
3402 if len(args) > 2 or kwds is not None:
3403 error(self.rhs.pos, "Can only declare one type at a time.")
3405 type = args[0].analyse_as_type(env)
3407 error(args[0].pos, "Unknown type")
3410 if func_name == 'declare':
3411 if isinstance(lhs, ExprNodes.NameNode):
3412 vars = [(lhs.name, lhs.pos)]
3413 elif isinstance(lhs, ExprNodes.TupleNode):
3414 vars = [(var.name, var.pos) for var in lhs.args]
3416 error(lhs.pos, "Invalid declaration")
3418 for var, pos in vars:
3419 env.declare_var(var, type, pos, is_cdef = True)
3424 self.declaration_only = True
3426 self.declaration_only = True
3427 if not isinstance(lhs, ExprNodes.NameNode):
3428 error(lhs.pos, "Invalid declaration.")
3429 env.declare_typedef(lhs.name, type, self.pos, visibility='private')
3431 elif func_name in ['struct', 'union']:
3432 self.declaration_only = True
3433 if len(args) > 0 or kwds is None:
3434 error(self.rhs.pos, "Struct or union members must be given by name.")
3437 for member, type_node in kwds.key_value_pairs:
3438 type = type_node.analyse_as_type(env)
3440 error(type_node.pos, "Unknown type")
3442 members.append((member.value, type, member.pos))
3443 if len(members) < len(kwds.key_value_pairs):
3445 if not isinstance(self.lhs, ExprNodes.NameNode):
3446 error(self.lhs.pos, "Invalid declaration.")
3447 name = self.lhs.name
3448 scope = StructOrUnionScope(name)
3449 env.declare_struct_or_union(name, func_name, scope, False, self.rhs.pos)
3450 for member, type, pos in members:
3451 scope.declare_var(member, type, pos)
3453 if self.declaration_only:
3456 self.lhs.analyse_target_declaration(env)
3458 def analyse_types(self, env, use_temp = 0):
3459 self.rhs.analyse_types(env)
3460 self.lhs.analyse_target_types(env)
3461 self.lhs.gil_assignment_check(env)
3462 self.rhs = self.rhs.coerce_to(self.lhs.type, env)
3464 self.rhs = self.rhs.coerce_to_temp(env)
3466 def generate_rhs_evaluation_code(self, code):
3467 self.rhs.generate_evaluation_code(code)
3469 def generate_assignment_code(self, code):
3470 self.lhs.generate_assignment_code(self.rhs, code)
3472 def generate_function_definitions(self, env, code):
3473 self.rhs.generate_function_definitions(env, code)
3475 def annotate(self, code):
3476 self.lhs.annotate(code)
3477 self.rhs.annotate(code)
3480 class CascadedAssignmentNode(AssignmentNode):
3481 # An assignment with multiple left hand sides:
3485 # lhs_list [ExprNode] Left hand sides
3486 # rhs ExprNode Right hand sides
3490 # coerced_rhs_list [ExprNode] RHS coerced to type of each LHS
3492 child_attrs = ["lhs_list", "rhs", "coerced_rhs_list"]
3493 coerced_rhs_list = None
3495 def analyse_declarations(self, env):
3496 for lhs in self.lhs_list:
3497 lhs.analyse_target_declaration(env)
3499 def analyse_types(self, env, use_temp = 0):
3500 self.rhs.analyse_types(env)
3501 if not self.rhs.is_simple():
3503 self.rhs = self.rhs.coerce_to_temp(env)
3505 self.rhs = self.rhs.coerce_to_simple(env)
3506 from ExprNodes import CloneNode
3507 self.coerced_rhs_list = []
3508 for lhs in self.lhs_list:
3509 lhs.analyse_target_types(env)
3510 lhs.gil_assignment_check(env)
3511 rhs = CloneNode(self.rhs)
3512 rhs = rhs.coerce_to(lhs.type, env)
3513 self.coerced_rhs_list.append(rhs)
3515 def generate_rhs_evaluation_code(self, code):
3516 self.rhs.generate_evaluation_code(code)
3518 def generate_assignment_code(self, code):
3519 for i in range(len(self.lhs_list)):
3520 lhs = self.lhs_list[i]
3521 rhs = self.coerced_rhs_list[i]
3522 rhs.generate_evaluation_code(code)
3523 lhs.generate_assignment_code(rhs, code)
3524 # Assignment has disposed of the cloned RHS
3525 self.rhs.generate_disposal_code(code)
3526 self.rhs.free_temps(code)
3528 def generate_function_definitions(self, env, code):
3529 self.rhs.generate_function_definitions(env, code)
3531 def annotate(self, code):
3532 for i in range(len(self.lhs_list)):
3533 lhs = self.lhs_list[i].annotate(code)
3534 rhs = self.coerced_rhs_list[i].annotate(code)
3535 self.rhs.annotate(code)
3538 class ParallelAssignmentNode(AssignmentNode):
3539 # A combined packing/unpacking assignment:
3543 # This has been rearranged by the parser into
3545 # a = d ; b = e ; c = f
3547 # but we must evaluate all the right hand sides
3548 # before assigning to any of the left hand sides.
3550 # stats [AssignmentNode] The constituent assignments
3552 child_attrs = ["stats"]
3554 def analyse_declarations(self, env):
3555 for stat in self.stats:
3556 stat.analyse_declarations(env)
3558 def analyse_expressions(self, env):
3559 for stat in self.stats:
3560 stat.analyse_types(env, use_temp = 1)
3562 # def analyse_expressions(self, env):
3563 # for stat in self.stats:
3564 # stat.analyse_expressions_1(env, use_temp = 1)
3565 # for stat in self.stats:
3566 # stat.analyse_expressions_2(env)
3568 def generate_execution_code(self, code):
3569 for stat in self.stats:
3570 stat.generate_rhs_evaluation_code(code)
3571 for stat in self.stats:
3572 stat.generate_assignment_code(code)
3574 def generate_function_definitions(self, env, code):
3575 for stat in self.stats:
3576 stat.generate_function_definitions(env, code)
3578 def annotate(self, code):
3579 for stat in self.stats:
3583 class InPlaceAssignmentNode(AssignmentNode):
3584 # An in place arithmetic operand:
3590 # lhs ExprNode Left hand side
3591 # rhs ExprNode Right hand side
3592 # op char one of "+-*/%^&|"
3593 # dup (ExprNode) copy of lhs used for operation (auto-generated)
3595 # This code is a bit tricky because in order to obey Python
3596 # semantics the sub-expressions (e.g. indices) of the lhs must
3597 # not be evaluated twice. So we must re-use the values calculated
3598 # in evaluation phase for the assignment phase as well.
3599 # Fortunately, the type of the lhs node is fairly constrained
3600 # (it must be a NameNode, AttributeNode, or IndexNode).
3602 child_attrs = ["lhs", "rhs"]
3604 def analyse_declarations(self, env):
3605 self.lhs.analyse_target_declaration(env)
3607 def analyse_types(self, env):
3608 self.rhs.analyse_types(env)
3609 self.lhs.analyse_target_types(env)
3611 def generate_execution_code(self, code):
3613 self.rhs.generate_evaluation_code(code)
3614 self.lhs.generate_subexpr_evaluation_code(code)
3615 c_op = self.operator
3619 error(self.pos, "No C inplace power operator")
3620 if isinstance(self.lhs, ExprNodes.IndexNode) and self.lhs.is_buffer_access:
3621 if self.lhs.type.is_pyobject:
3622 error(self.pos, "In-place operators not allowed on object buffers in this release.")
3623 if c_op in ('/', '%') and self.lhs.type.is_int and not code.directives['cdivision']:
3624 error(self.pos, "In-place non-c divide operators not allowed on int buffers.")
3625 self.lhs.generate_buffer_setitem_code(self.rhs, code, c_op)
3628 # TODO: make sure overload is declared
3629 code.putln("%s %s= %s;" % (self.lhs.result(), c_op, self.rhs.result()))
3630 self.lhs.generate_subexpr_disposal_code(code)
3631 self.lhs.free_subexpr_temps(code)
3632 self.rhs.generate_disposal_code(code)
3633 self.rhs.free_temps(code)
3635 def annotate(self, code):
3636 self.lhs.annotate(code)
3637 self.rhs.annotate(code)
3639 def create_binop_node(self):
3641 return ExprNodes.binop_node(self.pos, self.operator, self.lhs, self.rhs)
3644 class PrintStatNode(StatNode):
3647 # arg_tuple TupleNode
3648 # stream ExprNode or None (stdout)
3649 # append_newline boolean
3651 child_attrs = ["arg_tuple", "stream"]
3653 def analyse_expressions(self, env):
3655 self.stream.analyse_expressions(env)
3656 self.stream = self.stream.coerce_to_pyobject(env)
3657 self.arg_tuple.analyse_expressions(env)
3658 self.arg_tuple = self.arg_tuple.coerce_to_pyobject(env)
3659 env.use_utility_code(printing_utility_code)
3660 if len(self.arg_tuple.args) == 1 and self.append_newline:
3661 env.use_utility_code(printing_one_utility_code)
3663 nogil_check = Node.gil_error
3664 gil_message = "Python print statement"
3666 def generate_execution_code(self, code):
3668 self.stream.generate_evaluation_code(code)
3669 stream_result = self.stream.py_result()
3672 if len(self.arg_tuple.args) == 1 and self.append_newline:
3673 arg = self.arg_tuple.args[0]
3674 arg.generate_evaluation_code(code)
3677 "if (__Pyx_PrintOne(%s, %s) < 0) %s" % (
3680 code.error_goto(self.pos)))
3681 arg.generate_disposal_code(code)
3682 arg.free_temps(code)
3684 self.arg_tuple.generate_evaluation_code(code)
3686 "if (__Pyx_Print(%s, %s, %d) < 0) %s" % (
3688 self.arg_tuple.py_result(),
3689 self.append_newline,
3690 code.error_goto(self.pos)))
3691 self.arg_tuple.generate_disposal_code(code)
3692 self.arg_tuple.free_temps(code)
3695 self.stream.generate_disposal_code(code)
3696 self.stream.free_temps(code)
3698 def generate_function_definitions(self, env, code):
3700 self.stream.generate_function_definitions(env, code)
3701 self.arg_tuple.generate_function_definitions(env, code)
3703 def annotate(self, code):
3705 self.stream.annotate(code)
3706 self.arg_tuple.annotate(code)
3709 class ExecStatNode(StatNode):
3714 child_attrs = ["args"]
3716 def analyse_expressions(self, env):
3717 for i, arg in enumerate(self.args):
3718 arg.analyse_expressions(env)
3719 arg = arg.coerce_to_pyobject(env)
3721 env.use_utility_code(Builtin.pyexec_utility_code)
3723 nogil_check = Node.gil_error
3724 gil_message = "Python exec statement"
3726 def generate_execution_code(self, code):
3728 for arg in self.args:
3729 arg.generate_evaluation_code(code)
3730 args.append( arg.py_result() )
3731 args = tuple(args + ['0', '0'][:3-len(args)])
3732 temp_result = code.funcstate.allocate_temp(PyrexTypes.py_object_type, manage_ref=True)
3733 code.putln("%s = __Pyx_PyRun(%s, %s, %s);" % (
3734 (temp_result,) + args))
3735 for arg in self.args:
3736 arg.generate_disposal_code(code)
3737 arg.free_temps(code)
3739 code.error_goto_if_null(temp_result, self.pos))
3740 code.put_gotref(temp_result)
3741 code.put_decref_clear(temp_result, py_object_type)
3742 code.funcstate.release_temp(temp_result)
3744 def annotate(self, code):
3745 for arg in self.args:
3749 class DelStatNode(StatNode):
3754 child_attrs = ["args"]
3756 def analyse_declarations(self, env):
3757 for arg in self.args:
3758 arg.analyse_target_declaration(env)
3760 def analyse_expressions(self, env):
3761 for arg in self.args:
3762 arg.analyse_target_expression(env, None)
3763 if arg.type.is_pyobject:
3765 elif arg.type.is_ptr and arg.type.base_type.is_cpp_class:
3767 elif arg.type.is_cpp_class:
3768 error(arg.pos, "Deletion of non-heap C++ object")
3770 error(arg.pos, "Deletion of non-Python, non-C++ object")
3771 #arg.release_target_temp(env)
3773 def nogil_check(self, env):
3774 for arg in self.args:
3775 if arg.type.is_pyobject:
3778 gil_message = "Deleting Python object"
3780 def generate_execution_code(self, code):
3781 for arg in self.args:
3782 if arg.type.is_pyobject:
3783 arg.generate_deletion_code(code)
3784 elif arg.type.is_ptr and arg.type.base_type.is_cpp_class:
3785 arg.generate_result_code(code)
3786 code.putln("delete %s;" % arg.result())
3787 # else error reported earlier
3789 def annotate(self, code):
3790 for arg in self.args:
3794 class PassStatNode(StatNode):
3799 def analyse_expressions(self, env):
3802 def generate_execution_code(self, code):
3806 class BreakStatNode(StatNode):
3810 def analyse_expressions(self, env):
3813 def generate_execution_code(self, code):
3814 if not code.break_label:
3815 error(self.pos, "break statement not inside loop")
3817 code.put_goto(code.break_label)
3820 class ContinueStatNode(StatNode):
3824 def analyse_expressions(self, env):
3827 def generate_execution_code(self, code):
3828 if code.funcstate.in_try_finally:
3829 error(self.pos, "continue statement inside try of try...finally")
3830 elif not code.continue_label:
3831 error(self.pos, "continue statement not inside loop")
3833 code.put_goto(code.continue_label)
3836 class ReturnStatNode(StatNode):
3839 # value ExprNode or None
3840 # return_type PyrexType
3842 child_attrs = ["value"]
3844 def analyse_expressions(self, env):
3845 return_type = env.return_type
3846 self.return_type = return_type
3848 error(self.pos, "Return not inside a function body")
3851 self.value.analyse_types(env)
3852 if return_type.is_void or return_type.is_returncode:
3853 error(self.value.pos,
3854 "Return with value in void function")
3856 self.value = self.value.coerce_to(env.return_type, env)
3858 if (not return_type.is_void
3859 and not return_type.is_pyobject
3860 and not return_type.is_returncode):
3861 error(self.pos, "Return value required")
3863 def nogil_check(self, env):
3864 if self.return_type.is_pyobject:
3867 gil_message = "Returning Python object"
3869 def generate_execution_code(self, code):
3870 code.mark_pos(self.pos)
3871 if not self.return_type:
3872 # error reported earlier
3874 if self.return_type.is_pyobject:
3875 code.put_xdecref(Naming.retval_cname,
3878 self.value.generate_evaluation_code(code)
3879 self.value.make_owned_reference(code)
3882 Naming.retval_cname,
3883 self.value.result_as(self.return_type)))
3884 self.value.generate_post_assignment_code(code)
3885 self.value.free_temps(code)
3887 if self.return_type.is_pyobject:
3888 code.put_init_to_py_none(Naming.retval_cname, self.return_type)
3889 elif self.return_type.is_returncode:
3892 Naming.retval_cname,
3893 self.return_type.default_value))
3894 for cname, type in code.funcstate.temps_holding_reference():
3895 code.put_decref_clear(cname, type)
3896 code.put_goto(code.return_label)
3898 def generate_function_definitions(self, env, code):
3899 if self.value is not None:
3900 self.value.generate_function_definitions(env, code)
3902 def annotate(self, code):
3904 self.value.annotate(code)
3907 class RaiseStatNode(StatNode):
3910 # exc_type ExprNode or None
3911 # exc_value ExprNode or None
3912 # exc_tb ExprNode or None
3914 child_attrs = ["exc_type", "exc_value", "exc_tb"]
3916 def analyse_expressions(self, env):
3918 self.exc_type.analyse_types(env)
3919 self.exc_type = self.exc_type.coerce_to_pyobject(env)
3921 self.exc_value.analyse_types(env)
3922 self.exc_value = self.exc_value.coerce_to_pyobject(env)
3924 self.exc_tb.analyse_types(env)
3925 self.exc_tb = self.exc_tb.coerce_to_pyobject(env)
3926 env.use_utility_code(raise_utility_code)
3928 nogil_check = Node.gil_error
3929 gil_message = "Raising exception"
3931 def generate_execution_code(self, code):
3933 self.exc_type.generate_evaluation_code(code)
3934 type_code = self.exc_type.py_result()
3938 self.exc_value.generate_evaluation_code(code)
3939 value_code = self.exc_value.py_result()
3943 self.exc_tb.generate_evaluation_code(code)
3944 tb_code = self.exc_tb.py_result()
3948 "__Pyx_Raise(%s, %s, %s);" % (
3952 for obj in (self.exc_type, self.exc_value, self.exc_tb):
3954 obj.generate_disposal_code(code)
3955 obj.free_temps(code)
3957 code.error_goto(self.pos))
3959 def generate_function_definitions(self, env, code):
3960 if self.exc_type is not None:
3961 self.exc_type.generate_function_definitions(env, code)
3962 if self.exc_value is not None:
3963 self.exc_value.generate_function_definitions(env, code)
3964 if self.exc_tb is not None:
3965 self.exc_tb.generate_function_definitions(env, code)
3967 def annotate(self, code):
3969 self.exc_type.annotate(code)
3971 self.exc_value.annotate(code)
3973 self.exc_tb.annotate(code)
3976 class ReraiseStatNode(StatNode):
3980 def analyse_expressions(self, env):
3981 env.use_utility_code(restore_exception_utility_code)
3983 nogil_check = Node.gil_error
3984 gil_message = "Raising exception"
3986 def generate_execution_code(self, code):
3987 vars = code.funcstate.exc_vars
3989 for varname in vars:
3990 code.put_giveref(varname)
3991 code.putln("__Pyx_ErrRestore(%s, %s, %s);" % tuple(vars))
3992 for varname in vars:
3993 code.put("%s = 0; " % varname)
3995 code.putln(code.error_goto(self.pos))
3997 error(self.pos, "Reraise not inside except clause")
4000 class AssertStatNode(StatNode):
4004 # value ExprNode or None
4006 child_attrs = ["cond", "value"]
4008 def analyse_expressions(self, env):
4009 self.cond = self.cond.analyse_boolean_expression(env)
4011 self.value.analyse_types(env)
4012 self.value = self.value.coerce_to_pyobject(env)
4014 nogil_check = Node.gil_error
4015 gil_message = "Raising exception"
4017 def generate_execution_code(self, code):
4018 code.putln("#ifndef CYTHON_WITHOUT_ASSERTIONS")
4019 self.cond.generate_evaluation_code(code)
4021 "if (unlikely(!%s)) {" %
4024 self.value.generate_evaluation_code(code)
4026 "PyErr_SetObject(PyExc_AssertionError, %s);" %
4027 self.value.py_result())
4028 self.value.generate_disposal_code(code)
4029 self.value.free_temps(code)
4032 "PyErr_SetNone(PyExc_AssertionError);")
4034 code.error_goto(self.pos))
4037 self.cond.generate_disposal_code(code)
4038 self.cond.free_temps(code)
4039 code.putln("#endif")
4041 def generate_function_definitions(self, env, code):
4042 self.cond.generate_function_definitions(env, code)
4043 if self.value is not None:
4044 self.value.generate_function_definitions(env, code)
4046 def annotate(self, code):
4047 self.cond.annotate(code)
4049 self.value.annotate(code)
4052 class IfStatNode(StatNode):
4055 # if_clauses [IfClauseNode]
4056 # else_clause StatNode or None
4058 child_attrs = ["if_clauses", "else_clause"]
4060 def analyse_control_flow(self, env):
4061 env.start_branching(self.pos)
4062 for if_clause in self.if_clauses:
4063 if_clause.analyse_control_flow(env)
4064 env.next_branch(if_clause.end_pos())
4065 if self.else_clause:
4066 self.else_clause.analyse_control_flow(env)
4067 env.finish_branching(self.end_pos())
4069 def analyse_declarations(self, env):
4070 for if_clause in self.if_clauses:
4071 if_clause.analyse_declarations(env)
4072 if self.else_clause:
4073 self.else_clause.analyse_declarations(env)
4075 def analyse_expressions(self, env):
4076 for if_clause in self.if_clauses:
4077 if_clause.analyse_expressions(env)
4078 if self.else_clause:
4079 self.else_clause.analyse_expressions(env)
4081 def generate_execution_code(self, code):
4082 code.mark_pos(self.pos)
4083 end_label = code.new_label()
4084 for if_clause in self.if_clauses:
4085 if_clause.generate_execution_code(code, end_label)
4086 if self.else_clause:
4087 code.putln("/*else*/ {")
4088 self.else_clause.generate_execution_code(code)
4090 code.put_label(end_label)
4092 def generate_function_definitions(self, env, code):
4093 for clause in self.if_clauses:
4094 clause.generate_function_definitions(env, code)
4095 if self.else_clause is not None:
4096 self.else_clause.generate_function_definitions(env, code)
4098 def annotate(self, code):
4099 for if_clause in self.if_clauses:
4100 if_clause.annotate(code)
4101 if self.else_clause:
4102 self.else_clause.annotate(code)
4105 class IfClauseNode(Node):
4106 # if or elif clause in an if statement
4108 # condition ExprNode
4111 child_attrs = ["condition", "body"]
4113 def analyse_control_flow(self, env):
4114 self.body.analyse_control_flow(env)
4116 def analyse_declarations(self, env):
4117 self.body.analyse_declarations(env)
4119 def analyse_expressions(self, env):
4121 self.condition.analyse_temp_boolean_expression(env)
4122 self.body.analyse_expressions(env)
4124 def get_constant_condition_result(self):
4125 if self.condition.has_constant_result():
4126 return bool(self.condition.constant_result)
4130 def generate_execution_code(self, code, end_label):
4131 self.condition.generate_evaluation_code(code)
4134 self.condition.result())
4135 self.condition.generate_disposal_code(code)
4136 self.condition.free_temps(code)
4137 self.body.generate_execution_code(code)
4138 code.put_goto(end_label)
4141 def generate_function_definitions(self, env, code):
4142 self.condition.generate_function_definitions(env, code)
4143 self.body.generate_function_definitions(env, code)
4145 def annotate(self, code):
4146 self.condition.annotate(code)
4147 self.body.annotate(code)
4150 class SwitchCaseNode(StatNode):
4151 # Generated in the optimization of an if-elif-else node
4153 # conditions [ExprNode]
4156 child_attrs = ['conditions', 'body']
4158 def generate_execution_code(self, code):
4159 for cond in self.conditions:
4160 code.mark_pos(cond.pos)
4161 cond.generate_evaluation_code(code)
4162 code.putln("case %s:" % cond.result())
4163 self.body.generate_execution_code(code)
4164 code.putln("break;")
4166 def generate_function_definitions(self, env, code):
4167 for cond in self.conditions:
4168 cond.generate_function_definitions(env, code)
4169 self.body.generate_function_definitions(env, code)
4171 def annotate(self, code):
4172 for cond in self.conditions:
4174 self.body.annotate(code)
4176 class SwitchStatNode(StatNode):
4177 # Generated in the optimization of an if-elif-else node
4180 # cases [SwitchCaseNode]
4181 # else_clause StatNode or None
4183 child_attrs = ['test', 'cases', 'else_clause']
4185 def generate_execution_code(self, code):
4186 self.test.generate_evaluation_code(code)
4187 code.putln("switch (%s) {" % self.test.result())
4188 for case in self.cases:
4189 case.generate_execution_code(code)
4190 if self.else_clause is not None:
4191 code.putln("default:")
4192 self.else_clause.generate_execution_code(code)
4193 code.putln("break;")
4196 def generate_function_definitions(self, env, code):
4197 self.test.generate_function_definitions(env, code)
4198 for case in self.cases:
4199 case.generate_function_definitions(env, code)
4200 if self.else_clause is not None:
4201 self.else_clause.generate_function_definitions(env, code)
4203 def annotate(self, code):
4204 self.test.annotate(code)
4205 for case in self.cases:
4207 if self.else_clause is not None:
4208 self.else_clause.annotate(code)
4210 class LoopNode(object):
4212 def analyse_control_flow(self, env):
4213 env.start_branching(self.pos)
4214 self.body.analyse_control_flow(env)
4215 env.next_branch(self.body.end_pos())
4216 if self.else_clause:
4217 self.else_clause.analyse_control_flow(env)
4218 env.finish_branching(self.end_pos())
4221 class WhileStatNode(LoopNode, StatNode):
4224 # condition ExprNode
4226 # else_clause StatNode
4228 child_attrs = ["condition", "body", "else_clause"]
4230 def analyse_declarations(self, env):
4231 self.body.analyse_declarations(env)
4232 if self.else_clause:
4233 self.else_clause.analyse_declarations(env)
4235 def analyse_expressions(self, env):
4237 self.condition.analyse_temp_boolean_expression(env)
4238 self.body.analyse_expressions(env)
4239 if self.else_clause:
4240 self.else_clause.analyse_expressions(env)
4242 def generate_execution_code(self, code):
4243 old_loop_labels = code.new_loop_labels()
4246 self.condition.generate_evaluation_code(code)
4247 self.condition.generate_disposal_code(code)
4250 self.condition.result())
4251 self.condition.free_temps(code)
4252 self.body.generate_execution_code(code)
4253 code.put_label(code.continue_label)
4255 break_label = code.break_label
4256 code.set_loop_labels(old_loop_labels)
4257 if self.else_clause:
4258 code.putln("/*else*/ {")
4259 self.else_clause.generate_execution_code(code)
4261 code.put_label(break_label)
4263 def generate_function_definitions(self, env, code):
4264 self.condition.generate_function_definitions(env, code)
4265 self.body.generate_function_definitions(env, code)
4266 if self.else_clause is not None:
4267 self.else_clause.generate_function_definitions(env, code)
4269 def annotate(self, code):
4270 self.condition.annotate(code)
4271 self.body.annotate(code)
4272 if self.else_clause:
4273 self.else_clause.annotate(code)
4276 def ForStatNode(pos, **kw):
4277 if 'iterator' in kw:
4278 return ForInStatNode(pos, **kw)
4280 return ForFromStatNode(pos, **kw)
4282 class ForInStatNode(LoopNode, StatNode):
4286 # iterator IteratorNode
4288 # else_clause StatNode
4289 # item NextNode used internally
4291 child_attrs = ["target", "iterator", "body", "else_clause"]
4294 def analyse_declarations(self, env):
4295 self.target.analyse_target_declaration(env)
4296 self.body.analyse_declarations(env)
4297 if self.else_clause:
4298 self.else_clause.analyse_declarations(env)
4300 def analyse_expressions(self, env):
4302 self.target.analyse_target_types(env)
4303 self.iterator.analyse_expressions(env)
4304 self.item = ExprNodes.NextNode(self.iterator, env)
4305 self.item = self.item.coerce_to(self.target.type, env)
4306 self.body.analyse_expressions(env)
4307 if self.else_clause:
4308 self.else_clause.analyse_expressions(env)
4310 def generate_execution_code(self, code):
4311 old_loop_labels = code.new_loop_labels()
4312 self.iterator.allocate_counter_temp(code)
4313 self.iterator.generate_evaluation_code(code)
4316 self.item.generate_evaluation_code(code)
4317 self.target.generate_assignment_code(self.item, code)
4318 self.body.generate_execution_code(code)
4319 code.put_label(code.continue_label)
4322 break_label = code.break_label
4323 code.set_loop_labels(old_loop_labels)
4325 if self.else_clause:
4326 # in nested loops, the 'else' block can contain a
4327 # 'continue' statement for the outer loop, but we may need
4328 # to generate cleanup code before taking that path, so we
4330 orig_continue_label = code.continue_label
4331 code.continue_label = code.new_label('outer_continue')
4333 code.putln("/*else*/ {")
4334 self.else_clause.generate_execution_code(code)
4337 if code.label_used(code.continue_label):
4338 code.put_goto(break_label)
4339 code.put_label(code.continue_label)
4340 self.iterator.generate_disposal_code(code)
4341 code.put_goto(orig_continue_label)
4342 code.set_loop_labels(old_loop_labels)
4344 if code.label_used(break_label):
4345 code.put_label(break_label)
4346 self.iterator.release_counter_temp(code)
4347 self.iterator.generate_disposal_code(code)
4348 self.iterator.free_temps(code)
4350 def generate_function_definitions(self, env, code):
4351 self.target.generate_function_definitions(env, code)
4352 self.iterator.generate_function_definitions(env, code)
4353 self.body.generate_function_definitions(env, code)
4354 if self.else_clause is not None:
4355 self.else_clause.generate_function_definitions(env, code)
4357 def annotate(self, code):
4358 self.target.annotate(code)
4359 self.iterator.annotate(code)
4360 self.body.annotate(code)
4361 if self.else_clause:
4362 self.else_clause.annotate(code)
4363 self.item.annotate(code)
4366 class ForFromStatNode(LoopNode, StatNode):
4367 # for name from expr rel name rel expr
4374 # step ExprNode or None
4376 # else_clause StatNode or None
4382 # loopvar_node ExprNode (usually a NameNode or temp node)
4383 # py_loopvar_node PyTempNode or None
4384 child_attrs = ["target", "bound1", "bound2", "step", "body", "else_clause"]
4386 is_py_target = False
4388 py_loopvar_node = None
4391 gil_message = "For-loop using object bounds or target"
4393 def nogil_check(self, env):
4394 for x in (self.target, self.bound1, self.bound2):
4395 if x.type.is_pyobject:
4398 def analyse_declarations(self, env):
4399 self.target.analyse_target_declaration(env)
4400 self.body.analyse_declarations(env)
4401 if self.else_clause:
4402 self.else_clause.analyse_declarations(env)
4404 def analyse_expressions(self, env):
4406 self.target.analyse_target_types(env)
4407 self.bound1.analyse_types(env)
4408 self.bound2.analyse_types(env)
4409 if self.step is not None:
4410 if isinstance(self.step, ExprNodes.UnaryMinusNode):
4411 warning(self.step.pos, "Probable infinite loop in for-from-by statment. Consider switching the directions of the relations.", 2)
4412 self.step.analyse_types(env)
4414 target_type = self.target.type
4415 if self.target.type.is_numeric:
4416 loop_type = self.target.type
4418 loop_type = PyrexTypes.c_int_type
4419 if not self.bound1.type.is_pyobject:
4420 loop_type = PyrexTypes.widest_numeric_type(loop_type, self.bound1.type)
4421 if not self.bound2.type.is_pyobject:
4422 loop_type = PyrexTypes.widest_numeric_type(loop_type, self.bound2.type)
4423 if self.step is not None and not self.step.type.is_pyobject:
4424 loop_type = PyrexTypes.widest_numeric_type(loop_type, self.step.type)
4425 self.bound1 = self.bound1.coerce_to(loop_type, env)
4426 self.bound2 = self.bound2.coerce_to(loop_type, env)
4427 if not self.bound2.is_literal:
4428 self.bound2 = self.bound2.coerce_to_temp(env)
4429 if self.step is not None:
4430 self.step = self.step.coerce_to(loop_type, env)
4431 if not self.step.is_literal:
4432 self.step = self.step.coerce_to_temp(env)
4434 target_type = self.target.type
4435 if not (target_type.is_pyobject or target_type.is_numeric):
4436 error(self.target.pos,
4437 "for-from loop variable must be c numeric type or Python object")
4438 if target_type.is_numeric:
4439 self.is_py_target = False
4440 if isinstance(self.target, ExprNodes.IndexNode) and self.target.is_buffer_access:
4441 raise error(self.pos, "Buffer indexing not allowed as for loop target.")
4442 self.loopvar_node = self.target
4443 self.py_loopvar_node = None
4445 self.is_py_target = True
4446 c_loopvar_node = ExprNodes.TempNode(self.pos, loop_type, env)
4447 self.loopvar_node = c_loopvar_node
4448 self.py_loopvar_node = \
4449 ExprNodes.CloneNode(c_loopvar_node).coerce_to_pyobject(env)
4450 self.body.analyse_expressions(env)
4451 if self.else_clause:
4452 self.else_clause.analyse_expressions(env)
4454 def generate_execution_code(self, code):
4455 old_loop_labels = code.new_loop_labels()
4456 from_range = self.from_range
4457 self.bound1.generate_evaluation_code(code)
4458 self.bound2.generate_evaluation_code(code)
4459 offset, incop = self.relation_table[self.relation1]
4460 if self.step is not None:
4461 self.step.generate_evaluation_code(code)
4462 step = self.step.result()
4463 incop = "%s=%s" % (incop[0], step)
4465 if isinstance(self.loopvar_node, ExprNodes.TempNode):
4466 self.loopvar_node.allocate(code)
4467 if isinstance(self.py_loopvar_node, ExprNodes.TempNode):
4468 self.py_loopvar_node.allocate(code)
4470 loopvar_name = code.funcstate.allocate_temp(self.target.type, False)
4472 loopvar_name = self.loopvar_node.result()
4474 "for (%s = %s%s; %s %s %s; %s%s) {" % (
4476 self.bound1.result(), offset,
4477 loopvar_name, self.relation2, self.bound2.result(),
4478 loopvar_name, incop))
4479 if self.py_loopvar_node:
4480 self.py_loopvar_node.generate_evaluation_code(code)
4481 self.target.generate_assignment_code(self.py_loopvar_node, code)
4483 code.putln("%s = %s;" % (
4484 self.target.result(), loopvar_name))
4485 self.body.generate_execution_code(code)
4486 code.put_label(code.continue_label)
4487 if self.py_loopvar_node:
4488 # This mess is to make for..from loops with python targets behave
4489 # exactly like those with C targets with regards to re-assignment
4490 # of the loop variable.
4492 if self.target.entry.is_pyglobal:
4493 # We know target is a NameNode, this is the only ugly case.
4494 target_node = ExprNodes.PyTempNode(self.target.pos, None)
4495 target_node.allocate(code)
4496 interned_cname = code.intern_identifier(self.target.entry.name)
4497 code.globalstate.use_utility_code(ExprNodes.get_name_interned_utility_code)
4498 code.putln("%s = __Pyx_GetName(%s, %s); %s" % (
4499 target_node.result(),
4500 Naming.module_cname,
4502 code.error_goto_if_null(target_node.result(), self.target.pos)))
4503 code.put_gotref(target_node.result())
4505 target_node = self.target
4506 from_py_node = ExprNodes.CoerceFromPyTypeNode(self.loopvar_node.type, target_node, None)
4507 from_py_node.temp_code = loopvar_name
4508 from_py_node.generate_result_code(code)
4509 if self.target.entry.is_pyglobal:
4510 code.put_decref(target_node.result(), target_node.type)
4511 target_node.release(code)
4513 if self.py_loopvar_node:
4514 # This is potentially wasteful, but we don't want the semantics to
4515 # depend on whether or not the loop is a python type.
4516 self.py_loopvar_node.generate_evaluation_code(code)
4517 self.target.generate_assignment_code(self.py_loopvar_node, code)
4519 code.funcstate.release_temp(loopvar_name)
4520 break_label = code.break_label
4521 code.set_loop_labels(old_loop_labels)
4522 if self.else_clause:
4523 code.putln("/*else*/ {")
4524 self.else_clause.generate_execution_code(code)
4526 code.put_label(break_label)
4527 self.bound1.generate_disposal_code(code)
4528 self.bound1.free_temps(code)
4529 self.bound2.generate_disposal_code(code)
4530 self.bound2.free_temps(code)
4531 if isinstance(self.loopvar_node, ExprNodes.TempNode):
4532 self.loopvar_node.release(code)
4533 if isinstance(self.py_loopvar_node, ExprNodes.TempNode):
4534 self.py_loopvar_node.release(code)
4535 if self.step is not None:
4536 self.step.generate_disposal_code(code)
4537 self.step.free_temps(code)
4540 # {relop : (initial offset, increment op)}
4547 def generate_function_definitions(self, env, code):
4548 self.target.generate_function_definitions(env, code)
4549 self.bound1.generate_function_definitions(env, code)
4550 self.bound2.generate_function_definitions(env, code)
4551 if self.step is not None:
4552 self.step.generate_function_definitions(env, code)
4553 self.body.generate_function_definitions(env, code)
4554 if self.else_clause is not None:
4555 self.else_clause.generate_function_definitions(env, code)
4557 def annotate(self, code):
4558 self.target.annotate(code)
4559 self.bound1.annotate(code)
4560 self.bound2.annotate(code)
4562 self.step.annotate(code)
4563 self.body.annotate(code)
4564 if self.else_clause:
4565 self.else_clause.annotate(code)
4568 class WithStatNode(StatNode):
4570 Represents a Python with statement.
4572 This is only used at parse tree level; and is not present in
4573 analysis or generation phases.
4575 # manager The with statement manager object
4576 # target Node (lhs expression)
4578 child_attrs = ["manager", "target", "body"]
4580 class TryExceptStatNode(StatNode):
4581 # try .. except statement
4584 # except_clauses [ExceptClauseNode]
4585 # else_clause StatNode or None
4587 child_attrs = ["body", "except_clauses", "else_clause"]
4589 def analyse_control_flow(self, env):
4590 env.start_branching(self.pos)
4591 self.body.analyse_control_flow(env)
4592 successful_try = env.control_flow # grab this for later
4593 env.next_branch(self.body.end_pos())
4594 env.finish_branching(self.body.end_pos())
4596 env.start_branching(self.except_clauses[0].pos)
4597 for except_clause in self.except_clauses:
4598 except_clause.analyse_control_flow(env)
4599 env.next_branch(except_clause.end_pos())
4601 # the else cause it executed only when the try clause finishes
4602 env.control_flow.incoming = successful_try
4603 if self.else_clause:
4604 self.else_clause.analyse_control_flow(env)
4605 env.finish_branching(self.end_pos())
4607 def analyse_declarations(self, env):
4608 self.body.analyse_declarations(env)
4609 for except_clause in self.except_clauses:
4610 except_clause.analyse_declarations(env)
4611 if self.else_clause:
4612 self.else_clause.analyse_declarations(env)
4613 env.use_utility_code(reset_exception_utility_code)
4615 def analyse_expressions(self, env):
4616 self.body.analyse_expressions(env)
4617 default_clause_seen = 0
4618 for except_clause in self.except_clauses:
4619 except_clause.analyse_expressions(env)
4620 if default_clause_seen:
4621 error(except_clause.pos, "default 'except:' must be last")
4622 if not except_clause.pattern:
4623 default_clause_seen = 1
4624 self.has_default_clause = default_clause_seen
4625 if self.else_clause:
4626 self.else_clause.analyse_expressions(env)
4628 nogil_check = Node.gil_error
4629 gil_message = "Try-except statement"
4631 def generate_execution_code(self, code):
4632 old_return_label = code.return_label
4633 old_break_label = code.break_label
4634 old_continue_label = code.continue_label
4635 old_error_label = code.new_error_label()
4636 our_error_label = code.error_label
4637 except_end_label = code.new_label('exception_handled')
4638 except_error_label = code.new_label('except_error')
4639 except_return_label = code.new_label('except_return')
4640 try_return_label = code.new_label('try_return')
4641 try_break_label = code.new_label('try_break')
4642 try_continue_label = code.new_label('try_continue')
4643 try_end_label = code.new_label('try_end')
4646 code.putln("PyObject %s;" %
4647 ', '.join(['*%s' % var for var in Naming.exc_save_vars]))
4648 code.putln("__Pyx_ExceptionSave(%s);" %
4649 ', '.join(['&%s' % var for var in Naming.exc_save_vars]))
4650 for var in Naming.exc_save_vars:
4651 code.put_xgotref(var)
4654 code.return_label = try_return_label
4655 code.break_label = try_break_label
4656 code.continue_label = try_continue_label
4657 self.body.generate_execution_code(code)
4660 temps_to_clean_up = code.funcstate.all_free_managed_temps()
4661 code.error_label = except_error_label
4662 code.return_label = except_return_label
4663 if self.else_clause:
4666 self.else_clause.generate_execution_code(code)
4669 for var in Naming.exc_save_vars:
4670 code.put_xdecref_clear(var, py_object_type)
4671 code.put_goto(try_end_label)
4672 if code.label_used(try_return_label):
4673 code.put_label(try_return_label)
4674 for var in Naming.exc_save_vars: code.put_xgiveref(var)
4675 code.putln("__Pyx_ExceptionReset(%s);" %
4676 ', '.join(Naming.exc_save_vars))
4677 code.put_goto(old_return_label)
4678 code.put_label(our_error_label)
4679 for temp_name, type in temps_to_clean_up:
4680 code.put_xdecref_clear(temp_name, type)
4681 for except_clause in self.except_clauses:
4682 except_clause.generate_handling_code(code, except_end_label)
4684 error_label_used = code.label_used(except_error_label)
4685 if error_label_used or not self.has_default_clause:
4686 if error_label_used:
4687 code.put_label(except_error_label)
4688 for var in Naming.exc_save_vars: code.put_xgiveref(var)
4689 code.putln("__Pyx_ExceptionReset(%s);" %
4690 ', '.join(Naming.exc_save_vars))
4691 code.put_goto(old_error_label)
4693 for exit_label, old_label in zip(
4694 [try_break_label, try_continue_label, except_return_label],
4695 [old_break_label, old_continue_label, old_return_label]):
4697 if code.label_used(exit_label):
4698 code.put_label(exit_label)
4699 for var in Naming.exc_save_vars: code.put_xgiveref(var)
4700 code.putln("__Pyx_ExceptionReset(%s);" %
4701 ', '.join(Naming.exc_save_vars))
4702 code.put_goto(old_label)
4704 if code.label_used(except_end_label):
4705 code.put_label(except_end_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_label(try_end_label)
4712 code.return_label = old_return_label
4713 code.break_label = old_break_label
4714 code.continue_label = old_continue_label
4715 code.error_label = old_error_label
4717 def generate_function_definitions(self, env, code):
4718 self.body.generate_function_definitions(env, code)
4719 for except_clause in self.except_clauses:
4720 except_clause.generate_function_definitions(env, code)
4721 if self.else_clause is not None:
4722 self.else_clause.generate_function_definitions(env, code)
4724 def annotate(self, code):
4725 self.body.annotate(code)
4726 for except_node in self.except_clauses:
4727 except_node.annotate(code)
4728 if self.else_clause:
4729 self.else_clause.annotate(code)
4732 class ExceptClauseNode(Node):
4733 # Part of try ... except statement.
4735 # pattern [ExprNode]
4736 # target ExprNode or None
4738 # excinfo_target NameNode or None optional target for exception info
4739 # match_flag string result of exception match
4740 # exc_value ExcValueNode used internally
4741 # function_name string qualified name of enclosing function
4742 # exc_vars (string * 3) local exception variables
4744 # excinfo_target is never set by the parser, but can be set by a transform
4745 # in order to extract more extensive information about the exception as a
4746 # sys.exc_info()-style tuple into a target variable
4748 child_attrs = ["pattern", "target", "body", "exc_value", "excinfo_target"]
4751 excinfo_target = None
4753 def analyse_declarations(self, env):
4755 self.target.analyse_target_declaration(env)
4756 if self.excinfo_target is not None:
4757 self.excinfo_target.analyse_target_declaration(env)
4758 self.body.analyse_declarations(env)
4760 def analyse_expressions(self, env):
4762 genv = env.global_scope()
4763 self.function_name = env.qualified_name
4765 # normalise/unpack self.pattern into a list
4766 for i, pattern in enumerate(self.pattern):
4767 pattern.analyse_expressions(env)
4768 self.pattern[i] = pattern.coerce_to_pyobject(env)
4771 self.exc_value = ExprNodes.ExcValueNode(self.pos, env)
4772 self.target.analyse_target_expression(env, self.exc_value)
4773 if self.excinfo_target is not None:
4775 self.excinfo_tuple = ExprNodes.TupleNode(pos=self.pos, args=[
4776 ExprNodes.ExcValueNode(pos=self.pos, env=env) for x in range(3)])
4777 self.excinfo_tuple.analyse_expressions(env)
4778 self.excinfo_target.analyse_target_expression(env, self.excinfo_tuple)
4780 self.body.analyse_expressions(env)
4782 def generate_handling_code(self, code, end_label):
4783 code.mark_pos(self.pos)
4786 for pattern in self.pattern:
4787 pattern.generate_evaluation_code(code)
4788 exc_tests.append("PyErr_ExceptionMatches(%s)" % pattern.py_result())
4790 match_flag = code.funcstate.allocate_temp(PyrexTypes.c_int_type, False)
4792 "%s = %s;" % (match_flag, ' || '.join(exc_tests)))
4793 for pattern in self.pattern:
4794 pattern.generate_disposal_code(code)
4795 pattern.free_temps(code)
4799 code.funcstate.release_temp(match_flag)
4801 code.putln("/*except:*/ {")
4803 if not getattr(self.body, 'stats', True) and \
4804 self.excinfo_target is None and self.target is None:
4805 # most simple case: no exception variable, empty body (pass)
4806 # => reset the exception state, done
4807 code.putln("PyErr_Restore(0,0,0);")
4808 code.put_goto(end_label)
4812 exc_vars = [code.funcstate.allocate_temp(py_object_type,
4815 code.putln('__Pyx_AddTraceback("%s");' % self.function_name)
4816 # We always have to fetch the exception value even if
4817 # there is no target, because this also normalises the
4818 # exception and stores it in the thread state.
4819 code.globalstate.use_utility_code(get_exception_utility_code)
4820 exc_args = "&%s, &%s, &%s" % tuple(exc_vars)
4821 code.putln("if (__Pyx_GetException(%s) < 0) %s" % (exc_args,
4822 code.error_goto(self.pos)))
4826 self.exc_value.set_var(exc_vars[1])
4827 self.exc_value.generate_evaluation_code(code)
4828 self.target.generate_assignment_code(self.exc_value, code)
4829 if self.excinfo_target is not None:
4830 for tempvar, node in zip(exc_vars, self.excinfo_tuple.args):
4831 node.set_var(tempvar)
4832 self.excinfo_tuple.generate_evaluation_code(code)
4833 self.excinfo_target.generate_assignment_code(self.excinfo_tuple, code)
4835 old_break_label, old_continue_label = code.break_label, code.continue_label
4836 code.break_label = code.new_label('except_break')
4837 code.continue_label = code.new_label('except_continue')
4839 old_exc_vars = code.funcstate.exc_vars
4840 code.funcstate.exc_vars = exc_vars
4841 self.body.generate_execution_code(code)
4842 code.funcstate.exc_vars = old_exc_vars
4843 for var in exc_vars:
4844 code.putln("__Pyx_DECREF(%s); %s = 0;" % (var, var))
4845 code.put_goto(end_label)
4847 if code.label_used(code.break_label):
4848 code.put_label(code.break_label)
4849 for var in exc_vars:
4850 code.putln("__Pyx_DECREF(%s); %s = 0;" % (var, var))
4851 code.put_goto(old_break_label)
4852 code.break_label = old_break_label
4854 if code.label_used(code.continue_label):
4855 code.put_label(code.continue_label)
4856 for var in exc_vars:
4857 code.putln("__Pyx_DECREF(%s); %s = 0;" % (var, var))
4858 code.put_goto(old_continue_label)
4859 code.continue_label = old_continue_label
4861 for temp in exc_vars:
4862 code.funcstate.release_temp(temp)
4867 def generate_function_definitions(self, env, code):
4868 if self.target is not None:
4869 self.target.generate_function_definitions(env, code)
4870 self.body.generate_function_definitions(env, code)
4872 def annotate(self, code):
4874 for pattern in self.pattern:
4875 pattern.annotate(code)
4877 self.target.annotate(code)
4878 self.body.annotate(code)
4881 class TryFinallyStatNode(StatNode):
4882 # try ... finally statement
4885 # finally_clause StatNode
4887 # The plan is that we funnel all continue, break
4888 # return and error gotos into the beginning of the
4889 # finally block, setting a variable to remember which
4890 # one we're doing. At the end of the finally block, we
4891 # switch on the variable to figure out where to go.
4892 # In addition, if we're doing an error, we save the
4893 # exception on entry to the finally block and restore
4896 child_attrs = ["body", "finally_clause"]
4898 preserve_exception = 1
4900 disallow_continue_in_try_finally = 0
4901 # There doesn't seem to be any point in disallowing
4902 # continue in the try block, since we have no problem
4905 def create_analysed(pos, env, body, finally_clause):
4906 node = TryFinallyStatNode(pos, body=body, finally_clause=finally_clause)
4908 create_analysed = staticmethod(create_analysed)
4910 def analyse_control_flow(self, env):
4911 env.start_branching(self.pos)
4912 self.body.analyse_control_flow(env)
4913 env.next_branch(self.body.end_pos())
4914 env.finish_branching(self.body.end_pos())
4915 self.finally_clause.analyse_control_flow(env)
4917 def analyse_declarations(self, env):
4918 self.body.analyse_declarations(env)
4919 self.finally_clause.analyse_declarations(env)
4921 def analyse_expressions(self, env):
4922 self.body.analyse_expressions(env)
4923 self.finally_clause.analyse_expressions(env)
4925 nogil_check = Node.gil_error
4926 gil_message = "Try-finally statement"
4928 def generate_execution_code(self, code):
4929 old_error_label = code.error_label
4930 old_labels = code.all_new_labels()
4931 new_labels = code.get_all_labels()
4932 new_error_label = code.error_label
4933 catch_label = code.new_label()
4936 if self.disallow_continue_in_try_finally:
4937 was_in_try_finally = code.funcstate.in_try_finally
4938 code.funcstate.in_try_finally = 1
4939 self.body.generate_execution_code(code)
4940 if self.disallow_continue_in_try_finally:
4941 code.funcstate.in_try_finally = was_in_try_finally
4944 temps_to_clean_up = code.funcstate.all_free_managed_temps()
4945 code.mark_pos(self.finally_clause.pos)
4949 error_label_used = 0
4950 for i, new_label in enumerate(new_labels):
4951 if new_label in code.labels_used:
4952 cases_used.append(i)
4953 if new_label == new_error_label:
4954 error_label_used = 1
4955 error_label_case = i
4959 if error_label_used and self.preserve_exception:
4961 "PyObject *%s, *%s, *%s;" % Naming.exc_vars)
4963 "int %s;" % Naming.exc_lineno_name)
4964 exc_var_init_zero = ''.join(["%s = 0; " % var for var in Naming.exc_vars])
4965 exc_var_init_zero += '%s = 0;' % Naming.exc_lineno_name
4966 code.putln(exc_var_init_zero)
4968 exc_var_init_zero = None
4969 code.use_label(catch_label)
4971 "__pyx_why = 0; goto %s;" % catch_label)
4972 for i in cases_used:
4973 new_label = new_labels[i]
4974 #if new_label and new_label != "<try>":
4975 if new_label == new_error_label and self.preserve_exception:
4976 self.put_error_catcher(code,
4977 new_error_label, i+1, catch_label, temps_to_clean_up)
4979 code.put('%s: ' % new_label)
4980 if exc_var_init_zero:
4981 code.putln(exc_var_init_zero)
4982 code.putln("__pyx_why = %s; goto %s;" % (
4985 code.put_label(catch_label)
4986 code.set_all_labels(old_labels)
4987 if error_label_used:
4988 code.new_error_label()
4989 finally_error_label = code.error_label
4990 self.finally_clause.generate_execution_code(code)
4991 if error_label_used:
4992 if finally_error_label in code.labels_used and self.preserve_exception:
4993 over_label = code.new_label()
4994 code.put_goto(over_label);
4995 code.put_label(finally_error_label)
4996 code.putln("if (__pyx_why == %d) {" % (error_label_case + 1))
4997 for var in Naming.exc_vars:
4998 code.putln("Py_XDECREF(%s);" % var)
5000 code.put_goto(old_error_label)
5001 code.put_label(over_label)
5002 code.error_label = old_error_label
5005 "switch (__pyx_why) {")
5006 for i in cases_used:
5007 old_label = old_labels[i]
5008 if old_label == old_error_label and self.preserve_exception:
5009 self.put_error_uncatcher(code, i+1, old_error_label)
5011 code.use_label(old_label)
5013 "case %s: goto %s;" % (
5021 def generate_function_definitions(self, env, code):
5022 self.body.generate_function_definitions(env, code)
5023 self.finally_clause.generate_function_definitions(env, code)
5025 def put_error_catcher(self, code, error_label, i, catch_label, temps_to_clean_up):
5026 code.globalstate.use_utility_code(restore_exception_utility_code)
5033 for temp_name, type in temps_to_clean_up:
5034 code.put_xdecref_clear(temp_name, type)
5036 "__Pyx_ErrFetch(&%s, &%s, &%s);" %
5040 Naming.exc_lineno_name, Naming.lineno_cname))
5041 code.put_goto(catch_label)
5044 def put_error_uncatcher(self, code, i, error_label):
5045 code.globalstate.use_utility_code(restore_exception_utility_code)
5050 "__Pyx_ErrRestore(%s, %s, %s);" %
5054 Naming.lineno_cname, Naming.exc_lineno_name))
5055 for var in Naming.exc_vars:
5059 code.put_goto(error_label)
5063 def annotate(self, code):
5064 self.body.annotate(code)
5065 self.finally_clause.annotate(code)
5068 class GILStatNode(TryFinallyStatNode):
5069 # 'with gil' or 'with nogil' statement
5071 # state string 'gil' or 'nogil'
5075 preserve_exception = 0
5077 def __init__(self, pos, state, body):
5079 TryFinallyStatNode.__init__(self, pos,
5081 finally_clause = GILExitNode(pos, state = state))
5083 def analyse_expressions(self, env):
5084 env.use_utility_code(force_init_threads_utility_code)
5085 was_nogil = env.nogil
5087 TryFinallyStatNode.analyse_expressions(self, env)
5088 env.nogil = was_nogil
5092 def generate_execution_code(self, code):
5093 code.mark_pos(self.pos)
5095 if self.state == 'gil':
5096 code.putln("#ifdef WITH_THREAD")
5097 code.putln("PyGILState_STATE _save = PyGILState_Ensure();")
5098 code.putln("#endif")
5100 code.putln("#ifdef WITH_THREAD")
5101 code.putln("PyThreadState *_save;")
5102 code.putln("#endif")
5103 code.putln("Py_UNBLOCK_THREADS")
5104 TryFinallyStatNode.generate_execution_code(self, code)
5108 class GILExitNode(StatNode):
5109 # Used as the 'finally' block in a GILStatNode
5111 # state string 'gil' or 'nogil'
5115 def analyse_expressions(self, env):
5118 def generate_execution_code(self, code):
5119 if self.state == 'gil':
5120 code.putln("#ifdef WITH_THREAD")
5121 code.putln("PyGILState_Release(_save);")
5122 code.putln("#endif")
5124 code.putln("Py_BLOCK_THREADS")
5127 class CImportStatNode(StatNode):
5130 # module_name string Qualified name of module being imported
5131 # as_name string or None Name specified in "as" clause, if any
5135 def analyse_declarations(self, env):
5136 if not env.is_module_scope:
5137 error(self.pos, "cimport only allowed at module level")
5139 module_scope = env.find_module(self.module_name, self.pos)
5140 if "." in self.module_name:
5141 names = [EncodedString(name) for name in self.module_name.split(".")]
5143 top_module_scope = env.context.find_submodule(top_name)
5144 module_scope = top_module_scope
5145 for name in names[1:]:
5146 submodule_scope = module_scope.find_submodule(name)
5147 module_scope.declare_module(name, submodule_scope, self.pos)
5148 module_scope = submodule_scope
5150 env.declare_module(self.as_name, module_scope, self.pos)
5152 env.declare_module(top_name, top_module_scope, self.pos)
5154 name = self.as_name or self.module_name
5155 env.declare_module(name, module_scope, self.pos)
5157 def analyse_expressions(self, env):
5160 def generate_execution_code(self, code):
5164 class FromCImportStatNode(StatNode):
5165 # from ... cimport statement
5167 # module_name string Qualified name of module
5168 # imported_names [(pos, name, as_name, kind)] Names to be imported
5172 def analyse_declarations(self, env):
5173 if not env.is_module_scope:
5174 error(self.pos, "cimport only allowed at module level")
5176 module_scope = env.find_module(self.module_name, self.pos)
5177 env.add_imported_module(module_scope)
5178 for pos, name, as_name, kind in self.imported_names:
5180 for local_name, entry in module_scope.entries.items():
5181 env.add_imported_entry(local_name, entry, pos)
5183 entry = module_scope.lookup(name)
5185 if kind and not self.declaration_matches(entry, kind):
5186 entry.redeclared(pos)
5188 if kind == 'struct' or kind == 'union':
5189 entry = module_scope.declare_struct_or_union(name,
5190 kind = kind, scope = None, typedef_flag = 0, pos = pos)
5191 elif kind == 'class':
5192 entry = module_scope.declare_c_class(name, pos = pos,
5193 module_name = self.module_name)
5195 submodule_scope = env.context.find_module(name, relative_to = module_scope, pos = self.pos)
5196 if submodule_scope.parent_module is module_scope:
5197 env.declare_module(as_name or name, submodule_scope, self.pos)
5199 error(pos, "Name '%s' not declared in module '%s'"
5200 % (name, self.module_name))
5203 local_name = as_name or name
5204 env.add_imported_entry(local_name, entry, pos)
5206 def declaration_matches(self, entry, kind):
5207 if not entry.is_type:
5211 if not type.is_extension_type:
5214 if not type.is_struct_or_union:
5216 if kind != type.kind:
5220 def analyse_expressions(self, env):
5223 def generate_execution_code(self, code):
5227 class FromImportStatNode(StatNode):
5228 # from ... import statement
5231 # items [(string, NameNode)]
5232 # interned_items [(string, NameNode, ExprNode)]
5233 # item PyTempNode used internally
5234 # import_star boolean used internally
5236 child_attrs = ["module"]
5239 def analyse_declarations(self, env):
5240 for name, target in self.items:
5242 if not env.is_module_scope:
5243 error(self.pos, "import * only allowed at module level")
5245 env.has_import_star = 1
5246 self.import_star = 1
5248 target.analyse_target_declaration(env)
5250 def analyse_expressions(self, env):
5252 self.module.analyse_expressions(env)
5253 self.item = ExprNodes.RawCNameExprNode(self.pos, py_object_type)
5254 self.interned_items = []
5255 for name, target in self.items:
5257 for _, entry in env.entries.items():
5258 if not entry.is_type and entry.type.is_extension_type:
5259 env.use_utility_code(ExprNodes.type_test_utility_code)
5262 entry = env.lookup(target.name)
5263 # check whether or not entry is already cimported
5264 if (entry.is_type and entry.type.name == name
5265 and hasattr(entry.type, 'module_name')):
5266 if entry.type.module_name == self.module.module_name.value:
5267 # cimported with absolute name
5270 # cimported with relative name
5271 module = env.find_module(self.module.module_name.value,
5273 if entry.type.module_name == module.qualified_name:
5275 except AttributeError:
5277 target.analyse_target_expression(env, None)
5278 if target.type is py_object_type:
5281 coerced_item = self.item.coerce_to(target.type, env)
5282 self.interned_items.append((name, target, coerced_item))
5284 def generate_execution_code(self, code):
5285 self.module.generate_evaluation_code(code)
5286 if self.import_star:
5288 'if (%s(%s) < 0) %s;' % (
5290 self.module.py_result(),
5291 code.error_goto(self.pos)))
5292 item_temp = code.funcstate.allocate_temp(py_object_type, manage_ref=True)
5293 self.item.set_cname(item_temp)
5294 for name, target, coerced_item in self.interned_items:
5295 cname = code.intern_identifier(name)
5297 '%s = PyObject_GetAttr(%s, %s); %s' % (
5299 self.module.py_result(),
5301 code.error_goto_if_null(item_temp, self.pos)))
5302 code.put_gotref(item_temp)
5303 if coerced_item is None:
5304 target.generate_assignment_code(self.item, code)
5306 coerced_item.allocate_temp_result(code)
5307 coerced_item.generate_result_code(code)
5308 target.generate_assignment_code(coerced_item, code)
5309 code.put_decref_clear(item_temp, py_object_type)
5310 code.funcstate.release_temp(item_temp)
5311 self.module.generate_disposal_code(code)
5312 self.module.free_temps(code)
5316 #------------------------------------------------------------------------------------
5318 # Runtime support code
5320 #------------------------------------------------------------------------------------
5322 utility_function_predeclarations = \
5324 /* inline attribute */
5325 #ifndef CYTHON_INLINE
5326 #if defined(__GNUC__)
5327 #define CYTHON_INLINE __inline__
5328 #elif defined(_MSC_VER)
5329 #define CYTHON_INLINE __inline
5330 #elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
5331 #define CYTHON_INLINE inline
5333 #define CYTHON_INLINE
5337 /* unused attribute */
5338 #ifndef CYTHON_UNUSED
5339 # if defined(__GNUC__)
5340 # if !(defined(__cplusplus)) || (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4))
5341 # define CYTHON_UNUSED __attribute__ ((__unused__))
5343 # define CYTHON_UNUSED
5345 # elif defined(__ICC) || defined(__INTEL_COMPILER)
5346 # define CYTHON_UNUSED __attribute__ ((__unused__))
5348 # define CYTHON_UNUSED
5352 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*/
5356 if Options.gcc_branch_hints:
5357 branch_prediction_macros = \
5360 /* Test for GCC > 2.95 */
5361 #if __GNUC__ > 2 || (__GNUC__ == 2 && (__GNUC_MINOR__ > 95))
5362 #define likely(x) __builtin_expect(!!(x), 1)
5363 #define unlikely(x) __builtin_expect(!!(x), 0)
5364 #else /* __GNUC__ > 2 ... */
5365 #define likely(x) (x)
5366 #define unlikely(x) (x)
5367 #endif /* __GNUC__ > 2 ... */
5368 #else /* __GNUC__ */
5369 #define likely(x) (x)
5370 #define unlikely(x) (x)
5371 #endif /* __GNUC__ */
5374 branch_prediction_macros = \
5376 #define likely(x) (x)
5377 #define unlikely(x) (x)
5380 #get_name_predeclaration = \
5381 #"static PyObject *__Pyx_GetName(PyObject *dict, char *name); /*proto*/"
5383 #get_name_interned_predeclaration = \
5384 #"static PyObject *__Pyx_GetName(PyObject *dict, PyObject *name); /*proto*/"
5386 #------------------------------------------------------------------------------------
5388 printing_utility_code = UtilityCode(
5390 static int __Pyx_Print(PyObject*, PyObject *, int); /*proto*/
5391 #if PY_MAJOR_VERSION >= 3
5392 static PyObject* %s = 0;
5393 static PyObject* %s = 0;
5395 """ % (Naming.print_function, Naming.print_function_kwargs),
5397 #if PY_MAJOR_VERSION >= 3
5401 """ % (Naming.print_function, Naming.print_function_kwargs),
5403 #if PY_MAJOR_VERSION < 3
5404 static PyObject *__Pyx_GetStdout(void) {
5405 PyObject *f = PySys_GetObject((char *)"stdout");
5407 PyErr_SetString(PyExc_RuntimeError, "lost sys.stdout");
5412 static int __Pyx_Print(PyObject* f, PyObject *arg_tuple, int newline) {
5417 if (!(f = __Pyx_GetStdout()))
5420 for (i=0; i < PyTuple_GET_SIZE(arg_tuple); i++) {
5421 if (PyFile_SoftSpace(f, 1)) {
5422 if (PyFile_WriteString(" ", f) < 0)
5425 v = PyTuple_GET_ITEM(arg_tuple, i);
5426 if (PyFile_WriteObject(v, f, Py_PRINT_RAW) < 0)
5428 if (PyString_Check(v)) {
5429 char *s = PyString_AsString(v);
5430 Py_ssize_t len = PyString_Size(v);
5432 isspace(Py_CHARMASK(s[len-1])) &&
5434 PyFile_SoftSpace(f, 0);
5438 if (PyFile_WriteString("\n", f) < 0)
5440 PyFile_SoftSpace(f, 0);
5445 #else /* Python 3 has a print function */
5447 static int __Pyx_Print(PyObject* stream, PyObject *arg_tuple, int newline) {
5448 PyObject* kwargs = 0;
5449 PyObject* result = 0;
5450 PyObject* end_string;
5451 if (unlikely(!%(PRINT_FUNCTION)s)) {
5452 %(PRINT_FUNCTION)s = __Pyx_GetAttrString(%(BUILTINS)s, "print");
5453 if (!%(PRINT_FUNCTION)s)
5457 kwargs = PyDict_New();
5458 if (unlikely(!kwargs))
5460 if (unlikely(PyDict_SetItemString(kwargs, "file", stream) < 0))
5463 end_string = PyUnicode_FromStringAndSize(" ", 1);
5464 if (unlikely(!end_string))
5466 if (PyDict_SetItemString(kwargs, "end", end_string) < 0) {
5467 Py_DECREF(end_string);
5470 Py_DECREF(end_string);
5472 } else if (!newline) {
5473 if (unlikely(!%(PRINT_KWARGS)s)) {
5474 %(PRINT_KWARGS)s = PyDict_New();
5475 if (unlikely(!%(PRINT_KWARGS)s))
5477 end_string = PyUnicode_FromStringAndSize(" ", 1);
5478 if (unlikely(!end_string))
5480 if (PyDict_SetItemString(%(PRINT_KWARGS)s, "end", end_string) < 0) {
5481 Py_DECREF(end_string);
5484 Py_DECREF(end_string);
5486 kwargs = %(PRINT_KWARGS)s;
5488 result = PyObject_Call(%(PRINT_FUNCTION)s, arg_tuple, kwargs);
5489 if (unlikely(kwargs) && (kwargs != %(PRINT_KWARGS)s))
5496 if (kwargs != %(PRINT_KWARGS)s)
5502 """ % {'BUILTINS' : Naming.builtins_cname,
5503 'PRINT_FUNCTION' : Naming.print_function,
5504 'PRINT_KWARGS' : Naming.print_function_kwargs}
5508 printing_one_utility_code = UtilityCode(
5510 static int __Pyx_PrintOne(PyObject* stream, PyObject *o); /*proto*/
5513 #if PY_MAJOR_VERSION < 3
5515 static int __Pyx_PrintOne(PyObject* f, PyObject *o) {
5517 if (!(f = __Pyx_GetStdout()))
5520 if (PyFile_SoftSpace(f, 0)) {
5521 if (PyFile_WriteString(" ", f) < 0)
5524 if (PyFile_WriteObject(o, f, Py_PRINT_RAW) < 0)
5526 if (PyFile_WriteString("\n", f) < 0)
5529 /* the line below is just to avoid compiler
5530 * compiler warnings about unused functions */
5531 return __Pyx_Print(f, NULL, 0);
5534 #else /* Python 3 has a print function */
5536 static int __Pyx_PrintOne(PyObject* stream, PyObject *o) {
5538 PyObject* arg_tuple = PyTuple_New(1);
5539 if (unlikely(!arg_tuple))
5542 PyTuple_SET_ITEM(arg_tuple, 0, o);
5543 res = __Pyx_Print(stream, arg_tuple, 1);
5544 Py_DECREF(arg_tuple);
5550 requires=[printing_utility_code])
5554 #------------------------------------------------------------------------------------
5556 # Exception raising code
5558 # Exceptions are raised by __Pyx_Raise() and stored as plain
5559 # type/value/tb in PyThreadState->curexc_*. When being caught by an
5560 # 'except' statement, curexc_* is moved over to exc_* by
5561 # __Pyx_GetException()
5563 restore_exception_utility_code = UtilityCode(
5565 static CYTHON_INLINE void __Pyx_ErrRestore(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
5566 static CYTHON_INLINE void __Pyx_ErrFetch(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
5569 static CYTHON_INLINE void __Pyx_ErrRestore(PyObject *type, PyObject *value, PyObject *tb) {
5570 PyObject *tmp_type, *tmp_value, *tmp_tb;
5571 PyThreadState *tstate = PyThreadState_GET();
5573 tmp_type = tstate->curexc_type;
5574 tmp_value = tstate->curexc_value;
5575 tmp_tb = tstate->curexc_traceback;
5576 tstate->curexc_type = type;
5577 tstate->curexc_value = value;
5578 tstate->curexc_traceback = tb;
5579 Py_XDECREF(tmp_type);
5580 Py_XDECREF(tmp_value);
5584 static CYTHON_INLINE void __Pyx_ErrFetch(PyObject **type, PyObject **value, PyObject **tb) {
5585 PyThreadState *tstate = PyThreadState_GET();
5586 *type = tstate->curexc_type;
5587 *value = tstate->curexc_value;
5588 *tb = tstate->curexc_traceback;
5590 tstate->curexc_type = 0;
5591 tstate->curexc_value = 0;
5592 tstate->curexc_traceback = 0;
5597 # The following function is based on do_raise() from ceval.c. There
5598 # are separate versions for Python2 and Python3 as exception handling
5599 # has changed quite a lot between the two versions.
5601 raise_utility_code = UtilityCode(
5603 static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
5606 #if PY_MAJOR_VERSION < 3
5607 static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb) {
5611 /* First, check the traceback argument, replacing None with NULL. */
5612 if (tb == Py_None) {
5616 else if (tb != NULL && !PyTraceBack_Check(tb)) {
5617 PyErr_SetString(PyExc_TypeError,
5618 "raise: arg 3 must be a traceback or None");
5621 /* Next, replace a missing value with None */
5622 if (value == NULL) {
5626 #if PY_VERSION_HEX < 0x02050000
5627 if (!PyClass_Check(type))
5629 if (!PyType_Check(type))
5632 /* Raising an instance. The value should be a dummy. */
5633 if (value != Py_None) {
5634 PyErr_SetString(PyExc_TypeError,
5635 "instance exception may not have a separate value");
5638 /* Normalize to raise <class>, <instance> */
5641 #if PY_VERSION_HEX < 0x02050000
5642 if (PyInstance_Check(type)) {
5643 type = (PyObject*) ((PyInstanceObject*)type)->in_class;
5648 PyErr_SetString(PyExc_TypeError,
5649 "raise: exception must be an old-style class or instance");
5653 type = (PyObject*) Py_TYPE(type);
5655 if (!PyType_IsSubtype((PyTypeObject *)type, (PyTypeObject *)PyExc_BaseException)) {
5656 PyErr_SetString(PyExc_TypeError,
5657 "raise: exception class must be a subclass of BaseException");
5663 __Pyx_ErrRestore(type, value, tb);
5672 #else /* Python 3+ */
5674 static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb) {
5675 if (tb == Py_None) {
5677 } else if (tb && !PyTraceBack_Check(tb)) {
5678 PyErr_SetString(PyExc_TypeError,
5679 "raise: arg 3 must be a traceback or None");
5682 if (value == Py_None)
5685 if (PyExceptionInstance_Check(type)) {
5687 PyErr_SetString(PyExc_TypeError,
5688 "instance exception may not have a separate value");
5692 type = (PyObject*) Py_TYPE(value);
5693 } else if (!PyExceptionClass_Check(type)) {
5694 PyErr_SetString(PyExc_TypeError,
5695 "raise: exception class must be a subclass of BaseException");
5699 PyErr_SetObject(type, value);
5702 PyThreadState *tstate = PyThreadState_GET();
5703 PyObject* tmp_tb = tstate->curexc_traceback;
5706 tstate->curexc_traceback = tb;
5716 requires=[restore_exception_utility_code])
5718 #------------------------------------------------------------------------------------
5720 get_exception_utility_code = UtilityCode(
5722 static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
5725 static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb) {
5726 PyObject *local_type, *local_value, *local_tb;
5727 PyObject *tmp_type, *tmp_value, *tmp_tb;
5728 PyThreadState *tstate = PyThreadState_GET();
5729 local_type = tstate->curexc_type;
5730 local_value = tstate->curexc_value;
5731 local_tb = tstate->curexc_traceback;
5732 tstate->curexc_type = 0;
5733 tstate->curexc_value = 0;
5734 tstate->curexc_traceback = 0;
5735 PyErr_NormalizeException(&local_type, &local_value, &local_tb);
5736 if (unlikely(tstate->curexc_type))
5738 #if PY_MAJOR_VERSION >= 3
5739 if (unlikely(PyException_SetTraceback(local_value, local_tb) < 0))
5743 *value = local_value;
5745 Py_INCREF(local_type);
5746 Py_INCREF(local_value);
5747 Py_INCREF(local_tb);
5748 tmp_type = tstate->exc_type;
5749 tmp_value = tstate->exc_value;
5750 tmp_tb = tstate->exc_traceback;
5751 tstate->exc_type = local_type;
5752 tstate->exc_value = local_value;
5753 tstate->exc_traceback = local_tb;
5754 /* Make sure tstate is in a consistent state when we XDECREF
5755 these objects (XDECREF may run arbitrary code). */
5756 Py_XDECREF(tmp_type);
5757 Py_XDECREF(tmp_value);
5764 Py_XDECREF(local_type);
5765 Py_XDECREF(local_value);
5766 Py_XDECREF(local_tb);
5772 #------------------------------------------------------------------------------------
5774 get_exception_tuple_utility_code = UtilityCode(proto="""
5775 static PyObject *__Pyx_GetExceptionTuple(void); /*proto*/
5777 # I doubt that calling __Pyx_GetException() here is correct as it moves
5778 # the exception from tstate->curexc_* to tstate->exc_*, which prevents
5779 # exception handlers later on from receiving it.
5781 static PyObject *__Pyx_GetExceptionTuple(void) {
5782 PyObject *type = NULL, *value = NULL, *tb = NULL;
5783 if (__Pyx_GetException(&type, &value, &tb) == 0) {
5784 PyObject* exc_info = PyTuple_New(3);
5789 PyTuple_SET_ITEM(exc_info, 0, type);
5790 PyTuple_SET_ITEM(exc_info, 1, value);
5791 PyTuple_SET_ITEM(exc_info, 2, tb);
5798 requires=[get_exception_utility_code])
5800 #------------------------------------------------------------------------------------
5802 reset_exception_utility_code = UtilityCode(
5804 static CYTHON_INLINE void __Pyx_ExceptionSave(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
5805 static void __Pyx_ExceptionReset(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
5808 static CYTHON_INLINE void __Pyx_ExceptionSave(PyObject **type, PyObject **value, PyObject **tb) {
5809 PyThreadState *tstate = PyThreadState_GET();
5810 *type = tstate->exc_type;
5811 *value = tstate->exc_value;
5812 *tb = tstate->exc_traceback;
5818 static void __Pyx_ExceptionReset(PyObject *type, PyObject *value, PyObject *tb) {
5819 PyObject *tmp_type, *tmp_value, *tmp_tb;
5820 PyThreadState *tstate = PyThreadState_GET();
5821 tmp_type = tstate->exc_type;
5822 tmp_value = tstate->exc_value;
5823 tmp_tb = tstate->exc_traceback;
5824 tstate->exc_type = type;
5825 tstate->exc_value = value;
5826 tstate->exc_traceback = tb;
5827 Py_XDECREF(tmp_type);
5828 Py_XDECREF(tmp_value);
5833 #------------------------------------------------------------------------------------
5835 arg_type_test_utility_code = UtilityCode(
5837 static int __Pyx_ArgTypeTest(PyObject *obj, PyTypeObject *type, int none_allowed,
5838 const char *name, int exact); /*proto*/
5841 static int __Pyx_ArgTypeTest(PyObject *obj, PyTypeObject *type, int none_allowed,
5842 const char *name, int exact)
5845 PyErr_Format(PyExc_SystemError, "Missing type object");
5848 if (none_allowed && obj == Py_None) return 1;
5850 if (Py_TYPE(obj) == type) return 1;
5853 if (PyObject_TypeCheck(obj, type)) return 1;
5855 PyErr_Format(PyExc_TypeError,
5856 "Argument '%s' has incorrect type (expected %s, got %s)",
5857 name, type->tp_name, Py_TYPE(obj)->tp_name);
5862 #------------------------------------------------------------------------------------
5864 # __Pyx_RaiseArgtupleInvalid raises the correct exception when too
5865 # many or too few positional arguments were found. This handles
5866 # Py_ssize_t formatting correctly.
5868 raise_argtuple_invalid_utility_code = UtilityCode(
5870 static void __Pyx_RaiseArgtupleInvalid(const char* func_name, int exact,
5871 Py_ssize_t num_min, Py_ssize_t num_max, Py_ssize_t num_found); /*proto*/
5874 static void __Pyx_RaiseArgtupleInvalid(
5875 const char* func_name,
5879 Py_ssize_t num_found)
5881 Py_ssize_t num_expected;
5882 const char *number, *more_or_less;
5884 if (num_found < num_min) {
5885 num_expected = num_min;
5886 more_or_less = "at least";
5888 num_expected = num_max;
5889 more_or_less = "at most";
5892 more_or_less = "exactly";
5894 number = (num_expected == 1) ? "" : "s";
5895 PyErr_Format(PyExc_TypeError,
5896 #if PY_VERSION_HEX < 0x02050000
5897 "%s() takes %s %d positional argument%s (%d given)",
5899 "%s() takes %s %zd positional argument%s (%zd given)",
5901 func_name, more_or_less, num_expected, number, num_found);
5905 raise_keyword_required_utility_code = UtilityCode(
5907 static CYTHON_INLINE void __Pyx_RaiseKeywordRequired(const char* func_name, PyObject* kw_name); /*proto*/
5910 static CYTHON_INLINE void __Pyx_RaiseKeywordRequired(
5911 const char* func_name,
5914 PyErr_Format(PyExc_TypeError,
5915 #if PY_MAJOR_VERSION >= 3
5916 "%s() needs keyword-only argument %U", func_name, kw_name);
5918 "%s() needs keyword-only argument %s", func_name,
5919 PyString_AS_STRING(kw_name));
5924 raise_double_keywords_utility_code = UtilityCode(
5926 static void __Pyx_RaiseDoubleKeywordsError(
5927 const char* func_name, PyObject* kw_name); /*proto*/
5930 static void __Pyx_RaiseDoubleKeywordsError(
5931 const char* func_name,
5934 PyErr_Format(PyExc_TypeError,
5935 #if PY_MAJOR_VERSION >= 3
5936 "%s() got multiple values for keyword argument '%U'", func_name, kw_name);
5938 "%s() got multiple values for keyword argument '%s'", func_name,
5939 PyString_AS_STRING(kw_name));
5944 #------------------------------------------------------------------------------------
5946 # __Pyx_CheckKeywordStrings raises an error if non-string keywords
5947 # were passed to a function, or if any keywords were passed to a
5948 # function that does not accept them.
5950 keyword_string_check_utility_code = UtilityCode(
5952 static CYTHON_INLINE int __Pyx_CheckKeywordStrings(PyObject *kwdict,
5953 const char* function_name, int kw_allowed); /*proto*/
5956 static CYTHON_INLINE int __Pyx_CheckKeywordStrings(
5958 const char* function_name,
5963 while (PyDict_Next(kwdict, &pos, &key, 0)) {
5964 #if PY_MAJOR_VERSION < 3
5965 if (unlikely(!PyString_CheckExact(key)) && unlikely(!PyString_Check(key)))
5967 if (unlikely(!PyUnicode_CheckExact(key)) && unlikely(!PyUnicode_Check(key)))
5969 goto invalid_keyword_type;
5971 if ((!kw_allowed) && unlikely(key))
5972 goto invalid_keyword;
5974 invalid_keyword_type:
5975 PyErr_Format(PyExc_TypeError,
5976 "%s() keywords must be strings", function_name);
5979 PyErr_Format(PyExc_TypeError,
5980 #if PY_MAJOR_VERSION < 3
5981 "%s() got an unexpected keyword argument '%s'",
5982 function_name, PyString_AsString(key));
5984 "%s() got an unexpected keyword argument '%U'",
5985 function_name, key);
5991 #------------------------------------------------------------------------------------
5993 # __Pyx_ParseOptionalKeywords copies the optional/unknown keyword
5994 # arguments from the kwds dict into kwds2. If kwds2 is NULL, unknown
5995 # keywords will raise an invalid keyword error.
5997 # Three kinds of errors are checked: 1) non-string keywords, 2)
5998 # unexpected keywords and 3) overlap with positional arguments.
6000 # If num_posargs is greater 0, it denotes the number of positional
6001 # arguments that were passed and that must therefore not appear
6002 # amongst the keywords as well.
6004 # This method does not check for required keyword arguments.
6007 parse_keywords_utility_code = UtilityCode(
6009 static int __Pyx_ParseOptionalKeywords(PyObject *kwds, PyObject **argnames[], \
6010 PyObject *kwds2, PyObject *values[], Py_ssize_t num_pos_args, \
6011 const char* function_name); /*proto*/
6014 static int __Pyx_ParseOptionalKeywords(
6016 PyObject **argnames[],
6019 Py_ssize_t num_pos_args,
6020 const char* function_name)
6022 PyObject *key = 0, *value = 0;
6025 PyObject*** first_kw_arg = argnames + num_pos_args;
6027 while (PyDict_Next(kwds, &pos, &key, &value)) {
6028 name = first_kw_arg;
6029 while (*name && (**name != key)) name++;
6031 values[name-argnames] = value;
6033 #if PY_MAJOR_VERSION < 3
6034 if (unlikely(!PyString_CheckExact(key)) && unlikely(!PyString_Check(key))) {
6036 if (unlikely(!PyUnicode_CheckExact(key)) && unlikely(!PyUnicode_Check(key))) {
6038 goto invalid_keyword_type;
6040 for (name = first_kw_arg; *name; name++) {
6041 #if PY_MAJOR_VERSION >= 3
6042 if (PyUnicode_GET_SIZE(**name) == PyUnicode_GET_SIZE(key) &&
6043 PyUnicode_Compare(**name, key) == 0) break;
6045 if (PyString_GET_SIZE(**name) == PyString_GET_SIZE(key) &&
6046 _PyString_Eq(**name, key)) break;
6050 values[name-argnames] = value;
6052 /* unexpected keyword found */
6053 for (name=argnames; name != first_kw_arg; name++) {
6054 if (**name == key) goto arg_passed_twice;
6055 #if PY_MAJOR_VERSION >= 3
6056 if (PyUnicode_GET_SIZE(**name) == PyUnicode_GET_SIZE(key) &&
6057 PyUnicode_Compare(**name, key) == 0) goto arg_passed_twice;
6059 if (PyString_GET_SIZE(**name) == PyString_GET_SIZE(key) &&
6060 _PyString_Eq(**name, key)) goto arg_passed_twice;
6064 if (unlikely(PyDict_SetItem(kwds2, key, value))) goto bad;
6066 goto invalid_keyword;
6074 __Pyx_RaiseDoubleKeywordsError(function_name, **name);
6076 invalid_keyword_type:
6077 PyErr_Format(PyExc_TypeError,
6078 "%s() keywords must be strings", function_name);
6081 PyErr_Format(PyExc_TypeError,
6082 #if PY_MAJOR_VERSION < 3
6083 "%s() got an unexpected keyword argument '%s'",
6084 function_name, PyString_AsString(key));
6086 "%s() got an unexpected keyword argument '%U'",
6087 function_name, key);
6094 #------------------------------------------------------------------------------------
6096 traceback_utility_code = UtilityCode(
6098 static void __Pyx_AddTraceback(const char *funcname); /*proto*/
6101 #include "compile.h"
6102 #include "frameobject.h"
6103 #include "traceback.h"
6105 static void __Pyx_AddTraceback(const char *funcname) {
6106 PyObject *py_srcfile = 0;
6107 PyObject *py_funcname = 0;
6108 PyObject *py_globals = 0;
6109 PyCodeObject *py_code = 0;
6110 PyFrameObject *py_frame = 0;
6112 #if PY_MAJOR_VERSION < 3
6113 py_srcfile = PyString_FromString(%(FILENAME)s);
6115 py_srcfile = PyUnicode_FromString(%(FILENAME)s);
6117 if (!py_srcfile) goto bad;
6119 #if PY_MAJOR_VERSION < 3
6120 py_funcname = PyString_FromFormat( "%%s (%%s:%%d)", funcname, %(CFILENAME)s, %(CLINENO)s);
6122 py_funcname = PyUnicode_FromFormat( "%%s (%%s:%%d)", funcname, %(CFILENAME)s, %(CLINENO)s);
6126 #if PY_MAJOR_VERSION < 3
6127 py_funcname = PyString_FromString(funcname);
6129 py_funcname = PyUnicode_FromString(funcname);
6132 if (!py_funcname) goto bad;
6133 py_globals = PyModule_GetDict(%(GLOBALS)s);
6134 if (!py_globals) goto bad;
6135 py_code = PyCode_New(
6136 0, /*int argcount,*/
6137 #if PY_MAJOR_VERSION >= 3
6138 0, /*int kwonlyargcount,*/
6141 0, /*int stacksize,*/
6143 %(EMPTY_BYTES)s, /*PyObject *code,*/
6144 %(EMPTY_TUPLE)s, /*PyObject *consts,*/
6145 %(EMPTY_TUPLE)s, /*PyObject *names,*/
6146 %(EMPTY_TUPLE)s, /*PyObject *varnames,*/
6147 %(EMPTY_TUPLE)s, /*PyObject *freevars,*/
6148 %(EMPTY_TUPLE)s, /*PyObject *cellvars,*/
6149 py_srcfile, /*PyObject *filename,*/
6150 py_funcname, /*PyObject *name,*/
6151 %(LINENO)s, /*int firstlineno,*/
6152 %(EMPTY_BYTES)s /*PyObject *lnotab*/
6154 if (!py_code) goto bad;
6155 py_frame = PyFrame_New(
6156 PyThreadState_GET(), /*PyThreadState *tstate,*/
6157 py_code, /*PyCodeObject *code,*/
6158 py_globals, /*PyObject *globals,*/
6159 0 /*PyObject *locals*/
6161 if (!py_frame) goto bad;
6162 py_frame->f_lineno = %(LINENO)s;
6163 PyTraceBack_Here(py_frame);
6165 Py_XDECREF(py_srcfile);
6166 Py_XDECREF(py_funcname);
6167 Py_XDECREF(py_code);
6168 Py_XDECREF(py_frame);
6171 'FILENAME': Naming.filename_cname,
6172 'LINENO': Naming.lineno_cname,
6173 'CFILENAME': Naming.cfilenm_cname,
6174 'CLINENO': Naming.clineno_cname,
6175 'GLOBALS': Naming.module_cname,
6176 'EMPTY_TUPLE' : Naming.empty_tuple,
6177 'EMPTY_BYTES' : Naming.empty_bytes,
6180 #------------------------------------------------------------------------------------
6182 unraisable_exception_utility_code = UtilityCode(
6184 static void __Pyx_WriteUnraisable(const char *name); /*proto*/
6187 static void __Pyx_WriteUnraisable(const char *name) {
6188 PyObject *old_exc, *old_val, *old_tb;
6190 __Pyx_ErrFetch(&old_exc, &old_val, &old_tb);
6191 #if PY_MAJOR_VERSION < 3
6192 ctx = PyString_FromString(name);
6194 ctx = PyUnicode_FromString(name);
6196 __Pyx_ErrRestore(old_exc, old_val, old_tb);
6198 PyErr_WriteUnraisable(Py_None);
6200 PyErr_WriteUnraisable(ctx);
6205 requires=[restore_exception_utility_code])
6207 #------------------------------------------------------------------------------------
6209 set_vtable_utility_code = UtilityCode(
6211 static int __Pyx_SetVtable(PyObject *dict, void *vtable); /*proto*/
6214 static int __Pyx_SetVtable(PyObject *dict, void *vtable) {
6215 #if PY_VERSION_HEX >= 0x02070000 && !(PY_MAJOR_VERSION==3&&PY_MINOR_VERSION==0)
6216 PyObject *ob = PyCapsule_New(vtable, 0, 0);
6218 PyObject *ob = PyCObject_FromVoidPtr(vtable, 0);
6222 if (PyDict_SetItemString(dict, "__pyx_vtable__", ob) < 0)
6232 #------------------------------------------------------------------------------------
6234 get_vtable_utility_code = UtilityCode(
6236 static int __Pyx_GetVtable(PyObject *dict, void *vtabptr); /*proto*/
6239 static int __Pyx_GetVtable(PyObject *dict, void *vtabptr) {
6240 PyObject *ob = PyMapping_GetItemString(dict, (char *)"__pyx_vtable__");
6243 #if PY_VERSION_HEX >= 0x02070000 && !(PY_MAJOR_VERSION==3&&PY_MINOR_VERSION==0)
6244 *(void **)vtabptr = PyCapsule_GetPointer(ob, 0);
6246 *(void **)vtabptr = PyCObject_AsVoidPtr(ob);
6248 if (!*(void **)vtabptr)
6258 #------------------------------------------------------------------------------------
6260 init_string_tab_utility_code = UtilityCode(
6262 static int __Pyx_InitStrings(__Pyx_StringTabEntry *t); /*proto*/
6265 static int __Pyx_InitStrings(__Pyx_StringTabEntry *t) {
6267 #if PY_MAJOR_VERSION < 3
6268 if (t->is_unicode) {
6269 *t->p = PyUnicode_DecodeUTF8(t->s, t->n - 1, NULL);
6270 } else if (t->intern) {
6271 *t->p = PyString_InternFromString(t->s);
6273 *t->p = PyString_FromStringAndSize(t->s, t->n - 1);
6275 #else /* Python 3+ has unicode identifiers */
6276 if (t->is_unicode | t->is_str) {
6278 *t->p = PyUnicode_InternFromString(t->s);
6279 } else if (t->encoding) {
6280 *t->p = PyUnicode_Decode(t->s, t->n - 1, t->encoding, NULL);
6282 *t->p = PyUnicode_FromStringAndSize(t->s, t->n - 1);
6285 *t->p = PyBytes_FromStringAndSize(t->s, t->n - 1);
6296 #------------------------------------------------------------------------------------
6298 force_init_threads_utility_code = UtilityCode(
6300 #ifndef __PYX_FORCE_INIT_THREADS
6301 #if PY_VERSION_HEX < 0x02040200
6302 #define __PYX_FORCE_INIT_THREADS 1
6304 #define __PYX_FORCE_INIT_THREADS 0
6309 #------------------------------------------------------------------------------------
6311 # Note that cPython ignores PyTrace_EXCEPTION,
6312 # but maybe some other profilers don't.
6314 profile_utility_code = UtilityCode(proto="""
6315 #ifndef CYTHON_PROFILE
6316 #define CYTHON_PROFILE 1
6319 #ifndef CYTHON_PROFILE_REUSE_FRAME
6320 #define CYTHON_PROFILE_REUSE_FRAME 0
6325 #include "compile.h"
6326 #include "frameobject.h"
6327 #include "traceback.h"
6329 #if CYTHON_PROFILE_REUSE_FRAME
6330 #define CYTHON_FRAME_MODIFIER static
6331 #define CYTHON_FRAME_DEL
6333 #define CYTHON_FRAME_MODIFIER
6334 #define CYTHON_FRAME_DEL Py_DECREF(%(FRAME)s)
6337 #define __Pyx_TraceDeclarations \\
6338 static PyCodeObject *%(FRAME_CODE)s = NULL; \\
6339 CYTHON_FRAME_MODIFIER PyFrameObject *%(FRAME)s = NULL; \\
6340 int __Pyx_use_tracing = 0;
6342 #define __Pyx_TraceCall(funcname, srcfile, firstlineno) \\
6343 if (unlikely(PyThreadState_GET()->use_tracing && PyThreadState_GET()->c_profilefunc)) { \\
6344 __Pyx_use_tracing = __Pyx_TraceSetupAndCall(&%(FRAME_CODE)s, &%(FRAME)s, funcname, srcfile, firstlineno); \\
6347 #define __Pyx_TraceException() \\
6348 if (unlikely(__Pyx_use_tracing( && PyThreadState_GET()->use_tracing && PyThreadState_GET()->c_profilefunc) { \\
6349 PyObject *exc_info = __Pyx_GetExceptionTuple(); \\
6351 PyThreadState_GET()->c_profilefunc( \\
6352 PyThreadState_GET()->c_profileobj, %(FRAME)s, PyTrace_EXCEPTION, exc_info); \\
6353 Py_DECREF(exc_info); \\
6357 #define __Pyx_TraceReturn(result) \\
6358 if (unlikely(__Pyx_use_tracing) && PyThreadState_GET()->use_tracing && PyThreadState_GET()->c_profilefunc) { \\
6359 PyThreadState_GET()->c_profilefunc( \\
6360 PyThreadState_GET()->c_profileobj, %(FRAME)s, PyTrace_RETURN, (PyObject*)result); \\
6361 CYTHON_FRAME_DEL; \\
6364 static PyCodeObject *__Pyx_createFrameCodeObject(const char *funcname, const char *srcfile, int firstlineno); /*proto*/
6365 static int __Pyx_TraceSetupAndCall(PyCodeObject** code, PyFrameObject** frame, const char *funcname, const char *srcfile, int firstlineno); /*proto*/
6369 #define __Pyx_TraceDeclarations
6370 #define __Pyx_TraceCall(funcname, srcfile, firstlineno)
6371 #define __Pyx_TraceException()
6372 #define __Pyx_TraceReturn(result)
6374 #endif /* CYTHON_PROFILE */
6377 "FRAME": Naming.frame_cname,
6378 "FRAME_CODE": Naming.frame_code_cname,
6384 static int __Pyx_TraceSetupAndCall(PyCodeObject** code,
6385 PyFrameObject** frame,
6386 const char *funcname,
6387 const char *srcfile,
6389 if (*frame == NULL || !CYTHON_PROFILE_REUSE_FRAME) {
6390 if (*code == NULL) {
6391 *code = __Pyx_createFrameCodeObject(funcname, srcfile, firstlineno);
6392 if (*code == NULL) return 0;
6394 *frame = PyFrame_New(
6395 PyThreadState_GET(), /*PyThreadState *tstate*/
6396 *code, /*PyCodeObject *code*/
6397 PyModule_GetDict(%(MODULE)s), /*PyObject *globals*/
6398 0 /*PyObject *locals*/
6400 if (*frame == NULL) return 0;
6403 (*frame)->f_tstate = PyThreadState_GET();
6405 return PyThreadState_GET()->c_profilefunc(PyThreadState_GET()->c_profileobj, *frame, PyTrace_CALL, NULL) == 0;
6408 static PyCodeObject *__Pyx_createFrameCodeObject(const char *funcname, const char *srcfile, int firstlineno) {
6409 PyObject *py_srcfile = 0;
6410 PyObject *py_funcname = 0;
6411 PyCodeObject *py_code = 0;
6413 #if PY_MAJOR_VERSION < 3
6414 py_funcname = PyString_FromString(funcname);
6415 py_srcfile = PyString_FromString(srcfile);
6417 py_funcname = PyUnicode_FromString(funcname);
6418 py_srcfile = PyUnicode_FromString(srcfile);
6420 if (!py_funcname | !py_srcfile) goto bad;
6422 py_code = PyCode_New(
6423 0, /*int argcount,*/
6424 #if PY_MAJOR_VERSION >= 3
6425 0, /*int kwonlyargcount,*/
6428 0, /*int stacksize,*/
6430 %(EMPTY_BYTES)s, /*PyObject *code,*/
6431 %(EMPTY_TUPLE)s, /*PyObject *consts,*/
6432 %(EMPTY_TUPLE)s, /*PyObject *names,*/
6433 %(EMPTY_TUPLE)s, /*PyObject *varnames,*/
6434 %(EMPTY_TUPLE)s, /*PyObject *freevars,*/
6435 %(EMPTY_TUPLE)s, /*PyObject *cellvars,*/
6436 py_srcfile, /*PyObject *filename,*/
6437 py_funcname, /*PyObject *name,*/
6438 firstlineno, /*int firstlineno,*/
6439 %(EMPTY_BYTES)s /*PyObject *lnotab*/
6443 Py_XDECREF(py_srcfile);
6444 Py_XDECREF(py_funcname);
6449 #endif /* CYTHON_PROFILE */
6451 'EMPTY_TUPLE' : Naming.empty_tuple,
6452 'EMPTY_BYTES' : Naming.empty_bytes,
6453 "MODULE": Naming.module_cname,