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)
792 return PyrexTypes.error_type
794 class CNestedBaseTypeNode(CBaseTypeNode):
795 # For C++ classes that live inside other C++ classes.
798 # base_type CBaseTypeNode
800 child_attrs = ['base_type']
802 def analyse(self, env, could_be_name = None):
803 base_type = self.base_type.analyse(env)
804 if base_type is PyrexTypes.error_type:
805 return PyrexTypes.error_type
806 if not base_type.is_cpp_class:
807 error(self.pos, "'%s' is not a valid type scope" % base_type)
808 return PyrexTypes.error_type
809 type_entry = base_type.scope.lookup_here(self.name)
810 if not type_entry or not type_entry.is_type:
811 error(self.pos, "'%s.%s' is not a type identifier" % (base_type, self.name))
812 return PyrexTypes.error_type
813 return type_entry.type
815 class TemplatedTypeNode(CBaseTypeNode):
817 # positional_args [ExprNode] List of positional arguments
818 # keyword_args DictNode Keyword arguments
819 # base_type_node CBaseTypeNode
822 # type PyrexTypes.BufferType or PyrexTypes.CppClassType ...containing the right options
825 child_attrs = ["base_type_node", "positional_args",
826 "keyword_args", "dtype_node"]
832 def analyse(self, env, could_be_name = False, base_type = None):
833 if base_type is None:
834 base_type = self.base_type_node.analyse(env)
835 if base_type.is_error: return base_type
837 if base_type.is_cpp_class:
839 if self.keyword_args and self.keyword_args.key_value_pairs:
840 error(self.pos, "c++ templates cannot take keyword arguments");
841 self.type = PyrexTypes.error_type
844 for template_node in self.positional_args:
845 type = template_node.analyse_as_type(env)
847 error(template_node.pos, "unknown type in template argument")
849 template_types.append(type)
850 self.type = base_type.specialize_here(self.pos, template_types)
852 elif base_type.is_pyobject:
856 options = Buffer.analyse_buffer_options(
859 self.positional_args,
861 base_type.buffer_defaults)
863 if sys.version_info[0] < 3:
864 # Py 2.x enforces byte strings as keyword arguments ...
865 options = dict([ (name.encode('ASCII'), value)
866 for name, value in options.items() ])
868 self.type = PyrexTypes.BufferType(base_type, **options)
872 empty_declarator = CNameDeclaratorNode(self.pos, name="", cname=None)
873 if len(self.positional_args) > 1 or self.keyword_args.key_value_pairs:
874 error(self.pos, "invalid array declaration")
875 self.type = PyrexTypes.error_type
877 # It would be nice to merge this class with CArrayDeclaratorNode,
878 # but arrays are part of the declaration, not the type...
879 if not self.positional_args:
882 dimension = self.positional_args[0]
883 self.array_declarator = CArrayDeclaratorNode(self.pos,
884 base = empty_declarator,
885 dimension = dimension)
886 self.type = self.array_declarator.analyse(base_type, env)[1]
890 class CComplexBaseTypeNode(CBaseTypeNode):
891 # base_type CBaseTypeNode
892 # declarator CDeclaratorNode
894 child_attrs = ["base_type", "declarator"]
896 def analyse(self, env, could_be_name = False):
897 base = self.base_type.analyse(env, could_be_name)
898 _, type = self.declarator.analyse(base, env)
902 class CVarDefNode(StatNode):
903 # C variable definition or forward/extern function declaration.
905 # visibility 'private' or 'public' or 'extern'
906 # base_type CBaseTypeNode
907 # declarators [CDeclaratorNode]
911 # decorators [cython.locals(...)] or None
912 # directive_locals { string : NameNode } locals defined by cython.locals(...)
914 child_attrs = ["base_type", "declarators"]
917 directive_locals = {}
919 def analyse_declarations(self, env, dest_scope = None):
922 self.dest_scope = dest_scope
923 base_type = self.base_type.analyse(env)
925 # If the field is an external typedef, we cannot be sure about the type,
926 # so do conversion ourself rather than rely on the CPython mechanism (through
927 # a property; made in AnalyseDeclarationsTransform).
928 if (dest_scope.is_c_class_scope
929 and self.visibility in ('public', 'readonly')):
932 need_property = False
933 visibility = self.visibility
935 for declarator in self.declarators:
936 name_declarator, type = declarator.analyse(base_type, env)
937 if not type.is_complete():
938 if not (self.visibility == 'extern' and type.is_array):
939 error(declarator.pos,
940 "Variable type '%s' is incomplete" % type)
941 if self.visibility == 'extern' and type.is_pyobject:
942 error(declarator.pos,
943 "Python object cannot be declared extern")
944 name = name_declarator.name
945 cname = name_declarator.cname
947 error(declarator.pos, "Missing name in declaration.")
949 if type.is_cfunction:
950 entry = dest_scope.declare_cfunction(name, type, declarator.pos,
951 cname = cname, visibility = self.visibility, in_pxd = self.in_pxd,
953 if entry is not None:
954 entry.directive_locals = self.directive_locals
956 if self.directive_locals:
957 error(self.pos, "Decorators can only be followed by functions")
958 if self.in_pxd and self.visibility != 'extern':
960 "Only 'extern' C variable declaration allowed in .pxd file")
961 entry = dest_scope.declare_var(name, type, declarator.pos,
962 cname = cname, visibility = visibility, is_cdef = 1)
963 entry.needs_property = need_property
966 class CStructOrUnionDefNode(StatNode):
968 # cname string or None
969 # kind "struct" or "union"
970 # typedef_flag boolean
971 # visibility "public" or "private"
973 # attributes [CVarDefNode] or None
977 child_attrs = ["attributes"]
979 def analyse_declarations(self, env):
981 if self.visibility == 'extern' and self.packed:
982 error(self.pos, "Cannot declare extern struct as 'packed'")
983 if self.attributes is not None:
984 scope = StructOrUnionScope(self.name)
985 self.entry = env.declare_struct_or_union(
986 self.name, self.kind, scope, self.typedef_flag, self.pos,
987 self.cname, visibility = self.visibility, packed = self.packed)
988 if self.attributes is not None:
989 if self.in_pxd and not env.in_cinclude:
990 self.entry.defined_in_pxd = 1
991 for attr in self.attributes:
992 attr.analyse_declarations(env, scope)
993 if self.visibility != 'extern':
994 need_typedef_indirection = False
995 for attr in scope.var_entries:
998 type = type.base_type
999 if type == self.entry.type:
1000 error(attr.pos, "Struct cannot contain itself as a member.")
1001 if self.typedef_flag:
1003 type = type.base_type
1004 if type == self.entry.type:
1005 need_typedef_indirection = True
1006 if need_typedef_indirection:
1007 # C can't handle typedef structs that refer to themselves.
1008 struct_entry = self.entry
1009 self.entry = env.declare_typedef(
1010 self.name, struct_entry.type, self.pos,
1011 cname = self.cname, visibility='ignore')
1012 struct_entry.type.typedef_flag = False
1013 # FIXME: this might be considered a hack ;-)
1014 struct_entry.cname = struct_entry.type.cname = \
1015 '_' + self.entry.type.typedef_cname
1017 def analyse_expressions(self, env):
1020 def generate_execution_code(self, code):
1024 class CppClassNode(CStructOrUnionDefNode):
1027 # cname string or None
1028 # visibility "extern"
1030 # attributes [CVarDefNode] or None
1032 # base_classes [string]
1033 # templates [string] or None
1035 def analyse_declarations(self, env):
1037 if self.attributes is not None:
1038 scope = CppClassScope(self.name, env)
1039 base_class_types = []
1040 for base_class_name in self.base_classes:
1041 base_class_entry = env.lookup(base_class_name)
1042 if base_class_entry is None:
1043 error(self.pos, "'%s' not found" % base_class_name)
1044 elif not base_class_entry.is_type or not base_class_entry.type.is_cpp_class:
1045 error(self.pos, "'%s' is not a cpp class type" % base_class_name)
1047 base_class_types.append(base_class_entry.type)
1048 if self.templates is None:
1049 template_types = None
1051 template_types = [PyrexTypes.TemplatePlaceholderType(template_name) for template_name in self.templates]
1052 self.entry = env.declare_cpp_class(
1053 self.name, scope, self.pos,
1054 self.cname, base_class_types, visibility = self.visibility, templates = template_types)
1055 self.entry.is_cpp_class = 1
1056 if self.attributes is not None:
1057 if self.in_pxd and not env.in_cinclude:
1058 self.entry.defined_in_pxd = 1
1059 for attr in self.attributes:
1060 attr.analyse_declarations(scope)
1062 class CEnumDefNode(StatNode):
1063 # name string or None
1064 # cname string or None
1065 # items [CEnumDefItemNode]
1066 # typedef_flag boolean
1067 # visibility "public" or "private"
1071 child_attrs = ["items"]
1073 def analyse_declarations(self, env):
1074 self.entry = env.declare_enum(self.name, self.pos,
1075 cname = self.cname, typedef_flag = self.typedef_flag,
1076 visibility = self.visibility)
1077 if self.items is not None:
1078 if self.in_pxd and not env.in_cinclude:
1079 self.entry.defined_in_pxd = 1
1080 for item in self.items:
1081 item.analyse_declarations(env, self.entry)
1083 def analyse_expressions(self, env):
1086 def generate_execution_code(self, code):
1087 if self.visibility == 'public':
1088 temp = code.funcstate.allocate_temp(PyrexTypes.py_object_type, manage_ref=True)
1089 for item in self.entry.enum_values:
1090 code.putln("%s = PyInt_FromLong(%s); %s" % (
1093 code.error_goto_if_null(temp, item.pos)))
1094 code.put_gotref(temp)
1095 code.putln('if (__Pyx_SetAttrString(%s, "%s", %s) < 0) %s' % (
1096 Naming.module_cname,
1099 code.error_goto(item.pos)))
1100 code.put_decref_clear(temp, PyrexTypes.py_object_type)
1101 code.funcstate.release_temp(temp)
1104 class CEnumDefItemNode(StatNode):
1106 # cname string or None
1107 # value ExprNode or None
1109 child_attrs = ["value"]
1111 def analyse_declarations(self, env, enum_entry):
1113 self.value.analyse_const_expression(env)
1114 if not self.value.type.is_int:
1115 self.value = self.value.coerce_to(PyrexTypes.c_int_type, env)
1116 self.value.analyse_const_expression(env)
1117 entry = env.declare_const(self.name, enum_entry.type,
1118 self.value, self.pos, cname = self.cname,
1119 visibility = enum_entry.visibility)
1120 enum_entry.enum_values.append(entry)
1123 class CTypeDefNode(StatNode):
1124 # base_type CBaseTypeNode
1125 # declarator CDeclaratorNode
1126 # visibility "public" or "private"
1129 child_attrs = ["base_type", "declarator"]
1131 def analyse_declarations(self, env):
1132 base = self.base_type.analyse(env)
1133 name_declarator, type = self.declarator.analyse(base, env)
1134 name = name_declarator.name
1135 cname = name_declarator.cname
1136 entry = env.declare_typedef(name, type, self.pos,
1137 cname = cname, visibility = self.visibility)
1138 if self.in_pxd and not env.in_cinclude:
1139 entry.defined_in_pxd = 1
1141 def analyse_expressions(self, env):
1143 def generate_execution_code(self, code):
1147 class FuncDefNode(StatNode, BlockNode):
1148 # Base class for function definition nodes.
1150 # return_type PyrexType
1151 # #filename string C name of filename string const
1152 # entry Symtab.Entry
1153 # needs_closure boolean Whether or not this function has inner functions/classes/yield
1154 # needs_outer_scope boolean Whether or not this function requires outer scope
1155 # directive_locals { string : NameNode } locals defined by cython.locals(...)
1159 needs_closure = False
1160 needs_outer_scope = False
1163 def analyse_default_values(self, env):
1164 genv = env.global_scope()
1166 for arg in self.args:
1170 arg.default.analyse_types(env)
1171 arg.default = arg.default.coerce_to(arg.type, genv)
1174 "This argument cannot have a default value")
1179 error(arg.pos, "Non-default argument following default argument")
1181 def need_gil_acquisition(self, lenv):
1184 def create_local_scope(self, env):
1186 while genv.is_py_class_scope or genv.is_c_class_scope:
1187 genv = genv.outer_scope
1188 if self.needs_closure:
1189 lenv = ClosureScope(name=self.entry.name,
1191 scope_name=self.entry.cname)
1193 lenv = LocalScope(name=self.entry.name,
1196 lenv.return_type = self.return_type
1197 type = self.entry.type
1198 if type.is_cfunction:
1199 lenv.nogil = type.nogil and not type.with_gil
1200 self.local_scope = lenv
1201 lenv.directives = env.directives
1204 def generate_function_definitions(self, env, code):
1207 lenv = self.local_scope
1208 if lenv.is_closure_scope and not lenv.is_passthrough:
1209 outer_scope_cname = "%s->%s" % (Naming.cur_scope_cname,
1210 Naming.outer_scope_cname)
1212 outer_scope_cname = Naming.outer_scope_cname
1213 lenv.mangle_closure_cnames(outer_scope_cname)
1214 # Generate closure function definitions
1215 self.body.generate_function_definitions(lenv, code)
1216 # generate lambda function definitions
1217 self.generate_lambda_definitions(lenv, code)
1219 is_getbuffer_slot = (self.entry.name == "__getbuffer__" and
1220 self.entry.scope.is_c_class_scope)
1221 is_releasebuffer_slot = (self.entry.name == "__releasebuffer__" and
1222 self.entry.scope.is_c_class_scope)
1223 is_buffer_slot = is_getbuffer_slot or is_releasebuffer_slot
1225 if 'cython_unused' not in self.modifiers:
1226 self.modifiers = self.modifiers + ['cython_unused']
1228 preprocessor_guard = None
1229 if self.entry.is_special and not is_buffer_slot:
1230 slot = TypeSlots.method_name_to_slot.get(self.entry.name)
1232 preprocessor_guard = slot.preprocessor_guard_code()
1233 if (self.entry.name == '__long__' and
1234 not self.entry.scope.lookup_here('__int__')):
1235 preprocessor_guard = None
1237 profile = code.globalstate.directives['profile']
1240 error(self.pos, "Cannot profile nogil function.")
1241 code.globalstate.use_utility_code(profile_utility_code)
1243 # Generate C code for header and body of function
1244 code.enter_cfunc_scope()
1245 code.return_from_error_cleanup_label = code.new_label()
1247 # ----- Top-level constants used by this function
1248 code.mark_pos(self.pos)
1249 self.generate_cached_builtins_decls(lenv, code)
1250 # ----- Function header
1253 if preprocessor_guard:
1254 code.putln(preprocessor_guard)
1256 with_pymethdef = self.needs_assignment_synthesis(env, code)
1258 self.py_func.generate_function_header(code,
1259 with_pymethdef = with_pymethdef,
1261 self.generate_function_header(code,
1262 with_pymethdef = with_pymethdef)
1263 # ----- Local variable declarations
1264 # Find function scope
1266 while cenv.is_py_class_scope or cenv.is_c_class_scope:
1267 cenv = cenv.outer_scope
1268 if self.needs_closure:
1269 code.put(lenv.scope_class.type.declaration_code(Naming.cur_scope_cname))
1271 elif self.needs_outer_scope:
1272 if lenv.is_passthrough:
1273 code.put(lenv.scope_class.type.declaration_code(Naming.cur_scope_cname))
1275 code.put(cenv.scope_class.type.declaration_code(Naming.outer_scope_cname))
1277 self.generate_argument_declarations(lenv, code)
1278 for entry in lenv.var_entries:
1279 if not entry.in_closure:
1280 code.put_var_declaration(entry)
1282 if not self.return_type.is_void:
1283 if self.return_type.is_pyobject:
1287 (self.return_type.declaration_code(Naming.retval_cname),
1289 tempvardecl_code = code.insertion_point()
1290 self.generate_keyword_list(code)
1292 code.put_trace_declarations()
1293 # ----- Extern library function declarations
1294 lenv.generate_library_function_declarations(code)
1295 # ----- GIL acquisition
1296 acquire_gil = self.acquire_gil
1298 env.use_utility_code(force_init_threads_utility_code)
1299 code.putln("#ifdef WITH_THREAD")
1300 code.putln("PyGILState_STATE _save = PyGILState_Ensure();")
1301 code.putln("#endif")
1302 # ----- set up refnanny
1304 code.put_setup_refcount_context(self.entry.name)
1305 # ----- Automatic lead-ins for certain special functions
1306 if is_getbuffer_slot:
1307 self.getbuffer_init(code)
1308 # ----- Create closure scope object
1309 if self.needs_closure:
1310 code.putln("%s = (%s)%s->tp_new(%s, %s, NULL);" % (
1311 Naming.cur_scope_cname,
1312 lenv.scope_class.type.declaration_code(''),
1313 lenv.scope_class.type.typeptr_cname,
1314 lenv.scope_class.type.typeptr_cname,
1315 Naming.empty_tuple))
1316 code.putln("if (unlikely(!%s)) {" % Naming.cur_scope_cname)
1317 if is_getbuffer_slot:
1318 self.getbuffer_error_cleanup(code)
1320 code.put_finish_refcount_context()
1321 # FIXME: what if the error return value is a Python value?
1322 code.putln("return %s;" % self.error_value())
1324 code.put_gotref(Naming.cur_scope_cname)
1325 # Note that it is unsafe to decref the scope at this point.
1326 if self.needs_outer_scope:
1327 code.putln("%s = (%s)%s;" % (
1329 cenv.scope_class.type.declaration_code(''),
1331 if lenv.is_passthrough:
1332 code.putln("%s = %s;" % (Naming.cur_scope_cname, outer_scope_cname));
1333 elif self.needs_closure:
1334 # inner closures own a reference to their outer parent
1335 code.put_incref(outer_scope_cname, cenv.scope_class.type)
1336 code.put_giveref(outer_scope_cname)
1337 # ----- Trace function call
1339 # this looks a bit late, but if we don't get here due to a
1340 # fatal error before hand, it's not really worth tracing
1341 code.put_trace_call(self.entry.name, self.pos)
1342 # ----- Fetch arguments
1343 self.generate_argument_parsing_code(env, code)
1344 # If an argument is assigned to in the body, we must
1345 # incref it to properly keep track of refcounts.
1346 for entry in lenv.arg_entries:
1347 if entry.type.is_pyobject:
1348 if entry.assignments and not entry.in_closure:
1349 code.put_var_incref(entry)
1350 # ----- Initialise local variables
1351 for entry in lenv.var_entries:
1352 if entry.type.is_pyobject and entry.init_to_none and entry.used:
1353 code.put_init_var_to_py_none(entry)
1354 # ----- Initialise local buffer auxiliary variables
1355 for entry in lenv.var_entries + lenv.arg_entries:
1356 if entry.type.is_buffer and entry.buffer_aux.buffer_info_var.used:
1357 code.putln("%s.buf = NULL;" %
1358 entry.buffer_aux.buffer_info_var.cname)
1359 # ----- Check and convert arguments
1360 self.generate_argument_type_tests(code)
1361 # ----- Acquire buffer arguments
1362 for entry in lenv.arg_entries:
1363 if entry.type.is_buffer:
1364 Buffer.put_acquire_arg_buffer(entry, code, self.pos)
1366 # -------------------------
1367 # ----- Function body -----
1368 # -------------------------
1369 self.body.generate_execution_code(code)
1371 # ----- Default return value
1373 if self.return_type.is_pyobject:
1374 #if self.return_type.is_extension_type:
1375 # lhs = "(PyObject *)%s" % Naming.retval_cname
1377 lhs = Naming.retval_cname
1378 code.put_init_to_py_none(lhs, self.return_type)
1380 val = self.return_type.default_value
1382 code.putln("%s = %s;" % (Naming.retval_cname, val))
1383 # ----- Error cleanup
1384 if code.error_label in code.labels_used:
1385 code.put_goto(code.return_label)
1386 code.put_label(code.error_label)
1387 for cname, type in code.funcstate.all_managed_temps():
1388 code.put_xdecref(cname, type)
1390 # Clean up buffers -- this calls a Python function
1391 # so need to save and restore error state
1392 buffers_present = len(lenv.buffer_entries) > 0
1394 code.globalstate.use_utility_code(restore_exception_utility_code)
1395 code.putln("{ PyObject *__pyx_type, *__pyx_value, *__pyx_tb;")
1396 code.putln("__Pyx_ErrFetch(&__pyx_type, &__pyx_value, &__pyx_tb);")
1397 for entry in lenv.buffer_entries:
1398 Buffer.put_release_buffer_code(code, entry)
1399 #code.putln("%s = 0;" % entry.cname)
1400 code.putln("__Pyx_ErrRestore(__pyx_type, __pyx_value, __pyx_tb);}")
1402 err_val = self.error_value()
1403 exc_check = self.caller_will_check_exceptions()
1404 if err_val is not None or exc_check:
1405 # TODO: Fix exception tracing (though currently unused by cProfile).
1406 # code.globalstate.use_utility_code(get_exception_tuple_utility_code)
1407 # code.put_trace_exception()
1408 code.putln('__Pyx_AddTraceback("%s");' % self.entry.qualified_name)
1410 warning(self.entry.pos, "Unraisable exception in function '%s'." \
1411 % self.entry.qualified_name, 0)
1413 '__Pyx_WriteUnraisable("%s");' %
1414 self.entry.qualified_name)
1415 env.use_utility_code(unraisable_exception_utility_code)
1416 env.use_utility_code(restore_exception_utility_code)
1417 default_retval = self.return_type.default_value
1418 if err_val is None and default_retval:
1419 err_val = default_retval
1420 if err_val is not None:
1421 code.putln("%s = %s;" % (Naming.retval_cname, err_val))
1423 if is_getbuffer_slot:
1424 self.getbuffer_error_cleanup(code)
1426 # If we are using the non-error cleanup section we should
1427 # jump past it if we have an error. The if-test below determine
1428 # whether this section is used.
1429 if buffers_present or is_getbuffer_slot:
1430 code.put_goto(code.return_from_error_cleanup_label)
1433 # ----- Non-error return cleanup
1434 code.put_label(code.return_label)
1435 for entry in lenv.buffer_entries:
1437 Buffer.put_release_buffer_code(code, entry)
1438 if is_getbuffer_slot:
1439 self.getbuffer_normal_cleanup(code)
1440 # ----- Return cleanup for both error and no-error return
1441 code.put_label(code.return_from_error_cleanup_label)
1442 if not Options.init_local_none:
1443 for entry in lenv.var_entries:
1444 if lenv.control_flow.get_state((entry.name, 'initialized')) is not True:
1445 entry.xdecref_cleanup = 1
1447 for entry in lenv.var_entries:
1448 if entry.type.is_pyobject:
1449 if entry.used and not entry.in_closure:
1450 code.put_var_decref(entry)
1451 elif entry.in_closure and self.needs_closure:
1452 code.put_giveref(entry.cname)
1453 # Decref any increfed args
1454 for entry in lenv.arg_entries:
1455 if entry.type.is_pyobject:
1456 if entry.in_closure:
1457 code.put_var_giveref(entry)
1458 elif entry.assignments:
1459 code.put_var_decref(entry)
1460 if self.needs_closure:
1461 code.put_decref(Naming.cur_scope_cname, lenv.scope_class.type)
1464 # This code is duplicated in ModuleNode.generate_module_init_func
1466 default_retval = self.return_type.default_value
1467 err_val = self.error_value()
1468 if err_val is None and default_retval:
1469 err_val = default_retval
1470 if self.return_type.is_pyobject:
1471 code.put_xgiveref(self.return_type.as_pyobject(Naming.retval_cname))
1473 if self.entry.is_special and self.entry.name == "__hash__":
1474 # Returning -1 for __hash__ is supposed to signal an error
1475 # We do as Python instances and coerce -1 into -2.
1476 code.putln("if (unlikely(%s == -1) && !PyErr_Occurred()) %s = -2;" % (
1477 Naming.retval_cname, Naming.retval_cname))
1480 if self.return_type.is_pyobject:
1481 code.put_trace_return(Naming.retval_cname)
1483 code.put_trace_return("Py_None")
1485 code.put_finish_refcount_context()
1488 code.putln("#ifdef WITH_THREAD")
1489 code.putln("PyGILState_Release(_save);")
1490 code.putln("#endif")
1492 if not self.return_type.is_void:
1493 code.putln("return %s;" % Naming.retval_cname)
1497 if preprocessor_guard:
1498 code.putln("#endif /*!(%s)*/" % preprocessor_guard)
1500 # ----- Go back and insert temp variable declarations
1501 tempvardecl_code.put_temp_declarations(code.funcstate)
1502 # ----- Python version
1503 code.exit_cfunc_scope()
1505 self.py_func.generate_function_definitions(env, code)
1506 self.generate_wrapper_functions(code)
1508 def declare_argument(self, env, arg):
1509 if arg.type.is_void:
1510 error(arg.pos, "Invalid use of 'void'")
1511 elif not arg.type.is_complete() and not arg.type.is_array:
1513 "Argument type '%s' is incomplete" % arg.type)
1514 return env.declare_arg(arg.name, arg.type, arg.pos)
1516 def generate_arg_type_test(self, arg, code):
1517 # Generate type test for one argument.
1518 if arg.type.typeobj_is_available():
1519 code.globalstate.use_utility_code(arg_type_test_utility_code)
1520 typeptr_cname = arg.type.typeptr_cname
1521 arg_code = "((PyObject *)%s)" % arg.entry.cname
1523 'if (unlikely(!__Pyx_ArgTypeTest(%s, %s, %d, "%s", %s))) %s' % (
1528 arg.type.is_builtin_type,
1529 code.error_goto(arg.pos)))
1531 error(arg.pos, "Cannot test type of extern C class "
1532 "without type object name specification")
1534 def generate_arg_none_check(self, arg, code):
1535 # Generate None check for one argument.
1536 code.globalstate.use_utility_code(arg_type_test_utility_code)
1537 code.putln('if (unlikely(((PyObject *)%s) == Py_None)) {' % arg.entry.cname)
1538 code.putln('''PyErr_Format(PyExc_TypeError, "Argument '%s' must not be None"); %s''' % (
1540 code.error_goto(arg.pos)))
1543 def generate_wrapper_functions(self, code):
1546 def generate_execution_code(self, code):
1547 # Evaluate and store argument default values
1548 for arg in self.args:
1549 default = arg.default
1551 if not default.is_literal:
1552 default.generate_evaluation_code(code)
1553 default.make_owned_reference(code)
1554 result = default.result_as(arg.type)
1557 arg.calculate_default_value_code(code),
1559 if arg.type.is_pyobject:
1560 code.put_giveref(default.result())
1561 default.generate_post_assignment_code(code)
1562 default.free_temps(code)
1563 # For Python class methods, create and store function object
1565 self.assmt.generate_execution_code(code)
1568 # Special code for the __getbuffer__ function
1570 def getbuffer_init(self, code):
1571 info = self.local_scope.arg_entries[1].cname
1572 # Python 3.0 betas have a bug in memoryview which makes it call
1573 # getbuffer with a NULL parameter. For now we work around this;
1574 # the following line should be removed when this bug is fixed.
1575 code.putln("if (%s == NULL) return 0;" % info)
1576 code.putln("%s->obj = Py_None; __Pyx_INCREF(Py_None);" % info)
1577 code.put_giveref("%s->obj" % info) # Do not refnanny object within structs
1579 def getbuffer_error_cleanup(self, code):
1580 info = self.local_scope.arg_entries[1].cname
1581 code.put_gotref("%s->obj" % info)
1582 code.putln("__Pyx_DECREF(%s->obj); %s->obj = NULL;" %
1585 def getbuffer_normal_cleanup(self, code):
1586 info = self.local_scope.arg_entries[1].cname
1587 code.putln("if (%s->obj == Py_None) {" % info)
1588 code.put_gotref("Py_None")
1589 code.putln("__Pyx_DECREF(Py_None); %s->obj = NULL;" % info)
1592 class CFuncDefNode(FuncDefNode):
1593 # C function definition.
1595 # modifiers ['inline']
1596 # visibility 'private' or 'public' or 'extern'
1597 # base_type CBaseTypeNode
1598 # declarator CDeclaratorNode
1601 # decorators [DecoratorNode] list of decorators
1603 # with_gil boolean Acquire GIL around body
1605 # py_func wrapper for calling from Python
1606 # overridable whether or not this is a cpdef function
1607 # inline_in_pxd whether this is an inline function in a pxd file
1609 child_attrs = ["base_type", "declarator", "body", "py_func"]
1611 inline_in_pxd = False
1613 directive_locals = {}
1615 def unqualified_name(self):
1616 return self.entry.name
1618 def analyse_declarations(self, env):
1619 self.directive_locals.update(env.directives['locals'])
1620 base_type = self.base_type.analyse(env)
1621 # The 2 here is because we need both function and argument names.
1622 name_declarator, type = self.declarator.analyse(base_type, env, nonempty = 2 * (self.body is not None))
1623 if not type.is_cfunction:
1625 "Suite attached to non-function declaration")
1626 # Remember the actual type according to the function header
1627 # written here, because the type in the symbol table entry
1628 # may be different if we're overriding a C method inherited
1629 # from the base type of an extension type.
1631 type.is_overridable = self.overridable
1632 declarator = self.declarator
1633 while not hasattr(declarator, 'args'):
1634 declarator = declarator.base
1635 self.args = declarator.args
1636 for formal_arg, type_arg in zip(self.args, type.args):
1637 formal_arg.type = type_arg.type
1638 formal_arg.name = type_arg.name
1639 formal_arg.cname = type_arg.cname
1640 name = name_declarator.name
1641 cname = name_declarator.cname
1642 self.entry = env.declare_cfunction(
1643 name, type, self.pos,
1644 cname = cname, visibility = self.visibility,
1645 defining = self.body is not None,
1646 api = self.api, modifiers = self.modifiers)
1647 self.entry.inline_func_in_pxd = self.inline_in_pxd
1648 self.return_type = type.return_type
1650 if self.overridable and not env.is_module_scope:
1651 if len(self.args) < 1 or not self.args[0].type.is_pyobject:
1652 # An error will be produced in the cdef function
1653 self.overridable = False
1655 if self.overridable:
1657 py_func_body = self.call_self_node(is_module_scope = env.is_module_scope)
1658 self.py_func = DefNode(pos = self.pos,
1659 name = self.entry.name,
1662 starstar_arg = None,
1664 body = py_func_body,
1666 self.py_func.is_module_scope = env.is_module_scope
1667 self.py_func.analyse_declarations(env)
1668 self.entry.as_variable = self.py_func.entry
1669 # Reset scope entry the above cfunction
1670 env.entries[name] = self.entry
1671 if not env.is_module_scope or Options.lookup_module_cpdef:
1672 self.override = OverrideCheckNode(self.pos, py_func = self.py_func)
1673 self.body = StatListNode(self.pos, stats=[self.override, self.body])
1674 self.create_local_scope(env)
1676 def call_self_node(self, omit_optional_args=0, is_module_scope=0):
1678 args = self.type.args
1679 if omit_optional_args:
1680 args = args[:len(args) - self.type.optional_arg_count]
1681 arg_names = [arg.name for arg in args]
1683 cfunc = ExprNodes.NameNode(self.pos, name=self.entry.name)
1685 self_arg = ExprNodes.NameNode(self.pos, name=arg_names[0])
1686 cfunc = ExprNodes.AttributeNode(self.pos, obj=self_arg, attribute=self.entry.name)
1687 skip_dispatch = not is_module_scope or Options.lookup_module_cpdef
1688 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)
1689 return ReturnStatNode(pos=self.pos, return_type=PyrexTypes.py_object_type, value=c_call)
1691 def declare_arguments(self, env):
1692 for arg in self.type.args:
1694 error(arg.pos, "Missing argument name")
1695 self.declare_argument(env, arg)
1697 def need_gil_acquisition(self, lenv):
1698 return self.type.with_gil
1700 def nogil_check(self, env):
1702 with_gil = type.with_gil
1703 if type.nogil and not with_gil:
1704 if type.return_type.is_pyobject:
1706 "Function with Python return type cannot be declared nogil")
1707 for entry in self.local_scope.var_entries:
1708 if entry.type.is_pyobject:
1709 error(self.pos, "Function declared nogil has Python locals or temporaries")
1711 def analyse_expressions(self, env):
1712 self.local_scope.directives = env.directives
1713 if self.py_func is not None:
1714 # this will also analyse the default values
1715 self.py_func.analyse_expressions(env)
1717 self.analyse_default_values(env)
1718 self.acquire_gil = self.need_gil_acquisition(self.local_scope)
1720 def needs_assignment_synthesis(self, env, code=None):
1723 def generate_function_header(self, code, with_pymethdef, with_opt_args = 1, with_dispatch = 1, cname = None):
1726 visibility = self.entry.visibility
1727 for arg in type.args[:len(type.args)-type.optional_arg_count]:
1728 arg_decls.append(arg.declaration_code())
1729 if with_dispatch and self.overridable:
1730 arg_decls.append(PyrexTypes.c_int_type.declaration_code(Naming.skip_dispatch_cname))
1731 if type.optional_arg_count and with_opt_args:
1732 arg_decls.append(type.op_arg_struct.declaration_code(Naming.optional_args_cname))
1733 if type.has_varargs:
1734 arg_decls.append("...")
1736 arg_decls = ["void"]
1738 cname = self.entry.func_cname
1739 entity = type.function_header_code(cname, ', '.join(arg_decls))
1740 if visibility == 'public':
1741 dll_linkage = "DL_EXPORT"
1744 header = self.return_type.declaration_code(entity,
1745 dll_linkage = dll_linkage)
1746 if visibility == 'extern':
1747 storage_class = "%s " % Naming.extern_c_macro
1748 elif visibility == 'public':
1751 storage_class = "static "
1752 if 'inline' in self.modifiers:
1753 self.modifiers[self.modifiers.index('inline')] = 'cython_inline'
1754 code.putln("%s%s %s {" % (
1756 ' '.join(self.modifiers).upper(), # macro forms
1759 def generate_argument_declarations(self, env, code):
1760 for arg in self.args:
1762 result = arg.calculate_default_value_code(code)
1763 code.putln('%s = %s;' % (
1764 arg.type.declaration_code(arg.cname), result))
1766 def generate_keyword_list(self, code):
1769 def generate_argument_parsing_code(self, env, code):
1771 if self.type.optional_arg_count:
1772 code.putln('if (%s) {' % Naming.optional_args_cname)
1773 for arg in self.args:
1775 code.putln('if (%s->%sn > %s) {' % (Naming.optional_args_cname, Naming.pyrex_prefix, i))
1776 declarator = arg.declarator
1777 while not hasattr(declarator, 'name'):
1778 declarator = declarator.base
1779 code.putln('%s = %s->%s;' % (arg.cname, Naming.optional_args_cname, self.type.opt_arg_cname(declarator.name)))
1781 for _ in range(self.type.optional_arg_count):
1785 def generate_argument_conversion_code(self, code):
1788 def generate_argument_type_tests(self, code):
1789 # Generate type tests for args whose type in a parent
1790 # class is a supertype of the declared type.
1791 for arg in self.type.args:
1792 if arg.needs_type_test:
1793 self.generate_arg_type_test(arg, code)
1794 elif arg.type.is_pyobject and not arg.accept_none:
1795 self.generate_arg_none_check(arg, code)
1797 def error_value(self):
1798 if self.return_type.is_pyobject:
1802 return self.entry.type.exception_value
1804 def caller_will_check_exceptions(self):
1805 return self.entry.type.exception_check
1807 def generate_wrapper_functions(self, code):
1808 # If the C signature of a function has changed, we need to generate
1809 # wrappers to put in the slots here.
1812 func_type = entry.type
1813 while entry.prev_entry is not None:
1815 entry = entry.prev_entry
1816 entry.func_cname = "%s%swrap_%s" % (self.entry.func_cname, Naming.pyrex_prefix, k)
1818 self.generate_function_header(code,
1820 with_dispatch = entry.type.is_overridable,
1821 with_opt_args = entry.type.optional_arg_count,
1822 cname = entry.func_cname)
1823 if not self.return_type.is_void:
1825 args = self.type.args
1826 arglist = [arg.cname for arg in args[:len(args)-self.type.optional_arg_count]]
1827 if entry.type.is_overridable:
1828 arglist.append(Naming.skip_dispatch_cname)
1829 elif func_type.is_overridable:
1831 if entry.type.optional_arg_count:
1832 arglist.append(Naming.optional_args_cname)
1833 elif func_type.optional_arg_count:
1834 arglist.append('NULL')
1835 code.putln('%s(%s);' % (self.entry.func_cname, ', '.join(arglist)))
1839 class PyArgDeclNode(Node):
1840 # Argument which must be a Python object (used
1841 # for * and ** arguments).
1844 # entry Symtab.Entry
1845 # annotation ExprNode or None Py3 argument annotation
1848 def generate_function_definitions(self, env, code):
1849 self.entry.generate_function_definitions(env, code)
1851 class DecoratorNode(Node):
1854 # decorator NameNode or CallNode or AttributeNode
1855 child_attrs = ['decorator']
1858 class DefNode(FuncDefNode):
1859 # A Python function definition.
1861 # name string the Python name of the function
1862 # lambda_name string the internal name of a lambda 'function'
1863 # decorators [DecoratorNode] list of decorators
1864 # args [CArgDeclNode] formal arguments
1865 # star_arg PyArgDeclNode or None * argument
1866 # starstar_arg PyArgDeclNode or None ** argument
1867 # doc EncodedString or None
1869 # return_type_annotation
1870 # ExprNode or None the Py3 return type annotation
1872 # The following subnode is constructed internally
1873 # when the def statement is inside a Python class definition.
1875 # assmt AssignmentNode Function construction/assignment
1877 child_attrs = ["args", "star_arg", "starstar_arg", "body", "decorators"]
1882 num_required_kw_args = 0
1883 reqd_kw_flags_cname = "0"
1886 return_type_annotation = None
1891 def __init__(self, pos, **kwds):
1892 FuncDefNode.__init__(self, pos, **kwds)
1894 for arg in self.args:
1901 self.num_kwonly_args = k
1902 self.num_required_kw_args = rk
1903 self.num_required_args = r
1905 def as_cfunction(self, cfunc=None, scope=None):
1907 error(self.star_arg.pos, "cdef function cannot have star argument")
1908 if self.starstar_arg:
1909 error(self.starstar_arg.pos, "cdef function cannot have starstar argument")
1912 for formal_arg in self.args:
1913 name_declarator, type = formal_arg.analyse(scope, nonempty=1)
1914 cfunc_args.append(PyrexTypes.CFuncTypeArg(name = name_declarator.name,
1916 type = py_object_type,
1917 pos = formal_arg.pos))
1918 cfunc_type = PyrexTypes.CFuncType(return_type = py_object_type,
1920 has_varargs = False,
1921 exception_value = None,
1922 exception_check = False,
1925 is_overridable = True)
1926 cfunc = CVarDefNode(self.pos, type=cfunc_type)
1930 cfunc_type = cfunc.type
1931 if len(self.args) != len(cfunc_type.args) or cfunc_type.has_varargs:
1932 error(self.pos, "wrong number of arguments")
1933 error(cfunc.pos, "previous declaration here")
1934 for i, (formal_arg, type_arg) in enumerate(zip(self.args, cfunc_type.args)):
1935 name_declarator, type = formal_arg.analyse(scope, nonempty=1,
1936 is_self_arg = (i == 0 and scope.is_c_class_scope))
1937 if type is None or type is PyrexTypes.py_object_type:
1938 formal_arg.type = type_arg.type
1939 formal_arg.name_declarator = name_declarator
1941 if cfunc_type.exception_value is None:
1942 exception_value = None
1944 exception_value = ExprNodes.ConstNode(self.pos, value=cfunc_type.exception_value, type=cfunc_type.return_type)
1945 declarator = CFuncDeclaratorNode(self.pos,
1946 base = CNameDeclaratorNode(self.pos, name=self.name, cname=None),
1948 has_varargs = False,
1949 exception_check = cfunc_type.exception_check,
1950 exception_value = exception_value,
1951 with_gil = cfunc_type.with_gil,
1952 nogil = cfunc_type.nogil)
1953 return CFuncDefNode(self.pos,
1955 base_type = CAnalysedBaseTypeNode(self.pos, type=cfunc_type.return_type),
1956 declarator = declarator,
1959 overridable = cfunc_type.is_overridable,
1961 with_gil = cfunc_type.with_gil,
1962 nogil = cfunc_type.nogil,
1963 visibility = 'private',
1965 directive_locals = getattr(cfunc, 'directive_locals', {}))
1967 def analyse_declarations(self, env):
1968 self.is_classmethod = self.is_staticmethod = False
1970 for decorator in self.decorators:
1971 func = decorator.decorator
1973 self.is_classmethod |= func.name == 'classmethod'
1974 self.is_staticmethod |= func.name == 'staticmethod'
1976 if self.is_classmethod and env.lookup_here('classmethod'):
1977 # classmethod() was overridden - not much we can do here ...
1978 self.is_classmethod = False
1979 if self.is_staticmethod and env.lookup_here('staticmethod'):
1980 # staticmethod() was overridden - not much we can do here ...
1981 self.is_staticmethod = False
1983 if self.name == '__new__':
1984 self.is_staticmethod = 1
1986 self.analyse_argument_types(env)
1987 if self.name == '<lambda>':
1988 self.declare_lambda_function(env)
1990 self.declare_pyfunction(env)
1991 self.analyse_signature(env)
1992 self.return_type = self.entry.signature.return_type()
1993 self.create_local_scope(env)
1995 def analyse_argument_types(self, env):
1996 directive_locals = self.directive_locals = env.directives['locals']
1997 allow_none_for_extension_args = env.directives['allow_none_for_extension_args']
1998 for arg in self.args:
1999 if hasattr(arg, 'name'):
2001 name_declarator = None
2003 base_type = arg.base_type.analyse(env)
2004 name_declarator, type = \
2005 arg.declarator.analyse(base_type, env)
2006 arg.name = name_declarator.name
2007 if arg.name in directive_locals:
2008 type_node = directive_locals[arg.name]
2009 other_type = type_node.analyse_as_type(env)
2010 if other_type is None:
2011 error(type_node.pos, "Not a type")
2012 elif (type is not PyrexTypes.py_object_type
2013 and not type.same_as(other_type)):
2014 error(arg.base_type.pos, "Signature does not agree with previous declaration")
2015 error(type_node.pos, "Previous declaration here")
2018 if name_declarator and name_declarator.cname:
2020 "Python function argument cannot have C name specification")
2021 arg.type = type.as_argument_type()
2023 arg.needs_conversion = 0
2024 arg.needs_type_test = 0
2026 if arg.type.is_pyobject:
2028 arg.accept_none = True
2030 arg.accept_none = False
2031 elif arg.type.is_extension_type or arg.type.is_builtin_type:
2032 if arg.default and arg.default.constant_result is None:
2033 # special case: def func(MyType obj = None)
2034 arg.accept_none = True
2036 # default depends on compiler directive
2037 arg.accept_none = allow_none_for_extension_args
2039 # probably just a plain 'object'
2040 arg.accept_none = True
2042 arg.accept_none = True # won't be used, but must be there
2044 error(arg.pos, "Only Python type arguments can have 'not None'")
2046 error(arg.pos, "Only Python type arguments can have 'or None'")
2048 def analyse_signature(self, env):
2049 if self.entry.is_special:
2050 self.entry.trivial_signature = len(self.args) == 1 and not (self.star_arg or self.starstar_arg)
2051 elif not env.directives['always_allow_keywords'] and not (self.star_arg or self.starstar_arg):
2052 # Use the simpler calling signature for zero- and one-argument functions.
2053 if self.entry.signature is TypeSlots.pyfunction_signature:
2054 if len(self.args) == 0:
2055 self.entry.signature = TypeSlots.pyfunction_noargs
2056 elif len(self.args) == 1:
2057 if self.args[0].default is None and not self.args[0].kw_only:
2058 self.entry.signature = TypeSlots.pyfunction_onearg
2059 elif self.entry.signature is TypeSlots.pymethod_signature:
2060 if len(self.args) == 1:
2061 self.entry.signature = TypeSlots.unaryfunc
2062 elif len(self.args) == 2:
2063 if self.args[1].default is None and not self.args[1].kw_only:
2064 self.entry.signature = TypeSlots.ibinaryfunc
2066 sig = self.entry.signature
2067 nfixed = sig.num_fixed_args()
2068 if sig is TypeSlots.pymethod_signature and nfixed == 1 \
2069 and len(self.args) == 0 and self.star_arg:
2070 # this is the only case where a diverging number of
2071 # arguments is not an error - when we have no explicit
2072 # 'self' parameter as in method(*args)
2073 sig = self.entry.signature = TypeSlots.pyfunction_signature # self is not 'really' used
2074 self.self_in_stararg = 1
2077 for i in range(min(nfixed, len(self.args))):
2080 if sig.is_self_arg(i) and not self.is_staticmethod:
2081 if self.is_classmethod:
2083 arg.hdr_type = arg.type = Builtin.type_type
2086 arg.hdr_type = arg.type = env.parent_type
2087 arg.needs_conversion = 0
2089 arg.hdr_type = sig.fixed_arg_type(i)
2090 if not arg.type.same_as(arg.hdr_type):
2091 if arg.hdr_type.is_pyobject and arg.type.is_pyobject:
2092 arg.needs_type_test = 1
2094 arg.needs_conversion = 1
2095 if arg.needs_conversion:
2096 arg.hdr_cname = Naming.arg_prefix + arg.name
2098 arg.hdr_cname = Naming.var_prefix + arg.name
2100 if nfixed > len(self.args):
2101 self.bad_signature()
2103 elif nfixed < len(self.args):
2104 if not sig.has_generic_args:
2105 self.bad_signature()
2106 for arg in self.args:
2107 if arg.is_generic and \
2108 (arg.type.is_extension_type or arg.type.is_builtin_type):
2109 arg.needs_type_test = 1
2111 def bad_signature(self):
2112 sig = self.entry.signature
2113 expected_str = "%d" % sig.num_fixed_args()
2114 if sig.has_generic_args:
2115 expected_str = expected_str + " or more"
2117 if name.startswith("__") and name.endswith("__"):
2118 desc = "Special method"
2122 "%s %s has wrong number of arguments "
2123 "(%d declared, %s expected)" % (
2124 desc, self.name, len(self.args), expected_str))
2126 def signature_has_nongeneric_args(self):
2127 argcount = len(self.args)
2128 if argcount == 0 or (
2129 argcount == 1 and (self.args[0].is_self_arg or
2130 self.args[0].is_type_arg)):
2134 def signature_has_generic_args(self):
2135 return self.entry.signature.has_generic_args
2137 def declare_pyfunction(self, env):
2138 #print "DefNode.declare_pyfunction:", self.name, "in", env ###
2140 entry = env.lookup_here(name)
2141 if entry and entry.type.is_cfunction and not self.is_wrapper:
2142 warning(self.pos, "Overriding cdef method with def method.", 5)
2143 entry = env.declare_pyfunction(name, self.pos)
2145 prefix = env.scope_prefix
2146 entry.func_cname = \
2147 Naming.pyfunc_prefix + prefix + name
2148 entry.pymethdef_cname = \
2149 Naming.pymethdef_prefix + prefix + name
2150 if Options.docstrings:
2151 entry.doc = embed_position(self.pos, self.doc)
2153 Naming.funcdoc_prefix + prefix + name
2154 if entry.is_special:
2155 if entry.name in TypeSlots.invisible or not entry.doc or (entry.name in '__getattr__' and env.directives['fast_getattr']):
2156 entry.wrapperbase_cname = None
2158 entry.wrapperbase_cname = Naming.wrapperbase_prefix + prefix + name
2162 def declare_lambda_function(self, env):
2164 prefix = env.scope_prefix
2166 Naming.lambda_func_prefix + u'funcdef' + prefix + self.lambda_name
2167 entry = env.declare_lambda_function(func_cname, self.pos)
2168 entry.pymethdef_cname = \
2169 Naming.lambda_func_prefix + u'methdef' + prefix + self.lambda_name
2170 entry.qualified_name = env.qualify_name(self.lambda_name)
2174 def declare_arguments(self, env):
2175 for arg in self.args:
2177 error(arg.pos, "Missing argument name")
2179 env.control_flow.set_state((), (arg.name, 'source'), 'arg')
2180 env.control_flow.set_state((), (arg.name, 'initialized'), True)
2181 if arg.needs_conversion:
2182 arg.entry = env.declare_var(arg.name, arg.type, arg.pos)
2183 if arg.type.is_pyobject:
2184 arg.entry.init = "0"
2185 arg.entry.init_to_none = 0
2187 arg.entry = self.declare_argument(env, arg)
2189 arg.entry.is_self_arg = arg.is_self_arg
2191 if arg.is_self_arg or arg.is_type_arg or \
2192 (arg.type.is_extension_type and not arg.hdr_type.is_extension_type):
2193 arg.entry.is_declared_generic = 1
2194 self.declare_python_arg(env, self.star_arg)
2195 self.declare_python_arg(env, self.starstar_arg)
2197 def declare_python_arg(self, env, arg):
2199 if env.directives['infer_types'] != False:
2200 type = PyrexTypes.unspecified_type
2202 type = py_object_type
2203 entry = env.declare_var(arg.name, type, arg.pos)
2206 entry.init_to_none = 0
2207 entry.xdecref_cleanup = 1
2209 env.control_flow.set_state((), (arg.name, 'initialized'), True)
2211 def analyse_expressions(self, env):
2212 self.local_scope.directives = env.directives
2213 self.analyse_default_values(env)
2214 if self.needs_assignment_synthesis(env):
2215 # Shouldn't we be doing this at the module level too?
2216 self.synthesize_assignment_node(env)
2218 def needs_assignment_synthesis(self, env, code=None):
2219 # Should enable for module level as well, that will require more testing...
2220 if self.entry.is_lambda:
2222 if env.is_module_scope:
2224 return env.directives['binding']
2226 return code.globalstate.directives['binding']
2227 return env.is_py_class_scope or env.is_closure_scope
2229 def synthesize_assignment_node(self, env):
2232 while genv.is_py_class_scope or genv.is_c_class_scope:
2233 genv = genv.outer_scope
2235 if genv.is_closure_scope:
2236 rhs = ExprNodes.InnerFunctionNode(
2237 self.pos, pymethdef_cname = self.entry.pymethdef_cname)
2239 rhs = ExprNodes.PyCFunctionNode(
2240 self.pos, pymethdef_cname = self.entry.pymethdef_cname, binding = env.directives['binding'])
2242 if env.is_py_class_scope:
2243 if not self.is_staticmethod and not self.is_classmethod:
2246 self.assmt = SingleAssignmentNode(self.pos,
2247 lhs = ExprNodes.NameNode(self.pos, name = self.name),
2249 self.assmt.analyse_declarations(env)
2250 self.assmt.analyse_expressions(env)
2252 def generate_function_header(self, code, with_pymethdef, proto_only=0):
2254 sig = self.entry.signature
2255 if sig.has_dummy_arg or self.self_in_stararg:
2256 arg_code_list.append(
2257 "PyObject *%s" % Naming.self_cname)
2258 for arg in self.args:
2259 if not arg.is_generic:
2260 if arg.is_self_arg or arg.is_type_arg:
2261 arg_code_list.append("PyObject *%s" % arg.hdr_cname)
2263 arg_code_list.append(
2264 arg.hdr_type.declaration_code(arg.hdr_cname))
2265 if not self.entry.is_special and sig.method_flags() == [TypeSlots.method_noargs]:
2266 arg_code_list.append("CYTHON_UNUSED PyObject *unused")
2267 if sig.has_generic_args:
2268 arg_code_list.append(
2269 "PyObject *%s, PyObject *%s"
2270 % (Naming.args_cname, Naming.kwds_cname))
2271 arg_code = ", ".join(arg_code_list)
2272 dc = self.return_type.declaration_code(self.entry.func_cname)
2273 mf = " ".join(self.modifiers).upper()
2275 header = "static %s%s(%s)" % (mf, dc, arg_code)
2276 code.putln("%s; /*proto*/" % header)
2279 if (Options.docstrings and self.entry.doc and
2280 not self.entry.scope.is_property_scope and
2281 (not self.entry.is_special or self.entry.wrapperbase_cname)):
2282 docstr = self.entry.doc
2283 if docstr.is_unicode:
2284 docstr = docstr.utf8encode()
2286 'static char %s[] = "%s";' % (
2287 self.entry.doc_cname,
2288 split_string_literal(escape_byte_string(docstr))))
2289 if self.entry.is_special:
2291 "struct wrapperbase %s;" % self.entry.wrapperbase_cname)
2294 "static PyMethodDef %s = " %
2295 self.entry.pymethdef_cname)
2296 code.put_pymethoddef(self.entry, ";", allow_skip=False)
2297 code.putln("%s {" % header)
2299 def generate_argument_declarations(self, env, code):
2300 for arg in self.args:
2301 if arg.is_generic: # or arg.needs_conversion:
2302 if arg.needs_conversion:
2303 code.putln("PyObject *%s = 0;" % arg.hdr_cname)
2304 elif not arg.entry.in_closure:
2305 code.put_var_declaration(arg.entry)
2307 def generate_keyword_list(self, code):
2308 if self.signature_has_generic_args() and \
2309 self.signature_has_nongeneric_args():
2311 "static PyObject **%s[] = {" %
2312 Naming.pykwdlist_cname)
2313 for arg in self.args:
2315 pystring_cname = code.intern_identifier(arg.name)
2316 code.put('&%s,' % pystring_cname)
2319 def generate_argument_parsing_code(self, env, code):
2320 # Generate PyArg_ParseTuple call for generic
2321 # arguments, if any.
2322 if self.entry.signature.has_dummy_arg and not self.self_in_stararg:
2323 # get rid of unused argument warning
2324 code.putln("%s = %s;" % (Naming.self_cname, Naming.self_cname))
2326 old_error_label = code.new_error_label()
2327 our_error_label = code.error_label
2328 end_label = code.new_label("argument_unpacking_done")
2330 has_kwonly_args = self.num_kwonly_args > 0
2331 has_star_or_kw_args = self.star_arg is not None \
2332 or self.starstar_arg is not None or has_kwonly_args
2334 for arg in self.args:
2335 if not arg.type.is_pyobject:
2336 done = arg.type.create_from_py_utility_code(env)
2337 if not done: pass # will fail later
2339 if not self.signature_has_generic_args():
2340 if has_star_or_kw_args:
2341 error(self.pos, "This method cannot have * or keyword arguments")
2342 self.generate_argument_conversion_code(code)
2344 elif not self.signature_has_nongeneric_args():
2345 # func(*args) or func(**kw) or func(*args, **kw)
2346 self.generate_stararg_copy_code(code)
2349 positional_args = []
2351 for arg in self.args:
2352 arg_entry = arg.entry
2355 if not arg.is_self_arg and not arg.is_type_arg:
2357 kw_only_args.append(arg)
2359 positional_args.append(arg)
2361 kw_only_args.append(arg)
2362 elif not arg.is_self_arg and not arg.is_type_arg:
2363 positional_args.append(arg)
2365 self.generate_tuple_and_keyword_parsing_code(
2366 positional_args, kw_only_args, end_label, code)
2368 code.error_label = old_error_label
2369 if code.label_used(our_error_label):
2370 if not code.label_used(end_label):
2371 code.put_goto(end_label)
2372 code.put_label(our_error_label)
2373 if has_star_or_kw_args:
2374 self.generate_arg_decref(self.star_arg, code)
2375 if self.starstar_arg:
2376 if self.starstar_arg.entry.xdecref_cleanup:
2377 code.put_var_xdecref(self.starstar_arg.entry)
2379 code.put_var_decref(self.starstar_arg.entry)
2380 code.putln('__Pyx_AddTraceback("%s");' % self.entry.qualified_name)
2381 # The arguments are put into the closure one after the
2382 # other, so when type errors are found, all references in
2383 # the closure instance must be properly ref-counted to
2384 # facilitate generic closure instance deallocation. In
2385 # the case of an argument type error, it's best to just
2386 # DECREF+clear the already handled references, as this
2387 # frees their references as early as possible.
2388 for arg in self.args:
2389 if arg.type.is_pyobject and arg.entry.in_closure:
2390 code.put_var_xdecref_clear(arg.entry)
2391 if self.needs_closure:
2392 code.put_decref(Naming.cur_scope_cname, self.local_scope.scope_class.type)
2393 code.put_finish_refcount_context()
2394 code.putln("return %s;" % self.error_value())
2395 if code.label_used(end_label):
2396 code.put_label(end_label)
2398 def generate_arg_assignment(self, arg, item, code):
2399 if arg.type.is_pyobject:
2401 item = PyrexTypes.typecast(arg.type, PyrexTypes.py_object_type, item)
2403 code.putln("%s = %s;" % (entry.cname, item))
2404 if entry.in_closure:
2405 code.put_var_incref(entry)
2407 func = arg.type.from_py_function
2409 code.putln("%s = %s(%s); %s" % (
2413 code.error_goto_if(arg.type.error_condition(arg.entry.cname), arg.pos)))
2415 error(arg.pos, "Cannot convert Python object argument to type '%s'" % arg.type)
2417 def generate_arg_xdecref(self, arg, code):
2419 code.put_var_xdecref(arg.entry)
2421 def generate_arg_decref(self, arg, code):
2423 code.put_var_decref(arg.entry)
2425 def generate_stararg_copy_code(self, code):
2426 if not self.star_arg:
2427 code.globalstate.use_utility_code(raise_argtuple_invalid_utility_code)
2428 code.putln("if (unlikely(PyTuple_GET_SIZE(%s) > 0)) {" %
2430 code.put('__Pyx_RaiseArgtupleInvalid("%s", 1, 0, 0, PyTuple_GET_SIZE(%s)); return %s;' % (
2431 self.name, Naming.args_cname, self.error_value()))
2434 code.globalstate.use_utility_code(keyword_string_check_utility_code)
2436 if self.starstar_arg:
2438 kwarg_check = "unlikely(%s)" % Naming.kwds_cname
2440 kwarg_check = "%s" % Naming.kwds_cname
2442 kwarg_check = "unlikely(%s) && unlikely(PyDict_Size(%s) > 0)" % (
2443 Naming.kwds_cname, Naming.kwds_cname)
2445 "if (%s && unlikely(!__Pyx_CheckKeywordStrings(%s, \"%s\", %d))) return %s;" % (
2446 kwarg_check, Naming.kwds_cname, self.name,
2447 bool(self.starstar_arg), self.error_value()))
2449 if self.starstar_arg:
2450 code.putln("%s = (%s) ? PyDict_Copy(%s) : PyDict_New();" % (
2451 self.starstar_arg.entry.cname,
2454 code.putln("if (unlikely(!%s)) return %s;" % (
2455 self.starstar_arg.entry.cname, self.error_value()))
2456 self.starstar_arg.entry.xdecref_cleanup = 0
2457 code.put_gotref(self.starstar_arg.entry.cname)
2459 if self.self_in_stararg:
2460 # need to create a new tuple with 'self' inserted as first item
2461 code.put("%s = PyTuple_New(PyTuple_GET_SIZE(%s)+1); if (unlikely(!%s)) " % (
2462 self.star_arg.entry.cname,
2464 self.star_arg.entry.cname))
2465 if self.starstar_arg:
2467 code.put_decref_clear(self.starstar_arg.entry.cname, py_object_type)
2468 code.putln("return %s;" % self.error_value())
2471 code.putln("return %s;" % self.error_value())
2472 code.put_gotref(self.star_arg.entry.cname)
2473 code.put_incref(Naming.self_cname, py_object_type)
2474 code.put_giveref(Naming.self_cname)
2475 code.putln("PyTuple_SET_ITEM(%s, 0, %s);" % (
2476 self.star_arg.entry.cname, Naming.self_cname))
2477 temp = code.funcstate.allocate_temp(PyrexTypes.c_py_ssize_t_type, manage_ref=False)
2478 code.putln("for (%s=0; %s < PyTuple_GET_SIZE(%s); %s++) {" % (
2479 temp, temp, Naming.args_cname, temp))
2480 code.putln("PyObject* item = PyTuple_GET_ITEM(%s, %s);" % (
2481 Naming.args_cname, temp))
2482 code.put_incref("item", py_object_type)
2483 code.put_giveref("item")
2484 code.putln("PyTuple_SET_ITEM(%s, %s+1, item);" % (
2485 self.star_arg.entry.cname, temp))
2487 code.funcstate.release_temp(temp)
2488 self.star_arg.entry.xdecref_cleanup = 0
2490 code.put_incref(Naming.args_cname, py_object_type)
2491 code.putln("%s = %s;" % (
2492 self.star_arg.entry.cname,
2494 self.star_arg.entry.xdecref_cleanup = 0
2496 def generate_tuple_and_keyword_parsing_code(self, positional_args,
2497 kw_only_args, success_label, code):
2498 argtuple_error_label = code.new_label("argtuple_error")
2500 min_positional_args = self.num_required_args - self.num_required_kw_args
2501 if len(self.args) > 0 and (self.args[0].is_self_arg or self.args[0].is_type_arg):
2502 min_positional_args -= 1
2503 max_positional_args = len(positional_args)
2504 has_fixed_positional_count = not self.star_arg and \
2505 min_positional_args == max_positional_args
2507 code.globalstate.use_utility_code(raise_double_keywords_utility_code)
2508 code.globalstate.use_utility_code(raise_argtuple_invalid_utility_code)
2509 if self.num_required_kw_args:
2510 code.globalstate.use_utility_code(raise_keyword_required_utility_code)
2512 if self.starstar_arg or self.star_arg:
2513 self.generate_stararg_init_code(max_positional_args, code)
2515 # --- optimised code when we receive keyword arguments
2516 if self.num_required_kw_args:
2517 likely_hint = "likely"
2519 likely_hint = "unlikely"
2520 code.putln("if (%s(%s)) {" % (likely_hint, Naming.kwds_cname))
2521 self.generate_keyword_unpacking_code(
2522 min_positional_args, max_positional_args,
2523 has_fixed_positional_count,
2524 positional_args, kw_only_args, argtuple_error_label, code)
2526 # --- optimised code when we do not receive any keyword arguments
2527 if (self.num_required_kw_args and min_positional_args > 0) or min_positional_args == max_positional_args:
2528 # Python raises arg tuple related errors first, so we must
2529 # check the length here
2530 if min_positional_args == max_positional_args and not self.star_arg:
2534 code.putln('} else if (PyTuple_GET_SIZE(%s) %s %d) {' % (
2535 Naming.args_cname, compare, min_positional_args))
2536 code.put_goto(argtuple_error_label)
2538 if self.num_required_kw_args:
2539 # pure error case: keywords required but not passed
2540 if max_positional_args > min_positional_args and not self.star_arg:
2541 code.putln('} else if (PyTuple_GET_SIZE(%s) > %d) {' % (
2542 Naming.args_cname, max_positional_args))
2543 code.put_goto(argtuple_error_label)
2544 code.putln('} else {')
2545 for i, arg in enumerate(kw_only_args):
2547 pystring_cname = code.intern_identifier(arg.name)
2548 # required keyword-only argument missing
2549 code.put('__Pyx_RaiseKeywordRequired("%s", %s); ' % (
2552 code.putln(code.error_goto(self.pos))
2555 elif min_positional_args == max_positional_args:
2556 # parse the exact number of positional arguments from the
2558 code.putln('} else {')
2559 for i, arg in enumerate(positional_args):
2560 item = "PyTuple_GET_ITEM(%s, %d)" % (Naming.args_cname, i)
2561 self.generate_arg_assignment(arg, item, code)
2562 self.generate_arg_default_assignments(code)
2565 # parse the positional arguments from the variable length
2567 code.putln('} else {')
2568 self.generate_arg_default_assignments(code)
2569 code.putln('switch (PyTuple_GET_SIZE(%s)) {' % Naming.args_cname)
2571 code.putln('default:')
2572 reversed_args = list(enumerate(positional_args))[::-1]
2573 for i, arg in reversed_args:
2574 if i >= min_positional_args-1:
2575 if min_positional_args > 1:
2576 code.putln('case %2d:' % (i+1)) # pure code beautification
2578 code.put('case %2d: ' % (i+1))
2579 item = "PyTuple_GET_ITEM(%s, %d)" % (Naming.args_cname, i)
2580 self.generate_arg_assignment(arg, item, code)
2581 if min_positional_args == 0:
2582 code.put('case 0: ')
2583 code.putln('break;')
2585 if min_positional_args:
2586 for i in range(min_positional_args-1, -1, -1):
2587 code.putln('case %2d:' % i)
2588 code.put_goto(argtuple_error_label)
2590 code.put('default: ')
2591 code.put_goto(argtuple_error_label)
2596 if code.label_used(argtuple_error_label):
2597 code.put_goto(success_label)
2598 code.put_label(argtuple_error_label)
2599 code.put('__Pyx_RaiseArgtupleInvalid("%s", %d, %d, %d, PyTuple_GET_SIZE(%s)); ' % (
2600 self.name, has_fixed_positional_count,
2601 min_positional_args, max_positional_args,
2603 code.putln(code.error_goto(self.pos))
2605 def generate_arg_default_assignments(self, code):
2606 for arg in self.args:
2607 if arg.is_generic and arg.default:
2611 arg.calculate_default_value_code(code)))
2613 def generate_stararg_init_code(self, max_positional_args, code):
2614 if self.starstar_arg:
2615 self.starstar_arg.entry.xdecref_cleanup = 0
2616 code.putln('%s = PyDict_New(); if (unlikely(!%s)) return %s;' % (
2617 self.starstar_arg.entry.cname,
2618 self.starstar_arg.entry.cname,
2619 self.error_value()))
2620 code.put_gotref(self.starstar_arg.entry.cname)
2622 self.star_arg.entry.xdecref_cleanup = 0
2623 code.putln('if (PyTuple_GET_SIZE(%s) > %d) {' % (
2625 max_positional_args))
2626 code.put('%s = PyTuple_GetSlice(%s, %d, PyTuple_GET_SIZE(%s)); ' % (
2627 self.star_arg.entry.cname, Naming.args_cname,
2628 max_positional_args, Naming.args_cname))
2629 code.put_gotref(self.star_arg.entry.cname)
2630 if self.starstar_arg:
2632 code.putln("if (unlikely(!%s)) {" % self.star_arg.entry.cname)
2633 code.put_decref(self.starstar_arg.entry.cname, py_object_type)
2634 code.putln('return %s;' % self.error_value())
2637 code.putln("if (unlikely(!%s)) return %s;" % (
2638 self.star_arg.entry.cname, self.error_value()))
2639 code.putln('} else {')
2640 code.put("%s = %s; " % (self.star_arg.entry.cname, Naming.empty_tuple))
2641 code.put_incref(Naming.empty_tuple, py_object_type)
2644 def generate_keyword_unpacking_code(self, min_positional_args, max_positional_args,
2645 has_fixed_positional_count, positional_args,
2646 kw_only_args, argtuple_error_label, code):
2647 all_args = tuple(positional_args) + tuple(kw_only_args)
2648 max_args = len(all_args)
2650 code.putln("Py_ssize_t kw_args = PyDict_Size(%s);" %
2652 # the 'values' array collects borrowed references to arguments
2653 # before doing any type coercion etc.
2654 code.putln("PyObject* values[%d] = {%s};" % (
2655 max_args, ','.join('0'*max_args)))
2657 # assign borrowed Python default values to the values array,
2658 # so that they can be overwritten by received arguments below
2659 for i, arg in enumerate(all_args):
2660 if arg.default and arg.type.is_pyobject:
2661 default_value = arg.calculate_default_value_code(code)
2662 code.putln('values[%d] = %s;' % (i, arg.type.as_pyobject(default_value)))
2664 # parse the args tuple and check that it's not too long
2665 code.putln('switch (PyTuple_GET_SIZE(%s)) {' % Naming.args_cname)
2667 code.putln('default:')
2668 for i in range(max_positional_args-1, -1, -1):
2669 code.put('case %2d: ' % (i+1))
2670 code.putln("values[%d] = PyTuple_GET_ITEM(%s, %d);" % (
2671 i, Naming.args_cname, i))
2672 code.putln('case 0: break;')
2673 if not self.star_arg:
2674 code.put('default: ') # more arguments than allowed
2675 code.put_goto(argtuple_error_label)
2678 # now fill up the positional/required arguments with values
2680 if self.num_required_args or max_positional_args > 0:
2681 last_required_arg = -1
2682 for i, arg in enumerate(all_args):
2684 last_required_arg = i
2685 if last_required_arg < max_positional_args:
2686 last_required_arg = max_positional_args-1
2687 num_required_args = self.num_required_args
2688 if max_positional_args > 0:
2689 code.putln('switch (PyTuple_GET_SIZE(%s)) {' % Naming.args_cname)
2690 for i, arg in enumerate(all_args[:last_required_arg+1]):
2691 if max_positional_args > 0 and i <= max_positional_args:
2692 if self.star_arg and i == max_positional_args:
2693 code.putln('default:')
2695 code.putln('case %2d:' % i)
2696 pystring_cname = code.intern_identifier(arg.name)
2699 # handled separately below
2701 code.putln('if (kw_args > 0) {')
2702 code.putln('PyObject* value = PyDict_GetItem(%s, %s);' % (
2703 Naming.kwds_cname, pystring_cname))
2704 code.putln('if (value) { values[%d] = value; kw_args--; }' % i)
2707 num_required_args -= 1
2708 code.putln('values[%d] = PyDict_GetItem(%s, %s);' % (
2709 i, Naming.kwds_cname, pystring_cname))
2710 code.putln('if (likely(values[%d])) kw_args--;' % i);
2711 if i < min_positional_args:
2713 # special case: we know arg 0 is missing
2715 code.put_goto(argtuple_error_label)
2717 # print the correct number of values (args or
2718 # kwargs) that were passed into positional
2719 # arguments up to this point
2720 code.putln('else {')
2721 code.put('__Pyx_RaiseArgtupleInvalid("%s", %d, %d, %d, %d); ' % (
2722 self.name, has_fixed_positional_count,
2723 min_positional_args, max_positional_args, i))
2724 code.putln(code.error_goto(self.pos))
2727 code.putln('else {')
2728 code.put('__Pyx_RaiseKeywordRequired("%s", %s); ' %(
2729 self.name, pystring_cname))
2730 code.putln(code.error_goto(self.pos))
2732 if max_positional_args > 0:
2735 if kw_only_args and not self.starstar_arg:
2736 # unpack optional keyword-only arguments
2737 # checking for interned strings in a dict is faster than iterating
2738 # but it's too likely that we must iterate if we expect **kwargs
2740 for i, arg in enumerate(all_args[max_positional_args:]):
2741 if not arg.kw_only or not arg.default:
2743 optional_args.append((i+max_positional_args, arg))
2745 # this mimics an unrolled loop so that we can "break" out of it
2746 code.putln('while (kw_args > 0) {')
2747 code.putln('PyObject* value;')
2748 for i, arg in optional_args:
2749 pystring_cname = code.intern_identifier(arg.name)
2751 'value = PyDict_GetItem(%s, %s);' % (
2752 Naming.kwds_cname, pystring_cname))
2754 'if (value) { values[%d] = value; if (!(--kw_args)) break; }' % i)
2755 code.putln('break;')
2758 code.putln('if (unlikely(kw_args > 0)) {')
2759 # non-positional/-required kw args left in dict: default args,
2760 # kw-only args, **kwargs or error
2762 # This is sort of a catch-all: except for checking required
2763 # arguments, this will always do the right thing for unpacking
2764 # keyword arguments, so that we can concentrate on optimising
2765 # common cases above.
2766 if max_positional_args == 0:
2769 code.putln("const Py_ssize_t used_pos_args = (PyTuple_GET_SIZE(%s) < %d) ? PyTuple_GET_SIZE(%s) : %d;" % (
2770 Naming.args_cname, max_positional_args,
2771 Naming.args_cname, max_positional_args))
2772 pos_arg_count = "used_pos_args"
2774 pos_arg_count = "PyTuple_GET_SIZE(%s)" % Naming.args_cname
2775 code.globalstate.use_utility_code(parse_keywords_utility_code)
2777 'if (unlikely(__Pyx_ParseOptionalKeywords(%s, %s, %s, values, %s, "%s") < 0)) ' % (
2779 Naming.pykwdlist_cname,
2780 self.starstar_arg and self.starstar_arg.entry.cname or '0',
2783 code.putln(code.error_goto(self.pos))
2786 # convert arg values to their final type and assign them
2787 for i, arg in enumerate(all_args):
2788 if arg.default and not arg.type.is_pyobject:
2789 code.putln("if (values[%d]) {" % i)
2790 self.generate_arg_assignment(arg, "values[%d]" % i, code)
2791 if arg.default and not arg.type.is_pyobject:
2792 code.putln('} else {')
2796 arg.calculate_default_value_code(code)))
2799 def generate_argument_conversion_code(self, code):
2800 # Generate code to convert arguments from signature type to
2801 # declared type, if needed. Also copies signature arguments
2802 # into closure fields.
2803 for arg in self.args:
2804 if arg.needs_conversion:
2805 self.generate_arg_conversion(arg, code)
2806 elif arg.entry.in_closure:
2807 code.putln('%s = %s;' % (arg.entry.cname, arg.hdr_cname))
2808 if arg.type.is_pyobject:
2809 code.put_var_incref(arg.entry)
2811 def generate_arg_conversion(self, arg, code):
2812 # Generate conversion code for one argument.
2813 old_type = arg.hdr_type
2815 if old_type.is_pyobject:
2817 code.putln("if (%s) {" % arg.hdr_cname)
2819 code.putln("assert(%s); {" % arg.hdr_cname)
2820 self.generate_arg_conversion_from_pyobject(arg, code)
2822 elif new_type.is_pyobject:
2823 self.generate_arg_conversion_to_pyobject(arg, code)
2825 if new_type.assignable_from(old_type):
2827 "%s = %s;" % (arg.entry.cname, arg.hdr_cname))
2830 "Cannot convert 1 argument from '%s' to '%s'" %
2831 (old_type, new_type))
2833 def generate_arg_conversion_from_pyobject(self, arg, code):
2835 func = new_type.from_py_function
2836 # copied from CoerceFromPyTypeNode
2838 lhs = arg.entry.cname
2839 rhs = "%s(%s)" % (func, arg.hdr_cname)
2840 if new_type.is_enum:
2841 rhs = PyrexTypes.typecast(new_type, PyrexTypes.c_long_type, rhs)
2842 code.putln("%s = %s; %s" % (
2845 code.error_goto_if(new_type.error_condition(arg.entry.cname), arg.pos)))
2848 "Cannot convert Python object argument to type '%s'"
2851 def generate_arg_conversion_to_pyobject(self, arg, code):
2852 old_type = arg.hdr_type
2853 func = old_type.to_py_function
2855 code.putln("%s = %s(%s); %s" % (
2859 code.error_goto_if_null(arg.entry.cname, arg.pos)))
2860 code.put_var_gotref(arg.entry)
2863 "Cannot convert argument of type '%s' to Python object"
2866 def generate_argument_type_tests(self, code):
2867 # Generate type tests for args whose signature
2868 # type is PyObject * and whose declared type is
2869 # a subtype thereof.
2870 for arg in self.args:
2871 if arg.needs_type_test:
2872 self.generate_arg_type_test(arg, code)
2873 elif not arg.accept_none and arg.type.is_pyobject:
2874 self.generate_arg_none_check(arg, code)
2876 def error_value(self):
2877 return self.entry.signature.error_value
2879 def caller_will_check_exceptions(self):
2882 class OverrideCheckNode(StatNode):
2883 # A Node for dispatching to the def method if it
2892 child_attrs = ['body']
2896 def analyse_expressions(self, env):
2897 self.args = env.arg_entries
2898 if self.py_func.is_module_scope:
2903 self.func_node = ExprNodes.RawCNameExprNode(self.pos, py_object_type)
2904 call_tuple = ExprNodes.TupleNode(self.pos, args=[ExprNodes.NameNode(self.pos, name=arg.name) for arg in self.args[first_arg:]])
2905 call_node = ExprNodes.SimpleCallNode(self.pos,
2906 function=self.func_node,
2907 args=[ExprNodes.NameNode(self.pos, name=arg.name) for arg in self.args[first_arg:]])
2908 self.body = ReturnStatNode(self.pos, value=call_node)
2909 self.body.analyse_expressions(env)
2911 def generate_execution_code(self, code):
2912 interned_attr_cname = code.intern_identifier(self.py_func.entry.name)
2913 # Check to see if we are an extension type
2914 if self.py_func.is_module_scope:
2915 self_arg = "((PyObject *)%s)" % Naming.module_cname
2917 self_arg = "((PyObject *)%s)" % self.args[0].cname
2918 code.putln("/* Check if called by wrapper */")
2919 code.putln("if (unlikely(%s)) ;" % Naming.skip_dispatch_cname)
2920 code.putln("/* Check if overriden in Python */")
2921 if self.py_func.is_module_scope:
2922 code.putln("else {")
2924 code.putln("else if (unlikely(Py_TYPE(%s)->tp_dictoffset != 0)) {" % self_arg)
2925 func_node_temp = code.funcstate.allocate_temp(py_object_type, manage_ref=True)
2926 self.func_node.set_cname(func_node_temp)
2927 # need to get attribute manually--scope would return cdef method
2928 err = code.error_goto_if_null(func_node_temp, self.pos)
2929 code.putln("%s = PyObject_GetAttr(%s, %s); %s" % (
2930 func_node_temp, self_arg, interned_attr_cname, err))
2931 code.put_gotref(func_node_temp)
2932 is_builtin_function_or_method = "PyCFunction_Check(%s)" % func_node_temp
2933 is_overridden = "(PyCFunction_GET_FUNCTION(%s) != (void *)&%s)" % (
2934 func_node_temp, self.py_func.entry.func_cname)
2935 code.putln("if (!%s || %s) {" % (is_builtin_function_or_method, is_overridden))
2936 self.body.generate_execution_code(code)
2938 code.put_decref_clear(func_node_temp, PyrexTypes.py_object_type)
2939 code.funcstate.release_temp(func_node_temp)
2942 class ClassDefNode(StatNode, BlockNode):
2945 class PyClassDefNode(ClassDefNode):
2946 # A Python class definition.
2948 # name EncodedString Name of the class
2949 # doc string or None
2950 # body StatNode Attribute definition code
2951 # entry Symtab.Entry
2952 # scope PyClassScope
2953 # decorators [DecoratorNode] list of decorators or None
2955 # The following subnodes are constructed internally:
2957 # dict DictNode Class dictionary or Py3 namespace
2958 # classobj ClassNode Class object
2959 # target NameNode Variable to assign class object to
2961 child_attrs = ["body", "dict", "metaclass", "mkw", "bases", "classobj", "target"]
2963 py3_style_class = False # Python3 style class (bases+kwargs)
2965 def __init__(self, pos, name, bases, doc, body, decorators = None,
2966 keyword_args = None, starstar_arg = None):
2967 StatNode.__init__(self, pos)
2971 self.decorators = decorators
2973 if self.doc and Options.docstrings:
2974 doc = embed_position(self.pos, self.doc)
2975 doc_node = ExprNodes.StringNode(pos, value = doc)
2978 if keyword_args or starstar_arg:
2979 self.py3_style_class = True
2981 self.metaclass = None
2982 if keyword_args and not starstar_arg:
2983 for i, item in list(enumerate(keyword_args.key_value_pairs))[::-1]:
2984 if item.key.value == 'metaclass':
2985 if self.metaclass is not None:
2986 error(item.pos, "keyword argument 'metaclass' passed multiple times")
2987 # special case: we already know the metaclass,
2988 # so we don't need to do the "build kwargs,
2989 # find metaclass" dance at runtime
2990 self.metaclass = item.value
2991 del keyword_args.key_value_pairs[i]
2992 if starstar_arg or (keyword_args and keyword_args.key_value_pairs):
2993 self.mkw = ExprNodes.KeywordArgsNode(
2994 pos, keyword_args = keyword_args, starstar_arg = starstar_arg)
2996 self.mkw = ExprNodes.NullNode(pos)
2997 if self.metaclass is None:
2998 self.metaclass = ExprNodes.PyClassMetaclassNode(
2999 pos, mkw = self.mkw, bases = self.bases)
3000 self.dict = ExprNodes.PyClassNamespaceNode(pos, name = name,
3001 doc = doc_node, metaclass = self.metaclass, bases = self.bases,
3003 self.classobj = ExprNodes.Py3ClassNode(pos, name = name,
3004 bases = self.bases, dict = self.dict, doc = doc_node,
3005 metaclass = self.metaclass, mkw = self.mkw)
3007 self.dict = ExprNodes.DictNode(pos, key_value_pairs = [])
3008 self.metaclass = None
3011 self.classobj = ExprNodes.ClassNode(pos, name = name,
3012 bases = bases, dict = self.dict, doc = doc_node)
3013 self.target = ExprNodes.NameNode(pos, name = name)
3015 def as_cclass(self):
3017 Return this node as if it were declared as an extension class
3019 if self.py3_style_class:
3020 error(self.classobj.pos, "Python3 style class could not be represented as C class")
3022 bases = self.classobj.bases.args
3024 base_class_name = None
3025 base_class_module = None
3026 elif len(bases) == 1:
3029 from ExprNodes import AttributeNode, NameNode
3030 while isinstance(base, AttributeNode):
3031 path.insert(0, base.attribute)
3033 if isinstance(base, NameNode):
3034 path.insert(0, base.name)
3035 base_class_name = path[-1]
3037 base_class_module = u'.'.join(path[:-1])
3039 base_class_module = None
3041 error(self.classobj.bases.args.pos, "Invalid base class")
3043 error(self.classobj.bases.args.pos, "C class may only have one base class")
3046 return CClassDefNode(self.pos,
3047 visibility = 'private',
3049 class_name = self.name,
3050 base_class_module = base_class_module,
3051 base_class_name = base_class_name,
3052 decorators = self.decorators,
3057 def create_scope(self, env):
3059 while genv.is_py_class_scope or genv.is_c_class_scope:
3060 genv = genv.outer_scope
3061 cenv = self.scope = PyClassScope(name = self.name, outer_scope = genv)
3064 def analyse_declarations(self, env):
3065 self.target.analyse_target_declaration(env)
3066 cenv = self.create_scope(env)
3067 cenv.directives = env.directives
3068 cenv.class_obj_cname = self.target.entry.cname
3069 self.body.analyse_declarations(cenv)
3071 def analyse_expressions(self, env):
3072 if self.py3_style_class:
3073 self.bases.analyse_expressions(env)
3074 self.metaclass.analyse_expressions(env)
3075 self.mkw.analyse_expressions(env)
3076 self.dict.analyse_expressions(env)
3077 self.classobj.analyse_expressions(env)
3078 genv = env.global_scope()
3080 self.body.analyse_expressions(cenv)
3081 self.target.analyse_target_expression(env, self.classobj)
3083 def generate_function_definitions(self, env, code):
3084 self.generate_lambda_definitions(self.scope, code)
3085 self.body.generate_function_definitions(self.scope, code)
3087 def generate_execution_code(self, code):
3088 code.pyclass_stack.append(self)
3090 if self.py3_style_class:
3091 self.bases.generate_evaluation_code(code)
3092 self.mkw.generate_evaluation_code(code)
3093 self.metaclass.generate_evaluation_code(code)
3094 self.dict.generate_evaluation_code(code)
3095 cenv.namespace_cname = cenv.class_obj_cname = self.dict.result()
3096 self.body.generate_execution_code(code)
3097 self.classobj.generate_evaluation_code(code)
3098 cenv.namespace_cname = cenv.class_obj_cname = self.classobj.result()
3099 self.target.generate_assignment_code(self.classobj, code)
3100 self.dict.generate_disposal_code(code)
3101 self.dict.free_temps(code)
3102 if self.py3_style_class:
3103 self.mkw.generate_disposal_code(code)
3104 self.mkw.free_temps(code)
3105 self.metaclass.generate_disposal_code(code)
3106 self.metaclass.free_temps(code)
3107 self.bases.generate_disposal_code(code)
3108 self.bases.free_temps(code)
3109 code.pyclass_stack.pop()
3111 class CClassDefNode(ClassDefNode):
3112 # An extension type definition.
3114 # visibility 'private' or 'public' or 'extern'
3115 # typedef_flag boolean
3117 # module_name string or None For import of extern type objects
3118 # class_name string Unqualified name of class
3119 # as_name string or None Name to declare as in this scope
3120 # base_class_module string or None Module containing the base class
3121 # base_class_name string or None Name of the base class
3122 # objstruct_name string or None Specified C name of object struct
3123 # typeobj_name string or None Specified C name of type object
3124 # in_pxd boolean Is in a .pxd file
3125 # decorators [DecoratorNode] list of decorators or None
3126 # doc string or None
3127 # body StatNode or None
3128 # entry Symtab.Entry
3129 # base_type PyExtensionType or None
3130 # buffer_defaults_node DictNode or None Declares defaults for a buffer
3131 # buffer_defaults_pos
3133 child_attrs = ["body"]
3134 buffer_defaults_node = None
3135 buffer_defaults_pos = None
3136 typedef_flag = False
3138 objstruct_name = None
3142 def analyse_declarations(self, env):
3143 #print "CClassDefNode.analyse_declarations:", self.class_name
3144 #print "...visibility =", self.visibility
3145 #print "...module_name =", self.module_name
3148 if self.buffer_defaults_node:
3149 buffer_defaults = Buffer.analyse_buffer_options(self.buffer_defaults_pos,
3150 env, [], self.buffer_defaults_node,
3151 need_complete=False)
3153 buffer_defaults = None
3155 if env.in_cinclude and not self.objstruct_name:
3156 error(self.pos, "Object struct name specification required for "
3157 "C class defined in 'extern from' block")
3158 self.base_type = None
3159 # Now that module imports are cached, we need to
3160 # import the modules for extern classes.
3161 if self.module_name:
3163 for module in env.cimported_modules:
3164 if module.name == self.module_name:
3165 self.module = module
3166 if self.module is None:
3167 self.module = ModuleScope(self.module_name, None, env.context)
3168 self.module.has_extern_class = 1
3169 env.add_imported_module(self.module)
3171 if self.base_class_name:
3172 if self.base_class_module:
3173 base_class_scope = env.find_module(self.base_class_module, self.pos)
3175 base_class_scope = env
3176 if self.base_class_name == 'object':
3177 # extension classes are special and don't need to inherit from object
3178 if base_class_scope is None or base_class_scope.lookup('object') is None:
3179 self.base_class_name = None
3180 self.base_class_module = None
3181 base_class_scope = None
3182 if base_class_scope:
3183 base_class_entry = base_class_scope.find(self.base_class_name, self.pos)
3184 if base_class_entry:
3185 if not base_class_entry.is_type:
3186 error(self.pos, "'%s' is not a type name" % self.base_class_name)
3187 elif not base_class_entry.type.is_extension_type:
3188 error(self.pos, "'%s' is not an extension type" % self.base_class_name)
3189 elif not base_class_entry.type.is_complete():
3190 error(self.pos, "Base class '%s' of type '%s' is incomplete" % (
3191 self.base_class_name, self.class_name))
3192 elif base_class_entry.type.scope and base_class_entry.type.scope.directives and \
3193 base_class_entry.type.scope.directives['final']:
3194 error(self.pos, "Base class '%s' of type '%s' is final" % (
3195 self.base_class_name, self.class_name))
3197 self.base_type = base_class_entry.type
3198 has_body = self.body is not None
3199 if self.module_name and self.visibility != 'extern':
3200 module_path = self.module_name.split(".")
3201 home_scope = env.find_imported_module(module_path, self.pos)
3207 if self.visibility == 'extern':
3208 if self.module_name == '__builtin__' and self.class_name in Builtin.builtin_types:
3209 warning(self.pos, "%s already a builtin Cython type" % self.class_name, 1)
3211 self.entry = home_scope.declare_c_class(
3212 name = self.class_name,
3214 defining = has_body and self.in_pxd,
3215 implementing = has_body and not self.in_pxd,
3216 module_name = self.module_name,
3217 base_type = self.base_type,
3218 objstruct_cname = self.objstruct_name,
3219 typeobj_cname = self.typeobj_name,
3220 visibility = self.visibility,
3221 typedef_flag = self.typedef_flag,
3223 buffer_defaults = buffer_defaults)
3224 if home_scope is not env and self.visibility == 'extern':
3225 env.add_imported_entry(self.class_name, self.entry, self.pos)
3226 self.scope = scope = self.entry.type.scope
3227 if scope is not None:
3228 scope.directives = env.directives
3230 if self.doc and Options.docstrings:
3231 scope.doc = embed_position(self.pos, self.doc)
3234 self.body.analyse_declarations(scope)
3238 scope.implemented = 1
3239 env.allocate_vtable_names(self.entry)
3241 def analyse_expressions(self, env):
3243 scope = self.entry.type.scope
3244 self.body.analyse_expressions(scope)
3246 def generate_function_definitions(self, env, code):
3247 self.generate_lambda_definitions(self.scope, code)
3249 self.body.generate_function_definitions(
3250 self.entry.type.scope, code)
3252 def generate_execution_code(self, code):
3253 # This is needed to generate evaluation code for
3254 # default values of method arguments.
3256 self.body.generate_execution_code(code)
3258 def annotate(self, code):
3260 self.body.annotate(code)
3263 class PropertyNode(StatNode):
3264 # Definition of a property in an extension type.
3267 # doc EncodedString or None Doc string
3270 child_attrs = ["body"]
3272 def analyse_declarations(self, env):
3273 entry = env.declare_property(self.name, self.doc, self.pos)
3275 entry.scope.directives = env.directives
3276 self.body.analyse_declarations(entry.scope)
3278 def analyse_expressions(self, env):
3279 self.body.analyse_expressions(env)
3281 def generate_function_definitions(self, env, code):
3282 self.body.generate_function_definitions(env, code)
3284 def generate_execution_code(self, code):
3287 def annotate(self, code):
3288 self.body.annotate(code)
3291 class GlobalNode(StatNode):
3292 # Global variable declaration.
3298 def analyse_declarations(self, env):
3299 for name in self.names:
3300 env.declare_global(name, self.pos)
3302 def analyse_expressions(self, env):
3305 def generate_execution_code(self, code):
3309 class ExprStatNode(StatNode):
3310 # Expression used as a statement.
3314 child_attrs = ["expr"]
3316 def analyse_declarations(self, env):
3318 if isinstance(self.expr, ExprNodes.GeneralCallNode):
3319 func = self.expr.function.as_cython_attribute()
3320 if func == u'declare':
3321 args, kwds = self.expr.explicit_args_kwds()
3323 error(self.expr.pos, "Variable names must be specified.")
3324 for var, type_node in kwds.key_value_pairs:
3325 type = type_node.analyse_as_type(env)
3327 error(type_node.pos, "Unknown type")
3329 env.declare_var(var.value, type, var.pos, is_cdef = True)
3330 self.__class__ = PassStatNode
3332 def analyse_expressions(self, env):
3333 self.expr.analyse_expressions(env)
3335 def generate_execution_code(self, code):
3336 self.expr.generate_evaluation_code(code)
3337 if not self.expr.is_temp and self.expr.result():
3338 code.putln("%s;" % self.expr.result())
3339 self.expr.generate_disposal_code(code)
3340 self.expr.free_temps(code)
3342 def generate_function_definitions(self, env, code):
3343 self.expr.generate_function_definitions(env, code)
3345 def annotate(self, code):
3346 self.expr.annotate(code)
3349 class AssignmentNode(StatNode):
3350 # Abstract base class for assignment nodes.
3352 # The analyse_expressions and generate_execution_code
3353 # phases of assignments are split into two sub-phases
3354 # each, to enable all the right hand sides of a
3355 # parallel assignment to be evaluated before assigning
3356 # to any of the left hand sides.
3358 def analyse_expressions(self, env):
3359 self.analyse_types(env)
3361 # def analyse_expressions(self, env):
3362 # self.analyse_expressions_1(env)
3363 # self.analyse_expressions_2(env)
3365 def generate_execution_code(self, code):
3366 self.generate_rhs_evaluation_code(code)
3367 self.generate_assignment_code(code)
3370 class SingleAssignmentNode(AssignmentNode):
3371 # The simplest case:
3375 # lhs ExprNode Left hand side
3376 # rhs ExprNode Right hand side
3377 # first bool Is this guaranteed the first assignment to lhs?
3379 child_attrs = ["lhs", "rhs"]
3381 declaration_only = False
3383 def analyse_declarations(self, env):
3386 # handle declarations of the form x = cython.foo()
3387 if isinstance(self.rhs, ExprNodes.CallNode):
3388 func_name = self.rhs.function.as_cython_attribute()
3390 args, kwds = self.rhs.explicit_args_kwds()
3392 if func_name in ['declare', 'typedef']:
3393 if len(args) > 2 or kwds is not None:
3394 error(self.rhs.pos, "Can only declare one type at a time.")
3396 type = args[0].analyse_as_type(env)
3398 error(args[0].pos, "Unknown type")
3401 if func_name == 'declare':
3402 if isinstance(lhs, ExprNodes.NameNode):
3403 vars = [(lhs.name, lhs.pos)]
3404 elif isinstance(lhs, ExprNodes.TupleNode):
3405 vars = [(var.name, var.pos) for var in lhs.args]
3407 error(lhs.pos, "Invalid declaration")
3409 for var, pos in vars:
3410 env.declare_var(var, type, pos, is_cdef = True)
3415 self.declaration_only = True
3417 self.declaration_only = True
3418 if not isinstance(lhs, ExprNodes.NameNode):
3419 error(lhs.pos, "Invalid declaration.")
3420 env.declare_typedef(lhs.name, type, self.pos, visibility='private')
3422 elif func_name in ['struct', 'union']:
3423 self.declaration_only = True
3424 if len(args) > 0 or kwds is None:
3425 error(self.rhs.pos, "Struct or union members must be given by name.")
3428 for member, type_node in kwds.key_value_pairs:
3429 type = type_node.analyse_as_type(env)
3431 error(type_node.pos, "Unknown type")
3433 members.append((member.value, type, member.pos))
3434 if len(members) < len(kwds.key_value_pairs):
3436 if not isinstance(self.lhs, ExprNodes.NameNode):
3437 error(self.lhs.pos, "Invalid declaration.")
3438 name = self.lhs.name
3439 scope = StructOrUnionScope(name)
3440 env.declare_struct_or_union(name, func_name, scope, False, self.rhs.pos)
3441 for member, type, pos in members:
3442 scope.declare_var(member, type, pos)
3444 if self.declaration_only:
3447 self.lhs.analyse_target_declaration(env)
3449 def analyse_types(self, env, use_temp = 0):
3450 self.rhs.analyse_types(env)
3451 self.lhs.analyse_target_types(env)
3452 self.lhs.gil_assignment_check(env)
3453 self.rhs = self.rhs.coerce_to(self.lhs.type, env)
3455 self.rhs = self.rhs.coerce_to_temp(env)
3457 def generate_rhs_evaluation_code(self, code):
3458 self.rhs.generate_evaluation_code(code)
3460 def generate_assignment_code(self, code):
3461 self.lhs.generate_assignment_code(self.rhs, code)
3463 def generate_function_definitions(self, env, code):
3464 self.rhs.generate_function_definitions(env, code)
3466 def annotate(self, code):
3467 self.lhs.annotate(code)
3468 self.rhs.annotate(code)
3471 class CascadedAssignmentNode(AssignmentNode):
3472 # An assignment with multiple left hand sides:
3476 # lhs_list [ExprNode] Left hand sides
3477 # rhs ExprNode Right hand sides
3481 # coerced_rhs_list [ExprNode] RHS coerced to type of each LHS
3483 child_attrs = ["lhs_list", "rhs", "coerced_rhs_list"]
3484 coerced_rhs_list = None
3486 def analyse_declarations(self, env):
3487 for lhs in self.lhs_list:
3488 lhs.analyse_target_declaration(env)
3490 def analyse_types(self, env, use_temp = 0):
3491 self.rhs.analyse_types(env)
3492 if not self.rhs.is_simple():
3494 self.rhs = self.rhs.coerce_to_temp(env)
3496 self.rhs = self.rhs.coerce_to_simple(env)
3497 from ExprNodes import CloneNode
3498 self.coerced_rhs_list = []
3499 for lhs in self.lhs_list:
3500 lhs.analyse_target_types(env)
3501 lhs.gil_assignment_check(env)
3502 rhs = CloneNode(self.rhs)
3503 rhs = rhs.coerce_to(lhs.type, env)
3504 self.coerced_rhs_list.append(rhs)
3506 def generate_rhs_evaluation_code(self, code):
3507 self.rhs.generate_evaluation_code(code)
3509 def generate_assignment_code(self, code):
3510 for i in range(len(self.lhs_list)):
3511 lhs = self.lhs_list[i]
3512 rhs = self.coerced_rhs_list[i]
3513 rhs.generate_evaluation_code(code)
3514 lhs.generate_assignment_code(rhs, code)
3515 # Assignment has disposed of the cloned RHS
3516 self.rhs.generate_disposal_code(code)
3517 self.rhs.free_temps(code)
3519 def generate_function_definitions(self, env, code):
3520 self.rhs.generate_function_definitions(env, code)
3522 def annotate(self, code):
3523 for i in range(len(self.lhs_list)):
3524 lhs = self.lhs_list[i].annotate(code)
3525 rhs = self.coerced_rhs_list[i].annotate(code)
3526 self.rhs.annotate(code)
3529 class ParallelAssignmentNode(AssignmentNode):
3530 # A combined packing/unpacking assignment:
3534 # This has been rearranged by the parser into
3536 # a = d ; b = e ; c = f
3538 # but we must evaluate all the right hand sides
3539 # before assigning to any of the left hand sides.
3541 # stats [AssignmentNode] The constituent assignments
3543 child_attrs = ["stats"]
3545 def analyse_declarations(self, env):
3546 for stat in self.stats:
3547 stat.analyse_declarations(env)
3549 def analyse_expressions(self, env):
3550 for stat in self.stats:
3551 stat.analyse_types(env, use_temp = 1)
3553 # def analyse_expressions(self, env):
3554 # for stat in self.stats:
3555 # stat.analyse_expressions_1(env, use_temp = 1)
3556 # for stat in self.stats:
3557 # stat.analyse_expressions_2(env)
3559 def generate_execution_code(self, code):
3560 for stat in self.stats:
3561 stat.generate_rhs_evaluation_code(code)
3562 for stat in self.stats:
3563 stat.generate_assignment_code(code)
3565 def generate_function_definitions(self, env, code):
3566 for stat in self.stats:
3567 stat.generate_function_definitions(env, code)
3569 def annotate(self, code):
3570 for stat in self.stats:
3574 class InPlaceAssignmentNode(AssignmentNode):
3575 # An in place arithmetic operand:
3581 # lhs ExprNode Left hand side
3582 # rhs ExprNode Right hand side
3583 # op char one of "+-*/%^&|"
3584 # dup (ExprNode) copy of lhs used for operation (auto-generated)
3586 # This code is a bit tricky because in order to obey Python
3587 # semantics the sub-expressions (e.g. indices) of the lhs must
3588 # not be evaluated twice. So we must re-use the values calculated
3589 # in evaluation phase for the assignment phase as well.
3590 # Fortunately, the type of the lhs node is fairly constrained
3591 # (it must be a NameNode, AttributeNode, or IndexNode).
3593 child_attrs = ["lhs", "rhs"]
3595 def analyse_declarations(self, env):
3596 self.lhs.analyse_target_declaration(env)
3598 def analyse_types(self, env):
3599 self.rhs.analyse_types(env)
3600 self.lhs.analyse_target_types(env)
3602 def generate_execution_code(self, code):
3604 self.rhs.generate_evaluation_code(code)
3605 self.lhs.generate_subexpr_evaluation_code(code)
3606 c_op = self.operator
3610 error(self.pos, "No C inplace power operator")
3611 if isinstance(self.lhs, ExprNodes.IndexNode) and self.lhs.is_buffer_access:
3612 if self.lhs.type.is_pyobject:
3613 error(self.pos, "In-place operators not allowed on object buffers in this release.")
3614 if c_op in ('/', '%') and self.lhs.type.is_int and not code.directives['cdivision']:
3615 error(self.pos, "In-place non-c divide operators not allowed on int buffers.")
3616 self.lhs.generate_buffer_setitem_code(self.rhs, code, c_op)
3619 # TODO: make sure overload is declared
3620 code.putln("%s %s= %s;" % (self.lhs.result(), c_op, self.rhs.result()))
3621 self.lhs.generate_subexpr_disposal_code(code)
3622 self.lhs.free_subexpr_temps(code)
3623 self.rhs.generate_disposal_code(code)
3624 self.rhs.free_temps(code)
3626 def annotate(self, code):
3627 self.lhs.annotate(code)
3628 self.rhs.annotate(code)
3630 def create_binop_node(self):
3632 return ExprNodes.binop_node(self.pos, self.operator, self.lhs, self.rhs)
3635 class PrintStatNode(StatNode):
3638 # arg_tuple TupleNode
3639 # stream ExprNode or None (stdout)
3640 # append_newline boolean
3642 child_attrs = ["arg_tuple", "stream"]
3644 def analyse_expressions(self, env):
3646 self.stream.analyse_expressions(env)
3647 self.stream = self.stream.coerce_to_pyobject(env)
3648 self.arg_tuple.analyse_expressions(env)
3649 self.arg_tuple = self.arg_tuple.coerce_to_pyobject(env)
3650 env.use_utility_code(printing_utility_code)
3651 if len(self.arg_tuple.args) == 1 and self.append_newline:
3652 env.use_utility_code(printing_one_utility_code)
3654 nogil_check = Node.gil_error
3655 gil_message = "Python print statement"
3657 def generate_execution_code(self, code):
3659 self.stream.generate_evaluation_code(code)
3660 stream_result = self.stream.py_result()
3663 if len(self.arg_tuple.args) == 1 and self.append_newline:
3664 arg = self.arg_tuple.args[0]
3665 arg.generate_evaluation_code(code)
3668 "if (__Pyx_PrintOne(%s, %s) < 0) %s" % (
3671 code.error_goto(self.pos)))
3672 arg.generate_disposal_code(code)
3673 arg.free_temps(code)
3675 self.arg_tuple.generate_evaluation_code(code)
3677 "if (__Pyx_Print(%s, %s, %d) < 0) %s" % (
3679 self.arg_tuple.py_result(),
3680 self.append_newline,
3681 code.error_goto(self.pos)))
3682 self.arg_tuple.generate_disposal_code(code)
3683 self.arg_tuple.free_temps(code)
3686 self.stream.generate_disposal_code(code)
3687 self.stream.free_temps(code)
3689 def generate_function_definitions(self, env, code):
3691 self.stream.generate_function_definitions(env, code)
3692 self.arg_tuple.generate_function_definitions(env, code)
3694 def annotate(self, code):
3696 self.stream.annotate(code)
3697 self.arg_tuple.annotate(code)
3700 class ExecStatNode(StatNode):
3705 child_attrs = ["args"]
3707 def analyse_expressions(self, env):
3708 for i, arg in enumerate(self.args):
3709 arg.analyse_expressions(env)
3710 arg = arg.coerce_to_pyobject(env)
3712 env.use_utility_code(Builtin.pyexec_utility_code)
3714 nogil_check = Node.gil_error
3715 gil_message = "Python exec statement"
3717 def generate_execution_code(self, code):
3719 for arg in self.args:
3720 arg.generate_evaluation_code(code)
3721 args.append( arg.py_result() )
3722 args = tuple(args + ['0', '0'][:3-len(args)])
3723 temp_result = code.funcstate.allocate_temp(PyrexTypes.py_object_type, manage_ref=True)
3724 code.putln("%s = __Pyx_PyRun(%s, %s, %s);" % (
3725 (temp_result,) + args))
3726 for arg in self.args:
3727 arg.generate_disposal_code(code)
3728 arg.free_temps(code)
3730 code.error_goto_if_null(temp_result, self.pos))
3731 code.put_gotref(temp_result)
3732 code.put_decref_clear(temp_result, py_object_type)
3733 code.funcstate.release_temp(temp_result)
3735 def annotate(self, code):
3736 for arg in self.args:
3740 class DelStatNode(StatNode):
3745 child_attrs = ["args"]
3747 def analyse_declarations(self, env):
3748 for arg in self.args:
3749 arg.analyse_target_declaration(env)
3751 def analyse_expressions(self, env):
3752 for arg in self.args:
3753 arg.analyse_target_expression(env, None)
3754 if arg.type.is_pyobject:
3756 elif arg.type.is_ptr and arg.type.base_type.is_cpp_class:
3758 elif arg.type.is_cpp_class:
3759 error(arg.pos, "Deletion of non-heap C++ object")
3761 error(arg.pos, "Deletion of non-Python, non-C++ object")
3762 #arg.release_target_temp(env)
3764 def nogil_check(self, env):
3765 for arg in self.args:
3766 if arg.type.is_pyobject:
3769 gil_message = "Deleting Python object"
3771 def generate_execution_code(self, code):
3772 for arg in self.args:
3773 if arg.type.is_pyobject:
3774 arg.generate_deletion_code(code)
3775 elif arg.type.is_ptr and arg.type.base_type.is_cpp_class:
3776 arg.generate_result_code(code)
3777 code.putln("delete %s;" % arg.result())
3778 # else error reported earlier
3780 def annotate(self, code):
3781 for arg in self.args:
3785 class PassStatNode(StatNode):
3790 def analyse_expressions(self, env):
3793 def generate_execution_code(self, code):
3797 class BreakStatNode(StatNode):
3801 def analyse_expressions(self, env):
3804 def generate_execution_code(self, code):
3805 if not code.break_label:
3806 error(self.pos, "break statement not inside loop")
3808 code.put_goto(code.break_label)
3811 class ContinueStatNode(StatNode):
3815 def analyse_expressions(self, env):
3818 def generate_execution_code(self, code):
3819 if code.funcstate.in_try_finally:
3820 error(self.pos, "continue statement inside try of try...finally")
3821 elif not code.continue_label:
3822 error(self.pos, "continue statement not inside loop")
3824 code.put_goto(code.continue_label)
3827 class ReturnStatNode(StatNode):
3830 # value ExprNode or None
3831 # return_type PyrexType
3833 child_attrs = ["value"]
3835 def analyse_expressions(self, env):
3836 return_type = env.return_type
3837 self.return_type = return_type
3839 error(self.pos, "Return not inside a function body")
3842 self.value.analyse_types(env)
3843 if return_type.is_void or return_type.is_returncode:
3844 error(self.value.pos,
3845 "Return with value in void function")
3847 self.value = self.value.coerce_to(env.return_type, env)
3849 if (not return_type.is_void
3850 and not return_type.is_pyobject
3851 and not return_type.is_returncode):
3852 error(self.pos, "Return value required")
3854 def nogil_check(self, env):
3855 if self.return_type.is_pyobject:
3858 gil_message = "Returning Python object"
3860 def generate_execution_code(self, code):
3861 code.mark_pos(self.pos)
3862 if not self.return_type:
3863 # error reported earlier
3865 if self.return_type.is_pyobject:
3866 code.put_xdecref(Naming.retval_cname,
3869 self.value.generate_evaluation_code(code)
3870 self.value.make_owned_reference(code)
3873 Naming.retval_cname,
3874 self.value.result_as(self.return_type)))
3875 self.value.generate_post_assignment_code(code)
3876 self.value.free_temps(code)
3878 if self.return_type.is_pyobject:
3879 code.put_init_to_py_none(Naming.retval_cname, self.return_type)
3880 elif self.return_type.is_returncode:
3883 Naming.retval_cname,
3884 self.return_type.default_value))
3885 for cname, type in code.funcstate.temps_holding_reference():
3886 code.put_decref_clear(cname, type)
3887 code.put_goto(code.return_label)
3889 def generate_function_definitions(self, env, code):
3890 if self.value is not None:
3891 self.value.generate_function_definitions(env, code)
3893 def annotate(self, code):
3895 self.value.annotate(code)
3898 class RaiseStatNode(StatNode):
3901 # exc_type ExprNode or None
3902 # exc_value ExprNode or None
3903 # exc_tb ExprNode or None
3905 child_attrs = ["exc_type", "exc_value", "exc_tb"]
3907 def analyse_expressions(self, env):
3909 self.exc_type.analyse_types(env)
3910 self.exc_type = self.exc_type.coerce_to_pyobject(env)
3912 self.exc_value.analyse_types(env)
3913 self.exc_value = self.exc_value.coerce_to_pyobject(env)
3915 self.exc_tb.analyse_types(env)
3916 self.exc_tb = self.exc_tb.coerce_to_pyobject(env)
3917 env.use_utility_code(raise_utility_code)
3919 nogil_check = Node.gil_error
3920 gil_message = "Raising exception"
3922 def generate_execution_code(self, code):
3924 self.exc_type.generate_evaluation_code(code)
3925 type_code = self.exc_type.py_result()
3929 self.exc_value.generate_evaluation_code(code)
3930 value_code = self.exc_value.py_result()
3934 self.exc_tb.generate_evaluation_code(code)
3935 tb_code = self.exc_tb.py_result()
3939 "__Pyx_Raise(%s, %s, %s);" % (
3943 for obj in (self.exc_type, self.exc_value, self.exc_tb):
3945 obj.generate_disposal_code(code)
3946 obj.free_temps(code)
3948 code.error_goto(self.pos))
3950 def generate_function_definitions(self, env, code):
3951 if self.exc_type is not None:
3952 self.exc_type.generate_function_definitions(env, code)
3953 if self.exc_value is not None:
3954 self.exc_value.generate_function_definitions(env, code)
3955 if self.exc_tb is not None:
3956 self.exc_tb.generate_function_definitions(env, code)
3958 def annotate(self, code):
3960 self.exc_type.annotate(code)
3962 self.exc_value.annotate(code)
3964 self.exc_tb.annotate(code)
3967 class ReraiseStatNode(StatNode):
3971 def analyse_expressions(self, env):
3972 env.use_utility_code(restore_exception_utility_code)
3974 nogil_check = Node.gil_error
3975 gil_message = "Raising exception"
3977 def generate_execution_code(self, code):
3978 vars = code.funcstate.exc_vars
3980 for varname in vars:
3981 code.put_giveref(varname)
3982 code.putln("__Pyx_ErrRestore(%s, %s, %s);" % tuple(vars))
3983 for varname in vars:
3984 code.put("%s = 0; " % varname)
3986 code.putln(code.error_goto(self.pos))
3988 error(self.pos, "Reraise not inside except clause")
3991 class AssertStatNode(StatNode):
3995 # value ExprNode or None
3997 child_attrs = ["cond", "value"]
3999 def analyse_expressions(self, env):
4000 self.cond = self.cond.analyse_boolean_expression(env)
4002 self.value.analyse_types(env)
4003 self.value = self.value.coerce_to_pyobject(env)
4005 nogil_check = Node.gil_error
4006 gil_message = "Raising exception"
4008 def generate_execution_code(self, code):
4009 code.putln("#ifndef CYTHON_WITHOUT_ASSERTIONS")
4010 self.cond.generate_evaluation_code(code)
4012 "if (unlikely(!%s)) {" %
4015 self.value.generate_evaluation_code(code)
4017 "PyErr_SetObject(PyExc_AssertionError, %s);" %
4018 self.value.py_result())
4019 self.value.generate_disposal_code(code)
4020 self.value.free_temps(code)
4023 "PyErr_SetNone(PyExc_AssertionError);")
4025 code.error_goto(self.pos))
4028 self.cond.generate_disposal_code(code)
4029 self.cond.free_temps(code)
4030 code.putln("#endif")
4032 def generate_function_definitions(self, env, code):
4033 self.cond.generate_function_definitions(env, code)
4034 if self.value is not None:
4035 self.value.generate_function_definitions(env, code)
4037 def annotate(self, code):
4038 self.cond.annotate(code)
4040 self.value.annotate(code)
4043 class IfStatNode(StatNode):
4046 # if_clauses [IfClauseNode]
4047 # else_clause StatNode or None
4049 child_attrs = ["if_clauses", "else_clause"]
4051 def analyse_control_flow(self, env):
4052 env.start_branching(self.pos)
4053 for if_clause in self.if_clauses:
4054 if_clause.analyse_control_flow(env)
4055 env.next_branch(if_clause.end_pos())
4056 if self.else_clause:
4057 self.else_clause.analyse_control_flow(env)
4058 env.finish_branching(self.end_pos())
4060 def analyse_declarations(self, env):
4061 for if_clause in self.if_clauses:
4062 if_clause.analyse_declarations(env)
4063 if self.else_clause:
4064 self.else_clause.analyse_declarations(env)
4066 def analyse_expressions(self, env):
4067 for if_clause in self.if_clauses:
4068 if_clause.analyse_expressions(env)
4069 if self.else_clause:
4070 self.else_clause.analyse_expressions(env)
4072 def generate_execution_code(self, code):
4073 code.mark_pos(self.pos)
4074 end_label = code.new_label()
4075 for if_clause in self.if_clauses:
4076 if_clause.generate_execution_code(code, end_label)
4077 if self.else_clause:
4078 code.putln("/*else*/ {")
4079 self.else_clause.generate_execution_code(code)
4081 code.put_label(end_label)
4083 def generate_function_definitions(self, env, code):
4084 for clause in self.if_clauses:
4085 clause.generate_function_definitions(env, code)
4086 if self.else_clause is not None:
4087 self.else_clause.generate_function_definitions(env, code)
4089 def annotate(self, code):
4090 for if_clause in self.if_clauses:
4091 if_clause.annotate(code)
4092 if self.else_clause:
4093 self.else_clause.annotate(code)
4096 class IfClauseNode(Node):
4097 # if or elif clause in an if statement
4099 # condition ExprNode
4102 child_attrs = ["condition", "body"]
4104 def analyse_control_flow(self, env):
4105 self.body.analyse_control_flow(env)
4107 def analyse_declarations(self, env):
4108 self.body.analyse_declarations(env)
4110 def analyse_expressions(self, env):
4112 self.condition.analyse_temp_boolean_expression(env)
4113 self.body.analyse_expressions(env)
4115 def get_constant_condition_result(self):
4116 if self.condition.has_constant_result():
4117 return bool(self.condition.constant_result)
4121 def generate_execution_code(self, code, end_label):
4122 self.condition.generate_evaluation_code(code)
4125 self.condition.result())
4126 self.condition.generate_disposal_code(code)
4127 self.condition.free_temps(code)
4128 self.body.generate_execution_code(code)
4129 code.put_goto(end_label)
4132 def generate_function_definitions(self, env, code):
4133 self.condition.generate_function_definitions(env, code)
4134 self.body.generate_function_definitions(env, code)
4136 def annotate(self, code):
4137 self.condition.annotate(code)
4138 self.body.annotate(code)
4141 class SwitchCaseNode(StatNode):
4142 # Generated in the optimization of an if-elif-else node
4144 # conditions [ExprNode]
4147 child_attrs = ['conditions', 'body']
4149 def generate_execution_code(self, code):
4150 for cond in self.conditions:
4151 code.mark_pos(cond.pos)
4152 cond.generate_evaluation_code(code)
4153 code.putln("case %s:" % cond.result())
4154 self.body.generate_execution_code(code)
4155 code.putln("break;")
4157 def generate_function_definitions(self, env, code):
4158 for cond in self.conditions:
4159 cond.generate_function_definitions(env, code)
4160 self.body.generate_function_definitions(env, code)
4162 def annotate(self, code):
4163 for cond in self.conditions:
4165 self.body.annotate(code)
4167 class SwitchStatNode(StatNode):
4168 # Generated in the optimization of an if-elif-else node
4171 # cases [SwitchCaseNode]
4172 # else_clause StatNode or None
4174 child_attrs = ['test', 'cases', 'else_clause']
4176 def generate_execution_code(self, code):
4177 self.test.generate_evaluation_code(code)
4178 code.putln("switch (%s) {" % self.test.result())
4179 for case in self.cases:
4180 case.generate_execution_code(code)
4181 if self.else_clause is not None:
4182 code.putln("default:")
4183 self.else_clause.generate_execution_code(code)
4184 code.putln("break;")
4187 def generate_function_definitions(self, env, code):
4188 self.test.generate_function_definitions(env, code)
4189 for case in self.cases:
4190 case.generate_function_definitions(env, code)
4191 if self.else_clause is not None:
4192 self.else_clause.generate_function_definitions(env, code)
4194 def annotate(self, code):
4195 self.test.annotate(code)
4196 for case in self.cases:
4198 if self.else_clause is not None:
4199 self.else_clause.annotate(code)
4201 class LoopNode(object):
4203 def analyse_control_flow(self, env):
4204 env.start_branching(self.pos)
4205 self.body.analyse_control_flow(env)
4206 env.next_branch(self.body.end_pos())
4207 if self.else_clause:
4208 self.else_clause.analyse_control_flow(env)
4209 env.finish_branching(self.end_pos())
4212 class WhileStatNode(LoopNode, StatNode):
4215 # condition ExprNode
4217 # else_clause StatNode
4219 child_attrs = ["condition", "body", "else_clause"]
4221 def analyse_declarations(self, env):
4222 self.body.analyse_declarations(env)
4223 if self.else_clause:
4224 self.else_clause.analyse_declarations(env)
4226 def analyse_expressions(self, env):
4228 self.condition.analyse_temp_boolean_expression(env)
4229 self.body.analyse_expressions(env)
4230 if self.else_clause:
4231 self.else_clause.analyse_expressions(env)
4233 def generate_execution_code(self, code):
4234 old_loop_labels = code.new_loop_labels()
4237 self.condition.generate_evaluation_code(code)
4238 self.condition.generate_disposal_code(code)
4241 self.condition.result())
4242 self.condition.free_temps(code)
4243 self.body.generate_execution_code(code)
4244 code.put_label(code.continue_label)
4246 break_label = code.break_label
4247 code.set_loop_labels(old_loop_labels)
4248 if self.else_clause:
4249 code.putln("/*else*/ {")
4250 self.else_clause.generate_execution_code(code)
4252 code.put_label(break_label)
4254 def generate_function_definitions(self, env, code):
4255 self.condition.generate_function_definitions(env, code)
4256 self.body.generate_function_definitions(env, code)
4257 if self.else_clause is not None:
4258 self.else_clause.generate_function_definitions(env, code)
4260 def annotate(self, code):
4261 self.condition.annotate(code)
4262 self.body.annotate(code)
4263 if self.else_clause:
4264 self.else_clause.annotate(code)
4267 def ForStatNode(pos, **kw):
4268 if 'iterator' in kw:
4269 return ForInStatNode(pos, **kw)
4271 return ForFromStatNode(pos, **kw)
4273 class ForInStatNode(LoopNode, StatNode):
4277 # iterator IteratorNode
4279 # else_clause StatNode
4280 # item NextNode used internally
4282 child_attrs = ["target", "iterator", "body", "else_clause"]
4285 def analyse_declarations(self, env):
4286 self.target.analyse_target_declaration(env)
4287 self.body.analyse_declarations(env)
4288 if self.else_clause:
4289 self.else_clause.analyse_declarations(env)
4291 def analyse_expressions(self, env):
4293 self.target.analyse_target_types(env)
4294 self.iterator.analyse_expressions(env)
4295 self.item = ExprNodes.NextNode(self.iterator, env)
4296 self.item = self.item.coerce_to(self.target.type, env)
4297 self.body.analyse_expressions(env)
4298 if self.else_clause:
4299 self.else_clause.analyse_expressions(env)
4301 def generate_execution_code(self, code):
4302 old_loop_labels = code.new_loop_labels()
4303 self.iterator.allocate_counter_temp(code)
4304 self.iterator.generate_evaluation_code(code)
4307 self.item.generate_evaluation_code(code)
4308 self.target.generate_assignment_code(self.item, code)
4309 self.body.generate_execution_code(code)
4310 code.put_label(code.continue_label)
4313 break_label = code.break_label
4314 code.set_loop_labels(old_loop_labels)
4316 if self.else_clause:
4317 # in nested loops, the 'else' block can contain a
4318 # 'continue' statement for the outer loop, but we may need
4319 # to generate cleanup code before taking that path, so we
4321 orig_continue_label = code.continue_label
4322 code.continue_label = code.new_label('outer_continue')
4324 code.putln("/*else*/ {")
4325 self.else_clause.generate_execution_code(code)
4328 if code.label_used(code.continue_label):
4329 code.put_goto(break_label)
4330 code.put_label(code.continue_label)
4331 self.iterator.generate_disposal_code(code)
4332 code.put_goto(orig_continue_label)
4333 code.set_loop_labels(old_loop_labels)
4335 if code.label_used(break_label):
4336 code.put_label(break_label)
4337 self.iterator.release_counter_temp(code)
4338 self.iterator.generate_disposal_code(code)
4339 self.iterator.free_temps(code)
4341 def generate_function_definitions(self, env, code):
4342 self.target.generate_function_definitions(env, code)
4343 self.iterator.generate_function_definitions(env, code)
4344 self.body.generate_function_definitions(env, code)
4345 if self.else_clause is not None:
4346 self.else_clause.generate_function_definitions(env, code)
4348 def annotate(self, code):
4349 self.target.annotate(code)
4350 self.iterator.annotate(code)
4351 self.body.annotate(code)
4352 if self.else_clause:
4353 self.else_clause.annotate(code)
4354 self.item.annotate(code)
4357 class ForFromStatNode(LoopNode, StatNode):
4358 # for name from expr rel name rel expr
4365 # step ExprNode or None
4367 # else_clause StatNode or None
4373 # loopvar_node ExprNode (usually a NameNode or temp node)
4374 # py_loopvar_node PyTempNode or None
4375 child_attrs = ["target", "bound1", "bound2", "step", "body", "else_clause"]
4377 is_py_target = False
4379 py_loopvar_node = None
4382 gil_message = "For-loop using object bounds or target"
4384 def nogil_check(self, env):
4385 for x in (self.target, self.bound1, self.bound2):
4386 if x.type.is_pyobject:
4389 def analyse_declarations(self, env):
4390 self.target.analyse_target_declaration(env)
4391 self.body.analyse_declarations(env)
4392 if self.else_clause:
4393 self.else_clause.analyse_declarations(env)
4395 def analyse_expressions(self, env):
4397 self.target.analyse_target_types(env)
4398 self.bound1.analyse_types(env)
4399 self.bound2.analyse_types(env)
4400 if self.step is not None:
4401 if isinstance(self.step, ExprNodes.UnaryMinusNode):
4402 warning(self.step.pos, "Probable infinite loop in for-from-by statment. Consider switching the directions of the relations.", 2)
4403 self.step.analyse_types(env)
4405 target_type = self.target.type
4406 if self.target.type.is_numeric:
4407 loop_type = self.target.type
4409 loop_type = PyrexTypes.c_int_type
4410 if not self.bound1.type.is_pyobject:
4411 loop_type = PyrexTypes.widest_numeric_type(loop_type, self.bound1.type)
4412 if not self.bound2.type.is_pyobject:
4413 loop_type = PyrexTypes.widest_numeric_type(loop_type, self.bound2.type)
4414 if self.step is not None and not self.step.type.is_pyobject:
4415 loop_type = PyrexTypes.widest_numeric_type(loop_type, self.step.type)
4416 self.bound1 = self.bound1.coerce_to(loop_type, env)
4417 self.bound2 = self.bound2.coerce_to(loop_type, env)
4418 if not self.bound2.is_literal:
4419 self.bound2 = self.bound2.coerce_to_temp(env)
4420 if self.step is not None:
4421 self.step = self.step.coerce_to(loop_type, env)
4422 if not self.step.is_literal:
4423 self.step = self.step.coerce_to_temp(env)
4425 target_type = self.target.type
4426 if not (target_type.is_pyobject or target_type.is_numeric):
4427 error(self.target.pos,
4428 "for-from loop variable must be c numeric type or Python object")
4429 if target_type.is_numeric:
4430 self.is_py_target = False
4431 if isinstance(self.target, ExprNodes.IndexNode) and self.target.is_buffer_access:
4432 raise error(self.pos, "Buffer indexing not allowed as for loop target.")
4433 self.loopvar_node = self.target
4434 self.py_loopvar_node = None
4436 self.is_py_target = True
4437 c_loopvar_node = ExprNodes.TempNode(self.pos, loop_type, env)
4438 self.loopvar_node = c_loopvar_node
4439 self.py_loopvar_node = \
4440 ExprNodes.CloneNode(c_loopvar_node).coerce_to_pyobject(env)
4441 self.body.analyse_expressions(env)
4442 if self.else_clause:
4443 self.else_clause.analyse_expressions(env)
4445 def generate_execution_code(self, code):
4446 old_loop_labels = code.new_loop_labels()
4447 from_range = self.from_range
4448 self.bound1.generate_evaluation_code(code)
4449 self.bound2.generate_evaluation_code(code)
4450 offset, incop = self.relation_table[self.relation1]
4451 if self.step is not None:
4452 self.step.generate_evaluation_code(code)
4453 step = self.step.result()
4454 incop = "%s=%s" % (incop[0], step)
4456 if isinstance(self.loopvar_node, ExprNodes.TempNode):
4457 self.loopvar_node.allocate(code)
4458 if isinstance(self.py_loopvar_node, ExprNodes.TempNode):
4459 self.py_loopvar_node.allocate(code)
4461 loopvar_name = code.funcstate.allocate_temp(self.target.type, False)
4463 loopvar_name = self.loopvar_node.result()
4465 "for (%s = %s%s; %s %s %s; %s%s) {" % (
4467 self.bound1.result(), offset,
4468 loopvar_name, self.relation2, self.bound2.result(),
4469 loopvar_name, incop))
4470 if self.py_loopvar_node:
4471 self.py_loopvar_node.generate_evaluation_code(code)
4472 self.target.generate_assignment_code(self.py_loopvar_node, code)
4474 code.putln("%s = %s;" % (
4475 self.target.result(), loopvar_name))
4476 self.body.generate_execution_code(code)
4477 code.put_label(code.continue_label)
4478 if self.py_loopvar_node:
4479 # This mess is to make for..from loops with python targets behave
4480 # exactly like those with C targets with regards to re-assignment
4481 # of the loop variable.
4483 if self.target.entry.is_pyglobal:
4484 # We know target is a NameNode, this is the only ugly case.
4485 target_node = ExprNodes.PyTempNode(self.target.pos, None)
4486 target_node.allocate(code)
4487 interned_cname = code.intern_identifier(self.target.entry.name)
4488 code.globalstate.use_utility_code(ExprNodes.get_name_interned_utility_code)
4489 code.putln("%s = __Pyx_GetName(%s, %s); %s" % (
4490 target_node.result(),
4491 Naming.module_cname,
4493 code.error_goto_if_null(target_node.result(), self.target.pos)))
4494 code.put_gotref(target_node.result())
4496 target_node = self.target
4497 from_py_node = ExprNodes.CoerceFromPyTypeNode(self.loopvar_node.type, target_node, None)
4498 from_py_node.temp_code = loopvar_name
4499 from_py_node.generate_result_code(code)
4500 if self.target.entry.is_pyglobal:
4501 code.put_decref(target_node.result(), target_node.type)
4502 target_node.release(code)
4504 if self.py_loopvar_node:
4505 # This is potentially wasteful, but we don't want the semantics to
4506 # depend on whether or not the loop is a python type.
4507 self.py_loopvar_node.generate_evaluation_code(code)
4508 self.target.generate_assignment_code(self.py_loopvar_node, code)
4510 code.funcstate.release_temp(loopvar_name)
4511 break_label = code.break_label
4512 code.set_loop_labels(old_loop_labels)
4513 if self.else_clause:
4514 code.putln("/*else*/ {")
4515 self.else_clause.generate_execution_code(code)
4517 code.put_label(break_label)
4518 self.bound1.generate_disposal_code(code)
4519 self.bound1.free_temps(code)
4520 self.bound2.generate_disposal_code(code)
4521 self.bound2.free_temps(code)
4522 if isinstance(self.loopvar_node, ExprNodes.TempNode):
4523 self.loopvar_node.release(code)
4524 if isinstance(self.py_loopvar_node, ExprNodes.TempNode):
4525 self.py_loopvar_node.release(code)
4526 if self.step is not None:
4527 self.step.generate_disposal_code(code)
4528 self.step.free_temps(code)
4531 # {relop : (initial offset, increment op)}
4538 def generate_function_definitions(self, env, code):
4539 self.target.generate_function_definitions(env, code)
4540 self.bound1.generate_function_definitions(env, code)
4541 self.bound2.generate_function_definitions(env, code)
4542 if self.step is not None:
4543 self.step.generate_function_definitions(env, code)
4544 self.body.generate_function_definitions(env, code)
4545 if self.else_clause is not None:
4546 self.else_clause.generate_function_definitions(env, code)
4548 def annotate(self, code):
4549 self.target.annotate(code)
4550 self.bound1.annotate(code)
4551 self.bound2.annotate(code)
4553 self.step.annotate(code)
4554 self.body.annotate(code)
4555 if self.else_clause:
4556 self.else_clause.annotate(code)
4559 class WithStatNode(StatNode):
4561 Represents a Python with statement.
4563 This is only used at parse tree level; and is not present in
4564 analysis or generation phases.
4566 # manager The with statement manager object
4567 # target Node (lhs expression)
4569 child_attrs = ["manager", "target", "body"]
4571 class TryExceptStatNode(StatNode):
4572 # try .. except statement
4575 # except_clauses [ExceptClauseNode]
4576 # else_clause StatNode or None
4578 child_attrs = ["body", "except_clauses", "else_clause"]
4580 def analyse_control_flow(self, env):
4581 env.start_branching(self.pos)
4582 self.body.analyse_control_flow(env)
4583 successful_try = env.control_flow # grab this for later
4584 env.next_branch(self.body.end_pos())
4585 env.finish_branching(self.body.end_pos())
4587 env.start_branching(self.except_clauses[0].pos)
4588 for except_clause in self.except_clauses:
4589 except_clause.analyse_control_flow(env)
4590 env.next_branch(except_clause.end_pos())
4592 # the else cause it executed only when the try clause finishes
4593 env.control_flow.incoming = successful_try
4594 if self.else_clause:
4595 self.else_clause.analyse_control_flow(env)
4596 env.finish_branching(self.end_pos())
4598 def analyse_declarations(self, env):
4599 self.body.analyse_declarations(env)
4600 for except_clause in self.except_clauses:
4601 except_clause.analyse_declarations(env)
4602 if self.else_clause:
4603 self.else_clause.analyse_declarations(env)
4604 env.use_utility_code(reset_exception_utility_code)
4606 def analyse_expressions(self, env):
4607 self.body.analyse_expressions(env)
4608 default_clause_seen = 0
4609 for except_clause in self.except_clauses:
4610 except_clause.analyse_expressions(env)
4611 if default_clause_seen:
4612 error(except_clause.pos, "default 'except:' must be last")
4613 if not except_clause.pattern:
4614 default_clause_seen = 1
4615 self.has_default_clause = default_clause_seen
4616 if self.else_clause:
4617 self.else_clause.analyse_expressions(env)
4619 nogil_check = Node.gil_error
4620 gil_message = "Try-except statement"
4622 def generate_execution_code(self, code):
4623 old_return_label = code.return_label
4624 old_break_label = code.break_label
4625 old_continue_label = code.continue_label
4626 old_error_label = code.new_error_label()
4627 our_error_label = code.error_label
4628 except_end_label = code.new_label('exception_handled')
4629 except_error_label = code.new_label('except_error')
4630 except_return_label = code.new_label('except_return')
4631 try_return_label = code.new_label('try_return')
4632 try_break_label = code.new_label('try_break')
4633 try_continue_label = code.new_label('try_continue')
4634 try_end_label = code.new_label('try_end')
4637 code.putln("PyObject %s;" %
4638 ', '.join(['*%s' % var for var in Naming.exc_save_vars]))
4639 code.putln("__Pyx_ExceptionSave(%s);" %
4640 ', '.join(['&%s' % var for var in Naming.exc_save_vars]))
4641 for var in Naming.exc_save_vars:
4642 code.put_xgotref(var)
4645 code.return_label = try_return_label
4646 code.break_label = try_break_label
4647 code.continue_label = try_continue_label
4648 self.body.generate_execution_code(code)
4651 temps_to_clean_up = code.funcstate.all_free_managed_temps()
4652 code.error_label = except_error_label
4653 code.return_label = except_return_label
4654 if self.else_clause:
4657 self.else_clause.generate_execution_code(code)
4660 for var in Naming.exc_save_vars:
4661 code.put_xdecref_clear(var, py_object_type)
4662 code.put_goto(try_end_label)
4663 if code.label_used(try_return_label):
4664 code.put_label(try_return_label)
4665 for var in Naming.exc_save_vars: code.put_xgiveref(var)
4666 code.putln("__Pyx_ExceptionReset(%s);" %
4667 ', '.join(Naming.exc_save_vars))
4668 code.put_goto(old_return_label)
4669 code.put_label(our_error_label)
4670 for temp_name, type in temps_to_clean_up:
4671 code.put_xdecref_clear(temp_name, type)
4672 for except_clause in self.except_clauses:
4673 except_clause.generate_handling_code(code, except_end_label)
4675 error_label_used = code.label_used(except_error_label)
4676 if error_label_used or not self.has_default_clause:
4677 if error_label_used:
4678 code.put_label(except_error_label)
4679 for var in Naming.exc_save_vars: code.put_xgiveref(var)
4680 code.putln("__Pyx_ExceptionReset(%s);" %
4681 ', '.join(Naming.exc_save_vars))
4682 code.put_goto(old_error_label)
4684 for exit_label, old_label in zip(
4685 [try_break_label, try_continue_label, except_return_label],
4686 [old_break_label, old_continue_label, old_return_label]):
4688 if code.label_used(exit_label):
4689 code.put_label(exit_label)
4690 for var in Naming.exc_save_vars: code.put_xgiveref(var)
4691 code.putln("__Pyx_ExceptionReset(%s);" %
4692 ', '.join(Naming.exc_save_vars))
4693 code.put_goto(old_label)
4695 if code.label_used(except_end_label):
4696 code.put_label(except_end_label)
4697 for var in Naming.exc_save_vars: code.put_xgiveref(var)
4698 code.putln("__Pyx_ExceptionReset(%s);" %
4699 ', '.join(Naming.exc_save_vars))
4700 code.put_label(try_end_label)
4703 code.return_label = old_return_label
4704 code.break_label = old_break_label
4705 code.continue_label = old_continue_label
4706 code.error_label = old_error_label
4708 def generate_function_definitions(self, env, code):
4709 self.body.generate_function_definitions(env, code)
4710 for except_clause in self.except_clauses:
4711 except_clause.generate_function_definitions(env, code)
4712 if self.else_clause is not None:
4713 self.else_clause.generate_function_definitions(env, code)
4715 def annotate(self, code):
4716 self.body.annotate(code)
4717 for except_node in self.except_clauses:
4718 except_node.annotate(code)
4719 if self.else_clause:
4720 self.else_clause.annotate(code)
4723 class ExceptClauseNode(Node):
4724 # Part of try ... except statement.
4726 # pattern [ExprNode]
4727 # target ExprNode or None
4729 # excinfo_target NameNode or None optional target for exception info
4730 # match_flag string result of exception match
4731 # exc_value ExcValueNode used internally
4732 # function_name string qualified name of enclosing function
4733 # exc_vars (string * 3) local exception variables
4735 # excinfo_target is never set by the parser, but can be set by a transform
4736 # in order to extract more extensive information about the exception as a
4737 # sys.exc_info()-style tuple into a target variable
4739 child_attrs = ["pattern", "target", "body", "exc_value", "excinfo_target"]
4742 excinfo_target = None
4744 def analyse_declarations(self, env):
4746 self.target.analyse_target_declaration(env)
4747 if self.excinfo_target is not None:
4748 self.excinfo_target.analyse_target_declaration(env)
4749 self.body.analyse_declarations(env)
4751 def analyse_expressions(self, env):
4753 genv = env.global_scope()
4754 self.function_name = env.qualified_name
4756 # normalise/unpack self.pattern into a list
4757 for i, pattern in enumerate(self.pattern):
4758 pattern.analyse_expressions(env)
4759 self.pattern[i] = pattern.coerce_to_pyobject(env)
4762 self.exc_value = ExprNodes.ExcValueNode(self.pos, env)
4763 self.target.analyse_target_expression(env, self.exc_value)
4764 if self.excinfo_target is not None:
4766 self.excinfo_tuple = ExprNodes.TupleNode(pos=self.pos, args=[
4767 ExprNodes.ExcValueNode(pos=self.pos, env=env) for x in range(3)])
4768 self.excinfo_tuple.analyse_expressions(env)
4769 self.excinfo_target.analyse_target_expression(env, self.excinfo_tuple)
4771 self.body.analyse_expressions(env)
4773 def generate_handling_code(self, code, end_label):
4774 code.mark_pos(self.pos)
4777 for pattern in self.pattern:
4778 pattern.generate_evaluation_code(code)
4779 exc_tests.append("PyErr_ExceptionMatches(%s)" % pattern.py_result())
4781 match_flag = code.funcstate.allocate_temp(PyrexTypes.c_int_type, False)
4783 "%s = %s;" % (match_flag, ' || '.join(exc_tests)))
4784 for pattern in self.pattern:
4785 pattern.generate_disposal_code(code)
4786 pattern.free_temps(code)
4790 code.funcstate.release_temp(match_flag)
4792 code.putln("/*except:*/ {")
4794 if not getattr(self.body, 'stats', True) and \
4795 self.excinfo_target is None and self.target is None:
4796 # most simple case: no exception variable, empty body (pass)
4797 # => reset the exception state, done
4798 code.putln("PyErr_Restore(0,0,0);")
4799 code.put_goto(end_label)
4803 exc_vars = [code.funcstate.allocate_temp(py_object_type,
4806 code.putln('__Pyx_AddTraceback("%s");' % self.function_name)
4807 # We always have to fetch the exception value even if
4808 # there is no target, because this also normalises the
4809 # exception and stores it in the thread state.
4810 code.globalstate.use_utility_code(get_exception_utility_code)
4811 exc_args = "&%s, &%s, &%s" % tuple(exc_vars)
4812 code.putln("if (__Pyx_GetException(%s) < 0) %s" % (exc_args,
4813 code.error_goto(self.pos)))
4817 self.exc_value.set_var(exc_vars[1])
4818 self.exc_value.generate_evaluation_code(code)
4819 self.target.generate_assignment_code(self.exc_value, code)
4820 if self.excinfo_target is not None:
4821 for tempvar, node in zip(exc_vars, self.excinfo_tuple.args):
4822 node.set_var(tempvar)
4823 self.excinfo_tuple.generate_evaluation_code(code)
4824 self.excinfo_target.generate_assignment_code(self.excinfo_tuple, code)
4826 old_break_label, old_continue_label = code.break_label, code.continue_label
4827 code.break_label = code.new_label('except_break')
4828 code.continue_label = code.new_label('except_continue')
4830 old_exc_vars = code.funcstate.exc_vars
4831 code.funcstate.exc_vars = exc_vars
4832 self.body.generate_execution_code(code)
4833 code.funcstate.exc_vars = old_exc_vars
4834 for var in exc_vars:
4835 code.putln("__Pyx_DECREF(%s); %s = 0;" % (var, var))
4836 code.put_goto(end_label)
4838 if code.label_used(code.break_label):
4839 code.put_label(code.break_label)
4840 for var in exc_vars:
4841 code.putln("__Pyx_DECREF(%s); %s = 0;" % (var, var))
4842 code.put_goto(old_break_label)
4843 code.break_label = old_break_label
4845 if code.label_used(code.continue_label):
4846 code.put_label(code.continue_label)
4847 for var in exc_vars:
4848 code.putln("__Pyx_DECREF(%s); %s = 0;" % (var, var))
4849 code.put_goto(old_continue_label)
4850 code.continue_label = old_continue_label
4852 for temp in exc_vars:
4853 code.funcstate.release_temp(temp)
4858 def generate_function_definitions(self, env, code):
4859 if self.target is not None:
4860 self.target.generate_function_definitions(env, code)
4861 self.body.generate_function_definitions(env, code)
4863 def annotate(self, code):
4865 for pattern in self.pattern:
4866 pattern.annotate(code)
4868 self.target.annotate(code)
4869 self.body.annotate(code)
4872 class TryFinallyStatNode(StatNode):
4873 # try ... finally statement
4876 # finally_clause StatNode
4878 # The plan is that we funnel all continue, break
4879 # return and error gotos into the beginning of the
4880 # finally block, setting a variable to remember which
4881 # one we're doing. At the end of the finally block, we
4882 # switch on the variable to figure out where to go.
4883 # In addition, if we're doing an error, we save the
4884 # exception on entry to the finally block and restore
4887 child_attrs = ["body", "finally_clause"]
4889 preserve_exception = 1
4891 disallow_continue_in_try_finally = 0
4892 # There doesn't seem to be any point in disallowing
4893 # continue in the try block, since we have no problem
4896 def create_analysed(pos, env, body, finally_clause):
4897 node = TryFinallyStatNode(pos, body=body, finally_clause=finally_clause)
4899 create_analysed = staticmethod(create_analysed)
4901 def analyse_control_flow(self, env):
4902 env.start_branching(self.pos)
4903 self.body.analyse_control_flow(env)
4904 env.next_branch(self.body.end_pos())
4905 env.finish_branching(self.body.end_pos())
4906 self.finally_clause.analyse_control_flow(env)
4908 def analyse_declarations(self, env):
4909 self.body.analyse_declarations(env)
4910 self.finally_clause.analyse_declarations(env)
4912 def analyse_expressions(self, env):
4913 self.body.analyse_expressions(env)
4914 self.finally_clause.analyse_expressions(env)
4916 nogil_check = Node.gil_error
4917 gil_message = "Try-finally statement"
4919 def generate_execution_code(self, code):
4920 old_error_label = code.error_label
4921 old_labels = code.all_new_labels()
4922 new_labels = code.get_all_labels()
4923 new_error_label = code.error_label
4924 catch_label = code.new_label()
4927 if self.disallow_continue_in_try_finally:
4928 was_in_try_finally = code.funcstate.in_try_finally
4929 code.funcstate.in_try_finally = 1
4930 self.body.generate_execution_code(code)
4931 if self.disallow_continue_in_try_finally:
4932 code.funcstate.in_try_finally = was_in_try_finally
4935 temps_to_clean_up = code.funcstate.all_free_managed_temps()
4936 code.mark_pos(self.finally_clause.pos)
4940 error_label_used = 0
4941 for i, new_label in enumerate(new_labels):
4942 if new_label in code.labels_used:
4943 cases_used.append(i)
4944 if new_label == new_error_label:
4945 error_label_used = 1
4946 error_label_case = i
4950 if error_label_used and self.preserve_exception:
4952 "PyObject *%s, *%s, *%s;" % Naming.exc_vars)
4954 "int %s;" % Naming.exc_lineno_name)
4955 exc_var_init_zero = ''.join(["%s = 0; " % var for var in Naming.exc_vars])
4956 exc_var_init_zero += '%s = 0;' % Naming.exc_lineno_name
4957 code.putln(exc_var_init_zero)
4959 exc_var_init_zero = None
4960 code.use_label(catch_label)
4962 "__pyx_why = 0; goto %s;" % catch_label)
4963 for i in cases_used:
4964 new_label = new_labels[i]
4965 #if new_label and new_label != "<try>":
4966 if new_label == new_error_label and self.preserve_exception:
4967 self.put_error_catcher(code,
4968 new_error_label, i+1, catch_label, temps_to_clean_up)
4970 code.put('%s: ' % new_label)
4971 if exc_var_init_zero:
4972 code.putln(exc_var_init_zero)
4973 code.putln("__pyx_why = %s; goto %s;" % (
4976 code.put_label(catch_label)
4977 code.set_all_labels(old_labels)
4978 if error_label_used:
4979 code.new_error_label()
4980 finally_error_label = code.error_label
4981 self.finally_clause.generate_execution_code(code)
4982 if error_label_used:
4983 if finally_error_label in code.labels_used and self.preserve_exception:
4984 over_label = code.new_label()
4985 code.put_goto(over_label);
4986 code.put_label(finally_error_label)
4987 code.putln("if (__pyx_why == %d) {" % (error_label_case + 1))
4988 for var in Naming.exc_vars:
4989 code.putln("Py_XDECREF(%s);" % var)
4991 code.put_goto(old_error_label)
4992 code.put_label(over_label)
4993 code.error_label = old_error_label
4996 "switch (__pyx_why) {")
4997 for i in cases_used:
4998 old_label = old_labels[i]
4999 if old_label == old_error_label and self.preserve_exception:
5000 self.put_error_uncatcher(code, i+1, old_error_label)
5002 code.use_label(old_label)
5004 "case %s: goto %s;" % (
5012 def generate_function_definitions(self, env, code):
5013 self.body.generate_function_definitions(env, code)
5014 self.finally_clause.generate_function_definitions(env, code)
5016 def put_error_catcher(self, code, error_label, i, catch_label, temps_to_clean_up):
5017 code.globalstate.use_utility_code(restore_exception_utility_code)
5024 for temp_name, type in temps_to_clean_up:
5025 code.put_xdecref_clear(temp_name, type)
5027 "__Pyx_ErrFetch(&%s, &%s, &%s);" %
5031 Naming.exc_lineno_name, Naming.lineno_cname))
5032 code.put_goto(catch_label)
5035 def put_error_uncatcher(self, code, i, error_label):
5036 code.globalstate.use_utility_code(restore_exception_utility_code)
5041 "__Pyx_ErrRestore(%s, %s, %s);" %
5045 Naming.lineno_cname, Naming.exc_lineno_name))
5046 for var in Naming.exc_vars:
5050 code.put_goto(error_label)
5054 def annotate(self, code):
5055 self.body.annotate(code)
5056 self.finally_clause.annotate(code)
5059 class GILStatNode(TryFinallyStatNode):
5060 # 'with gil' or 'with nogil' statement
5062 # state string 'gil' or 'nogil'
5066 preserve_exception = 0
5068 def __init__(self, pos, state, body):
5070 TryFinallyStatNode.__init__(self, pos,
5072 finally_clause = GILExitNode(pos, state = state))
5074 def analyse_expressions(self, env):
5075 env.use_utility_code(force_init_threads_utility_code)
5076 was_nogil = env.nogil
5078 TryFinallyStatNode.analyse_expressions(self, env)
5079 env.nogil = was_nogil
5083 def generate_execution_code(self, code):
5084 code.mark_pos(self.pos)
5086 if self.state == 'gil':
5087 code.putln("#ifdef WITH_THREAD")
5088 code.putln("PyGILState_STATE _save = PyGILState_Ensure();")
5089 code.putln("#endif")
5091 code.putln("#ifdef WITH_THREAD")
5092 code.putln("PyThreadState *_save;")
5093 code.putln("#endif")
5094 code.putln("Py_UNBLOCK_THREADS")
5095 TryFinallyStatNode.generate_execution_code(self, code)
5099 class GILExitNode(StatNode):
5100 # Used as the 'finally' block in a GILStatNode
5102 # state string 'gil' or 'nogil'
5106 def analyse_expressions(self, env):
5109 def generate_execution_code(self, code):
5110 if self.state == 'gil':
5111 code.putln("#ifdef WITH_THREAD")
5112 code.putln("PyGILState_Release(_save);")
5113 code.putln("#endif")
5115 code.putln("Py_BLOCK_THREADS")
5118 class CImportStatNode(StatNode):
5121 # module_name string Qualified name of module being imported
5122 # as_name string or None Name specified in "as" clause, if any
5126 def analyse_declarations(self, env):
5127 if not env.is_module_scope:
5128 error(self.pos, "cimport only allowed at module level")
5130 module_scope = env.find_module(self.module_name, self.pos)
5131 if "." in self.module_name:
5132 names = [EncodedString(name) for name in self.module_name.split(".")]
5134 top_module_scope = env.context.find_submodule(top_name)
5135 module_scope = top_module_scope
5136 for name in names[1:]:
5137 submodule_scope = module_scope.find_submodule(name)
5138 module_scope.declare_module(name, submodule_scope, self.pos)
5139 module_scope = submodule_scope
5141 env.declare_module(self.as_name, module_scope, self.pos)
5143 env.declare_module(top_name, top_module_scope, self.pos)
5145 name = self.as_name or self.module_name
5146 env.declare_module(name, module_scope, self.pos)
5148 def analyse_expressions(self, env):
5151 def generate_execution_code(self, code):
5155 class FromCImportStatNode(StatNode):
5156 # from ... cimport statement
5158 # module_name string Qualified name of module
5159 # imported_names [(pos, name, as_name, kind)] Names to be imported
5163 def analyse_declarations(self, env):
5164 if not env.is_module_scope:
5165 error(self.pos, "cimport only allowed at module level")
5167 module_scope = env.find_module(self.module_name, self.pos)
5168 env.add_imported_module(module_scope)
5169 for pos, name, as_name, kind in self.imported_names:
5171 for local_name, entry in module_scope.entries.items():
5172 env.add_imported_entry(local_name, entry, pos)
5174 entry = module_scope.lookup(name)
5176 if kind and not self.declaration_matches(entry, kind):
5177 entry.redeclared(pos)
5179 if kind == 'struct' or kind == 'union':
5180 entry = module_scope.declare_struct_or_union(name,
5181 kind = kind, scope = None, typedef_flag = 0, pos = pos)
5182 elif kind == 'class':
5183 entry = module_scope.declare_c_class(name, pos = pos,
5184 module_name = self.module_name)
5186 submodule_scope = env.context.find_module(name, relative_to = module_scope, pos = self.pos)
5187 if submodule_scope.parent_module is module_scope:
5188 env.declare_module(as_name or name, submodule_scope, self.pos)
5190 error(pos, "Name '%s' not declared in module '%s'"
5191 % (name, self.module_name))
5194 local_name = as_name or name
5195 env.add_imported_entry(local_name, entry, pos)
5197 def declaration_matches(self, entry, kind):
5198 if not entry.is_type:
5202 if not type.is_extension_type:
5205 if not type.is_struct_or_union:
5207 if kind != type.kind:
5211 def analyse_expressions(self, env):
5214 def generate_execution_code(self, code):
5218 class FromImportStatNode(StatNode):
5219 # from ... import statement
5222 # items [(string, NameNode)]
5223 # interned_items [(string, NameNode, ExprNode)]
5224 # item PyTempNode used internally
5225 # import_star boolean used internally
5227 child_attrs = ["module"]
5230 def analyse_declarations(self, env):
5231 for name, target in self.items:
5233 if not env.is_module_scope:
5234 error(self.pos, "import * only allowed at module level")
5236 env.has_import_star = 1
5237 self.import_star = 1
5239 target.analyse_target_declaration(env)
5241 def analyse_expressions(self, env):
5243 self.module.analyse_expressions(env)
5244 self.item = ExprNodes.RawCNameExprNode(self.pos, py_object_type)
5245 self.interned_items = []
5246 for name, target in self.items:
5248 for _, entry in env.entries.items():
5249 if not entry.is_type and entry.type.is_extension_type:
5250 env.use_utility_code(ExprNodes.type_test_utility_code)
5253 entry = env.lookup(target.name)
5254 # check whether or not entry is already cimported
5255 if (entry.is_type and entry.type.name == name
5256 and hasattr(entry.type, 'module_name')):
5257 if entry.type.module_name == self.module.module_name.value:
5258 # cimported with absolute name
5261 # cimported with relative name
5262 module = env.find_module(self.module.module_name.value,
5264 if entry.type.module_name == module.qualified_name:
5266 except AttributeError:
5268 target.analyse_target_expression(env, None)
5269 if target.type is py_object_type:
5272 coerced_item = self.item.coerce_to(target.type, env)
5273 self.interned_items.append((name, target, coerced_item))
5275 def generate_execution_code(self, code):
5276 self.module.generate_evaluation_code(code)
5277 if self.import_star:
5279 'if (%s(%s) < 0) %s;' % (
5281 self.module.py_result(),
5282 code.error_goto(self.pos)))
5283 item_temp = code.funcstate.allocate_temp(py_object_type, manage_ref=True)
5284 self.item.set_cname(item_temp)
5285 for name, target, coerced_item in self.interned_items:
5286 cname = code.intern_identifier(name)
5288 '%s = PyObject_GetAttr(%s, %s); %s' % (
5290 self.module.py_result(),
5292 code.error_goto_if_null(item_temp, self.pos)))
5293 code.put_gotref(item_temp)
5294 if coerced_item is None:
5295 target.generate_assignment_code(self.item, code)
5297 coerced_item.allocate_temp_result(code)
5298 coerced_item.generate_result_code(code)
5299 target.generate_assignment_code(coerced_item, code)
5300 code.put_decref_clear(item_temp, py_object_type)
5301 code.funcstate.release_temp(item_temp)
5302 self.module.generate_disposal_code(code)
5303 self.module.free_temps(code)
5307 #------------------------------------------------------------------------------------
5309 # Runtime support code
5311 #------------------------------------------------------------------------------------
5313 utility_function_predeclarations = \
5315 /* inline attribute */
5316 #ifndef CYTHON_INLINE
5317 #if defined(__GNUC__)
5318 #define CYTHON_INLINE __inline__
5319 #elif defined(_MSC_VER)
5320 #define CYTHON_INLINE __inline
5321 #elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
5322 #define CYTHON_INLINE inline
5324 #define CYTHON_INLINE
5328 /* unused attribute */
5329 #ifndef CYTHON_UNUSED
5330 # if defined(__GNUC__)
5331 # if !(defined(__cplusplus)) || (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4))
5332 # define CYTHON_UNUSED __attribute__ ((__unused__))
5334 # define CYTHON_UNUSED
5336 # elif defined(__ICC) || defined(__INTEL_COMPILER)
5337 # define CYTHON_UNUSED __attribute__ ((__unused__))
5339 # define CYTHON_UNUSED
5343 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*/
5347 if Options.gcc_branch_hints:
5348 branch_prediction_macros = \
5351 /* Test for GCC > 2.95 */
5352 #if __GNUC__ > 2 || (__GNUC__ == 2 && (__GNUC_MINOR__ > 95))
5353 #define likely(x) __builtin_expect(!!(x), 1)
5354 #define unlikely(x) __builtin_expect(!!(x), 0)
5355 #else /* __GNUC__ > 2 ... */
5356 #define likely(x) (x)
5357 #define unlikely(x) (x)
5358 #endif /* __GNUC__ > 2 ... */
5359 #else /* __GNUC__ */
5360 #define likely(x) (x)
5361 #define unlikely(x) (x)
5362 #endif /* __GNUC__ */
5365 branch_prediction_macros = \
5367 #define likely(x) (x)
5368 #define unlikely(x) (x)
5371 #get_name_predeclaration = \
5372 #"static PyObject *__Pyx_GetName(PyObject *dict, char *name); /*proto*/"
5374 #get_name_interned_predeclaration = \
5375 #"static PyObject *__Pyx_GetName(PyObject *dict, PyObject *name); /*proto*/"
5377 #------------------------------------------------------------------------------------
5379 printing_utility_code = UtilityCode(
5381 static int __Pyx_Print(PyObject*, PyObject *, int); /*proto*/
5382 #if PY_MAJOR_VERSION >= 3
5383 static PyObject* %s = 0;
5384 static PyObject* %s = 0;
5386 """ % (Naming.print_function, Naming.print_function_kwargs),
5388 #if PY_MAJOR_VERSION >= 3
5392 """ % (Naming.print_function, Naming.print_function_kwargs),
5394 #if PY_MAJOR_VERSION < 3
5395 static PyObject *__Pyx_GetStdout(void) {
5396 PyObject *f = PySys_GetObject((char *)"stdout");
5398 PyErr_SetString(PyExc_RuntimeError, "lost sys.stdout");
5403 static int __Pyx_Print(PyObject* f, PyObject *arg_tuple, int newline) {
5408 if (!(f = __Pyx_GetStdout()))
5411 for (i=0; i < PyTuple_GET_SIZE(arg_tuple); i++) {
5412 if (PyFile_SoftSpace(f, 1)) {
5413 if (PyFile_WriteString(" ", f) < 0)
5416 v = PyTuple_GET_ITEM(arg_tuple, i);
5417 if (PyFile_WriteObject(v, f, Py_PRINT_RAW) < 0)
5419 if (PyString_Check(v)) {
5420 char *s = PyString_AsString(v);
5421 Py_ssize_t len = PyString_Size(v);
5423 isspace(Py_CHARMASK(s[len-1])) &&
5425 PyFile_SoftSpace(f, 0);
5429 if (PyFile_WriteString("\n", f) < 0)
5431 PyFile_SoftSpace(f, 0);
5436 #else /* Python 3 has a print function */
5438 static int __Pyx_Print(PyObject* stream, PyObject *arg_tuple, int newline) {
5439 PyObject* kwargs = 0;
5440 PyObject* result = 0;
5441 PyObject* end_string;
5442 if (unlikely(!%(PRINT_FUNCTION)s)) {
5443 %(PRINT_FUNCTION)s = __Pyx_GetAttrString(%(BUILTINS)s, "print");
5444 if (!%(PRINT_FUNCTION)s)
5448 kwargs = PyDict_New();
5449 if (unlikely(!kwargs))
5451 if (unlikely(PyDict_SetItemString(kwargs, "file", stream) < 0))
5454 end_string = PyUnicode_FromStringAndSize(" ", 1);
5455 if (unlikely(!end_string))
5457 if (PyDict_SetItemString(kwargs, "end", end_string) < 0) {
5458 Py_DECREF(end_string);
5461 Py_DECREF(end_string);
5463 } else if (!newline) {
5464 if (unlikely(!%(PRINT_KWARGS)s)) {
5465 %(PRINT_KWARGS)s = PyDict_New();
5466 if (unlikely(!%(PRINT_KWARGS)s))
5468 end_string = PyUnicode_FromStringAndSize(" ", 1);
5469 if (unlikely(!end_string))
5471 if (PyDict_SetItemString(%(PRINT_KWARGS)s, "end", end_string) < 0) {
5472 Py_DECREF(end_string);
5475 Py_DECREF(end_string);
5477 kwargs = %(PRINT_KWARGS)s;
5479 result = PyObject_Call(%(PRINT_FUNCTION)s, arg_tuple, kwargs);
5480 if (unlikely(kwargs) && (kwargs != %(PRINT_KWARGS)s))
5487 if (kwargs != %(PRINT_KWARGS)s)
5493 """ % {'BUILTINS' : Naming.builtins_cname,
5494 'PRINT_FUNCTION' : Naming.print_function,
5495 'PRINT_KWARGS' : Naming.print_function_kwargs}
5499 printing_one_utility_code = UtilityCode(
5501 static int __Pyx_PrintOne(PyObject* stream, PyObject *o); /*proto*/
5504 #if PY_MAJOR_VERSION < 3
5506 static int __Pyx_PrintOne(PyObject* f, PyObject *o) {
5508 if (!(f = __Pyx_GetStdout()))
5511 if (PyFile_SoftSpace(f, 0)) {
5512 if (PyFile_WriteString(" ", f) < 0)
5515 if (PyFile_WriteObject(o, f, Py_PRINT_RAW) < 0)
5517 if (PyFile_WriteString("\n", f) < 0)
5520 /* the line below is just to avoid compiler
5521 * compiler warnings about unused functions */
5522 return __Pyx_Print(f, NULL, 0);
5525 #else /* Python 3 has a print function */
5527 static int __Pyx_PrintOne(PyObject* stream, PyObject *o) {
5529 PyObject* arg_tuple = PyTuple_New(1);
5530 if (unlikely(!arg_tuple))
5533 PyTuple_SET_ITEM(arg_tuple, 0, o);
5534 res = __Pyx_Print(stream, arg_tuple, 1);
5535 Py_DECREF(arg_tuple);
5541 requires=[printing_utility_code])
5545 #------------------------------------------------------------------------------------
5547 # Exception raising code
5549 # Exceptions are raised by __Pyx_Raise() and stored as plain
5550 # type/value/tb in PyThreadState->curexc_*. When being caught by an
5551 # 'except' statement, curexc_* is moved over to exc_* by
5552 # __Pyx_GetException()
5554 restore_exception_utility_code = UtilityCode(
5556 static CYTHON_INLINE void __Pyx_ErrRestore(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
5557 static CYTHON_INLINE void __Pyx_ErrFetch(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
5560 static CYTHON_INLINE void __Pyx_ErrRestore(PyObject *type, PyObject *value, PyObject *tb) {
5561 PyObject *tmp_type, *tmp_value, *tmp_tb;
5562 PyThreadState *tstate = PyThreadState_GET();
5564 tmp_type = tstate->curexc_type;
5565 tmp_value = tstate->curexc_value;
5566 tmp_tb = tstate->curexc_traceback;
5567 tstate->curexc_type = type;
5568 tstate->curexc_value = value;
5569 tstate->curexc_traceback = tb;
5570 Py_XDECREF(tmp_type);
5571 Py_XDECREF(tmp_value);
5575 static CYTHON_INLINE void __Pyx_ErrFetch(PyObject **type, PyObject **value, PyObject **tb) {
5576 PyThreadState *tstate = PyThreadState_GET();
5577 *type = tstate->curexc_type;
5578 *value = tstate->curexc_value;
5579 *tb = tstate->curexc_traceback;
5581 tstate->curexc_type = 0;
5582 tstate->curexc_value = 0;
5583 tstate->curexc_traceback = 0;
5588 # The following function is based on do_raise() from ceval.c. There
5589 # are separate versions for Python2 and Python3 as exception handling
5590 # has changed quite a lot between the two versions.
5592 raise_utility_code = UtilityCode(
5594 static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
5597 #if PY_MAJOR_VERSION < 3
5598 static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb) {
5602 /* First, check the traceback argument, replacing None with NULL. */
5603 if (tb == Py_None) {
5607 else if (tb != NULL && !PyTraceBack_Check(tb)) {
5608 PyErr_SetString(PyExc_TypeError,
5609 "raise: arg 3 must be a traceback or None");
5612 /* Next, replace a missing value with None */
5613 if (value == NULL) {
5617 #if PY_VERSION_HEX < 0x02050000
5618 if (!PyClass_Check(type))
5620 if (!PyType_Check(type))
5623 /* Raising an instance. The value should be a dummy. */
5624 if (value != Py_None) {
5625 PyErr_SetString(PyExc_TypeError,
5626 "instance exception may not have a separate value");
5629 /* Normalize to raise <class>, <instance> */
5632 #if PY_VERSION_HEX < 0x02050000
5633 if (PyInstance_Check(type)) {
5634 type = (PyObject*) ((PyInstanceObject*)type)->in_class;
5639 PyErr_SetString(PyExc_TypeError,
5640 "raise: exception must be an old-style class or instance");
5644 type = (PyObject*) Py_TYPE(type);
5646 if (!PyType_IsSubtype((PyTypeObject *)type, (PyTypeObject *)PyExc_BaseException)) {
5647 PyErr_SetString(PyExc_TypeError,
5648 "raise: exception class must be a subclass of BaseException");
5654 __Pyx_ErrRestore(type, value, tb);
5663 #else /* Python 3+ */
5665 static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb) {
5666 if (tb == Py_None) {
5668 } else if (tb && !PyTraceBack_Check(tb)) {
5669 PyErr_SetString(PyExc_TypeError,
5670 "raise: arg 3 must be a traceback or None");
5673 if (value == Py_None)
5676 if (PyExceptionInstance_Check(type)) {
5678 PyErr_SetString(PyExc_TypeError,
5679 "instance exception may not have a separate value");
5683 type = (PyObject*) Py_TYPE(value);
5684 } else if (!PyExceptionClass_Check(type)) {
5685 PyErr_SetString(PyExc_TypeError,
5686 "raise: exception class must be a subclass of BaseException");
5690 PyErr_SetObject(type, value);
5693 PyThreadState *tstate = PyThreadState_GET();
5694 PyObject* tmp_tb = tstate->curexc_traceback;
5697 tstate->curexc_traceback = tb;
5707 requires=[restore_exception_utility_code])
5709 #------------------------------------------------------------------------------------
5711 get_exception_utility_code = UtilityCode(
5713 static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
5716 static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb) {
5717 PyObject *local_type, *local_value, *local_tb;
5718 PyObject *tmp_type, *tmp_value, *tmp_tb;
5719 PyThreadState *tstate = PyThreadState_GET();
5720 local_type = tstate->curexc_type;
5721 local_value = tstate->curexc_value;
5722 local_tb = tstate->curexc_traceback;
5723 tstate->curexc_type = 0;
5724 tstate->curexc_value = 0;
5725 tstate->curexc_traceback = 0;
5726 PyErr_NormalizeException(&local_type, &local_value, &local_tb);
5727 if (unlikely(tstate->curexc_type))
5729 #if PY_MAJOR_VERSION >= 3
5730 if (unlikely(PyException_SetTraceback(local_value, local_tb) < 0))
5734 *value = local_value;
5736 Py_INCREF(local_type);
5737 Py_INCREF(local_value);
5738 Py_INCREF(local_tb);
5739 tmp_type = tstate->exc_type;
5740 tmp_value = tstate->exc_value;
5741 tmp_tb = tstate->exc_traceback;
5742 tstate->exc_type = local_type;
5743 tstate->exc_value = local_value;
5744 tstate->exc_traceback = local_tb;
5745 /* Make sure tstate is in a consistent state when we XDECREF
5746 these objects (XDECREF may run arbitrary code). */
5747 Py_XDECREF(tmp_type);
5748 Py_XDECREF(tmp_value);
5755 Py_XDECREF(local_type);
5756 Py_XDECREF(local_value);
5757 Py_XDECREF(local_tb);
5763 #------------------------------------------------------------------------------------
5765 get_exception_tuple_utility_code = UtilityCode(proto="""
5766 static PyObject *__Pyx_GetExceptionTuple(void); /*proto*/
5768 # I doubt that calling __Pyx_GetException() here is correct as it moves
5769 # the exception from tstate->curexc_* to tstate->exc_*, which prevents
5770 # exception handlers later on from receiving it.
5772 static PyObject *__Pyx_GetExceptionTuple(void) {
5773 PyObject *type = NULL, *value = NULL, *tb = NULL;
5774 if (__Pyx_GetException(&type, &value, &tb) == 0) {
5775 PyObject* exc_info = PyTuple_New(3);
5780 PyTuple_SET_ITEM(exc_info, 0, type);
5781 PyTuple_SET_ITEM(exc_info, 1, value);
5782 PyTuple_SET_ITEM(exc_info, 2, tb);
5789 requires=[get_exception_utility_code])
5791 #------------------------------------------------------------------------------------
5793 reset_exception_utility_code = UtilityCode(
5795 static CYTHON_INLINE void __Pyx_ExceptionSave(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
5796 static void __Pyx_ExceptionReset(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
5799 static CYTHON_INLINE void __Pyx_ExceptionSave(PyObject **type, PyObject **value, PyObject **tb) {
5800 PyThreadState *tstate = PyThreadState_GET();
5801 *type = tstate->exc_type;
5802 *value = tstate->exc_value;
5803 *tb = tstate->exc_traceback;
5809 static void __Pyx_ExceptionReset(PyObject *type, PyObject *value, PyObject *tb) {
5810 PyObject *tmp_type, *tmp_value, *tmp_tb;
5811 PyThreadState *tstate = PyThreadState_GET();
5812 tmp_type = tstate->exc_type;
5813 tmp_value = tstate->exc_value;
5814 tmp_tb = tstate->exc_traceback;
5815 tstate->exc_type = type;
5816 tstate->exc_value = value;
5817 tstate->exc_traceback = tb;
5818 Py_XDECREF(tmp_type);
5819 Py_XDECREF(tmp_value);
5824 #------------------------------------------------------------------------------------
5826 arg_type_test_utility_code = UtilityCode(
5828 static int __Pyx_ArgTypeTest(PyObject *obj, PyTypeObject *type, int none_allowed,
5829 const char *name, int exact); /*proto*/
5832 static int __Pyx_ArgTypeTest(PyObject *obj, PyTypeObject *type, int none_allowed,
5833 const char *name, int exact)
5836 PyErr_Format(PyExc_SystemError, "Missing type object");
5839 if (none_allowed && obj == Py_None) return 1;
5841 if (Py_TYPE(obj) == type) return 1;
5844 if (PyObject_TypeCheck(obj, type)) return 1;
5846 PyErr_Format(PyExc_TypeError,
5847 "Argument '%s' has incorrect type (expected %s, got %s)",
5848 name, type->tp_name, Py_TYPE(obj)->tp_name);
5853 #------------------------------------------------------------------------------------
5855 # __Pyx_RaiseArgtupleInvalid raises the correct exception when too
5856 # many or too few positional arguments were found. This handles
5857 # Py_ssize_t formatting correctly.
5859 raise_argtuple_invalid_utility_code = UtilityCode(
5861 static void __Pyx_RaiseArgtupleInvalid(const char* func_name, int exact,
5862 Py_ssize_t num_min, Py_ssize_t num_max, Py_ssize_t num_found); /*proto*/
5865 static void __Pyx_RaiseArgtupleInvalid(
5866 const char* func_name,
5870 Py_ssize_t num_found)
5872 Py_ssize_t num_expected;
5873 const char *number, *more_or_less;
5875 if (num_found < num_min) {
5876 num_expected = num_min;
5877 more_or_less = "at least";
5879 num_expected = num_max;
5880 more_or_less = "at most";
5883 more_or_less = "exactly";
5885 number = (num_expected == 1) ? "" : "s";
5886 PyErr_Format(PyExc_TypeError,
5887 #if PY_VERSION_HEX < 0x02050000
5888 "%s() takes %s %d positional argument%s (%d given)",
5890 "%s() takes %s %zd positional argument%s (%zd given)",
5892 func_name, more_or_less, num_expected, number, num_found);
5896 raise_keyword_required_utility_code = UtilityCode(
5898 static CYTHON_INLINE void __Pyx_RaiseKeywordRequired(const char* func_name, PyObject* kw_name); /*proto*/
5901 static CYTHON_INLINE void __Pyx_RaiseKeywordRequired(
5902 const char* func_name,
5905 PyErr_Format(PyExc_TypeError,
5906 #if PY_MAJOR_VERSION >= 3
5907 "%s() needs keyword-only argument %U", func_name, kw_name);
5909 "%s() needs keyword-only argument %s", func_name,
5910 PyString_AS_STRING(kw_name));
5915 raise_double_keywords_utility_code = UtilityCode(
5917 static void __Pyx_RaiseDoubleKeywordsError(
5918 const char* func_name, PyObject* kw_name); /*proto*/
5921 static void __Pyx_RaiseDoubleKeywordsError(
5922 const char* func_name,
5925 PyErr_Format(PyExc_TypeError,
5926 #if PY_MAJOR_VERSION >= 3
5927 "%s() got multiple values for keyword argument '%U'", func_name, kw_name);
5929 "%s() got multiple values for keyword argument '%s'", func_name,
5930 PyString_AS_STRING(kw_name));
5935 #------------------------------------------------------------------------------------
5937 # __Pyx_CheckKeywordStrings raises an error if non-string keywords
5938 # were passed to a function, or if any keywords were passed to a
5939 # function that does not accept them.
5941 keyword_string_check_utility_code = UtilityCode(
5943 static CYTHON_INLINE int __Pyx_CheckKeywordStrings(PyObject *kwdict,
5944 const char* function_name, int kw_allowed); /*proto*/
5947 static CYTHON_INLINE int __Pyx_CheckKeywordStrings(
5949 const char* function_name,
5954 while (PyDict_Next(kwdict, &pos, &key, 0)) {
5955 #if PY_MAJOR_VERSION < 3
5956 if (unlikely(!PyString_CheckExact(key)) && unlikely(!PyString_Check(key)))
5958 if (unlikely(!PyUnicode_CheckExact(key)) && unlikely(!PyUnicode_Check(key)))
5960 goto invalid_keyword_type;
5962 if ((!kw_allowed) && unlikely(key))
5963 goto invalid_keyword;
5965 invalid_keyword_type:
5966 PyErr_Format(PyExc_TypeError,
5967 "%s() keywords must be strings", function_name);
5970 PyErr_Format(PyExc_TypeError,
5971 #if PY_MAJOR_VERSION < 3
5972 "%s() got an unexpected keyword argument '%s'",
5973 function_name, PyString_AsString(key));
5975 "%s() got an unexpected keyword argument '%U'",
5976 function_name, key);
5982 #------------------------------------------------------------------------------------
5984 # __Pyx_ParseOptionalKeywords copies the optional/unknown keyword
5985 # arguments from the kwds dict into kwds2. If kwds2 is NULL, unknown
5986 # keywords will raise an invalid keyword error.
5988 # Three kinds of errors are checked: 1) non-string keywords, 2)
5989 # unexpected keywords and 3) overlap with positional arguments.
5991 # If num_posargs is greater 0, it denotes the number of positional
5992 # arguments that were passed and that must therefore not appear
5993 # amongst the keywords as well.
5995 # This method does not check for required keyword arguments.
5998 parse_keywords_utility_code = UtilityCode(
6000 static int __Pyx_ParseOptionalKeywords(PyObject *kwds, PyObject **argnames[], \
6001 PyObject *kwds2, PyObject *values[], Py_ssize_t num_pos_args, \
6002 const char* function_name); /*proto*/
6005 static int __Pyx_ParseOptionalKeywords(
6007 PyObject **argnames[],
6010 Py_ssize_t num_pos_args,
6011 const char* function_name)
6013 PyObject *key = 0, *value = 0;
6016 PyObject*** first_kw_arg = argnames + num_pos_args;
6018 while (PyDict_Next(kwds, &pos, &key, &value)) {
6019 name = first_kw_arg;
6020 while (*name && (**name != key)) name++;
6022 values[name-argnames] = value;
6024 #if PY_MAJOR_VERSION < 3
6025 if (unlikely(!PyString_CheckExact(key)) && unlikely(!PyString_Check(key))) {
6027 if (unlikely(!PyUnicode_CheckExact(key)) && unlikely(!PyUnicode_Check(key))) {
6029 goto invalid_keyword_type;
6031 for (name = first_kw_arg; *name; name++) {
6032 #if PY_MAJOR_VERSION >= 3
6033 if (PyUnicode_GET_SIZE(**name) == PyUnicode_GET_SIZE(key) &&
6034 PyUnicode_Compare(**name, key) == 0) break;
6036 if (PyString_GET_SIZE(**name) == PyString_GET_SIZE(key) &&
6037 _PyString_Eq(**name, key)) break;
6041 values[name-argnames] = value;
6043 /* unexpected keyword found */
6044 for (name=argnames; name != first_kw_arg; name++) {
6045 if (**name == key) goto arg_passed_twice;
6046 #if PY_MAJOR_VERSION >= 3
6047 if (PyUnicode_GET_SIZE(**name) == PyUnicode_GET_SIZE(key) &&
6048 PyUnicode_Compare(**name, key) == 0) goto arg_passed_twice;
6050 if (PyString_GET_SIZE(**name) == PyString_GET_SIZE(key) &&
6051 _PyString_Eq(**name, key)) goto arg_passed_twice;
6055 if (unlikely(PyDict_SetItem(kwds2, key, value))) goto bad;
6057 goto invalid_keyword;
6065 __Pyx_RaiseDoubleKeywordsError(function_name, **name);
6067 invalid_keyword_type:
6068 PyErr_Format(PyExc_TypeError,
6069 "%s() keywords must be strings", function_name);
6072 PyErr_Format(PyExc_TypeError,
6073 #if PY_MAJOR_VERSION < 3
6074 "%s() got an unexpected keyword argument '%s'",
6075 function_name, PyString_AsString(key));
6077 "%s() got an unexpected keyword argument '%U'",
6078 function_name, key);
6085 #------------------------------------------------------------------------------------
6087 traceback_utility_code = UtilityCode(
6089 static void __Pyx_AddTraceback(const char *funcname); /*proto*/
6092 #include "compile.h"
6093 #include "frameobject.h"
6094 #include "traceback.h"
6096 static void __Pyx_AddTraceback(const char *funcname) {
6097 PyObject *py_srcfile = 0;
6098 PyObject *py_funcname = 0;
6099 PyObject *py_globals = 0;
6100 PyCodeObject *py_code = 0;
6101 PyFrameObject *py_frame = 0;
6103 #if PY_MAJOR_VERSION < 3
6104 py_srcfile = PyString_FromString(%(FILENAME)s);
6106 py_srcfile = PyUnicode_FromString(%(FILENAME)s);
6108 if (!py_srcfile) goto bad;
6110 #if PY_MAJOR_VERSION < 3
6111 py_funcname = PyString_FromFormat( "%%s (%%s:%%d)", funcname, %(CFILENAME)s, %(CLINENO)s);
6113 py_funcname = PyUnicode_FromFormat( "%%s (%%s:%%d)", funcname, %(CFILENAME)s, %(CLINENO)s);
6117 #if PY_MAJOR_VERSION < 3
6118 py_funcname = PyString_FromString(funcname);
6120 py_funcname = PyUnicode_FromString(funcname);
6123 if (!py_funcname) goto bad;
6124 py_globals = PyModule_GetDict(%(GLOBALS)s);
6125 if (!py_globals) goto bad;
6126 py_code = PyCode_New(
6127 0, /*int argcount,*/
6128 #if PY_MAJOR_VERSION >= 3
6129 0, /*int kwonlyargcount,*/
6132 0, /*int stacksize,*/
6134 %(EMPTY_BYTES)s, /*PyObject *code,*/
6135 %(EMPTY_TUPLE)s, /*PyObject *consts,*/
6136 %(EMPTY_TUPLE)s, /*PyObject *names,*/
6137 %(EMPTY_TUPLE)s, /*PyObject *varnames,*/
6138 %(EMPTY_TUPLE)s, /*PyObject *freevars,*/
6139 %(EMPTY_TUPLE)s, /*PyObject *cellvars,*/
6140 py_srcfile, /*PyObject *filename,*/
6141 py_funcname, /*PyObject *name,*/
6142 %(LINENO)s, /*int firstlineno,*/
6143 %(EMPTY_BYTES)s /*PyObject *lnotab*/
6145 if (!py_code) goto bad;
6146 py_frame = PyFrame_New(
6147 PyThreadState_GET(), /*PyThreadState *tstate,*/
6148 py_code, /*PyCodeObject *code,*/
6149 py_globals, /*PyObject *globals,*/
6150 0 /*PyObject *locals*/
6152 if (!py_frame) goto bad;
6153 py_frame->f_lineno = %(LINENO)s;
6154 PyTraceBack_Here(py_frame);
6156 Py_XDECREF(py_srcfile);
6157 Py_XDECREF(py_funcname);
6158 Py_XDECREF(py_code);
6159 Py_XDECREF(py_frame);
6162 'FILENAME': Naming.filename_cname,
6163 'LINENO': Naming.lineno_cname,
6164 'CFILENAME': Naming.cfilenm_cname,
6165 'CLINENO': Naming.clineno_cname,
6166 'GLOBALS': Naming.module_cname,
6167 'EMPTY_TUPLE' : Naming.empty_tuple,
6168 'EMPTY_BYTES' : Naming.empty_bytes,
6171 #------------------------------------------------------------------------------------
6173 unraisable_exception_utility_code = UtilityCode(
6175 static void __Pyx_WriteUnraisable(const char *name); /*proto*/
6178 static void __Pyx_WriteUnraisable(const char *name) {
6179 PyObject *old_exc, *old_val, *old_tb;
6181 __Pyx_ErrFetch(&old_exc, &old_val, &old_tb);
6182 #if PY_MAJOR_VERSION < 3
6183 ctx = PyString_FromString(name);
6185 ctx = PyUnicode_FromString(name);
6187 __Pyx_ErrRestore(old_exc, old_val, old_tb);
6189 PyErr_WriteUnraisable(Py_None);
6191 PyErr_WriteUnraisable(ctx);
6196 requires=[restore_exception_utility_code])
6198 #------------------------------------------------------------------------------------
6200 set_vtable_utility_code = UtilityCode(
6202 static int __Pyx_SetVtable(PyObject *dict, void *vtable); /*proto*/
6205 static int __Pyx_SetVtable(PyObject *dict, void *vtable) {
6206 #if PY_VERSION_HEX >= 0x02070000 && !(PY_MAJOR_VERSION==3&&PY_MINOR_VERSION==0)
6207 PyObject *ob = PyCapsule_New(vtable, 0, 0);
6209 PyObject *ob = PyCObject_FromVoidPtr(vtable, 0);
6213 if (PyDict_SetItemString(dict, "__pyx_vtable__", ob) < 0)
6223 #------------------------------------------------------------------------------------
6225 get_vtable_utility_code = UtilityCode(
6227 static int __Pyx_GetVtable(PyObject *dict, void *vtabptr); /*proto*/
6230 static int __Pyx_GetVtable(PyObject *dict, void *vtabptr) {
6231 PyObject *ob = PyMapping_GetItemString(dict, (char *)"__pyx_vtable__");
6234 #if PY_VERSION_HEX >= 0x02070000 && !(PY_MAJOR_VERSION==3&&PY_MINOR_VERSION==0)
6235 *(void **)vtabptr = PyCapsule_GetPointer(ob, 0);
6237 *(void **)vtabptr = PyCObject_AsVoidPtr(ob);
6239 if (!*(void **)vtabptr)
6249 #------------------------------------------------------------------------------------
6251 init_string_tab_utility_code = UtilityCode(
6253 static int __Pyx_InitStrings(__Pyx_StringTabEntry *t); /*proto*/
6256 static int __Pyx_InitStrings(__Pyx_StringTabEntry *t) {
6258 #if PY_MAJOR_VERSION < 3
6259 if (t->is_unicode) {
6260 *t->p = PyUnicode_DecodeUTF8(t->s, t->n - 1, NULL);
6261 } else if (t->intern) {
6262 *t->p = PyString_InternFromString(t->s);
6264 *t->p = PyString_FromStringAndSize(t->s, t->n - 1);
6266 #else /* Python 3+ has unicode identifiers */
6267 if (t->is_unicode | t->is_str) {
6269 *t->p = PyUnicode_InternFromString(t->s);
6270 } else if (t->encoding) {
6271 *t->p = PyUnicode_Decode(t->s, t->n - 1, t->encoding, NULL);
6273 *t->p = PyUnicode_FromStringAndSize(t->s, t->n - 1);
6276 *t->p = PyBytes_FromStringAndSize(t->s, t->n - 1);
6287 #------------------------------------------------------------------------------------
6289 force_init_threads_utility_code = UtilityCode(
6291 #ifndef __PYX_FORCE_INIT_THREADS
6292 #if PY_VERSION_HEX < 0x02040200
6293 #define __PYX_FORCE_INIT_THREADS 1
6295 #define __PYX_FORCE_INIT_THREADS 0
6300 #------------------------------------------------------------------------------------
6302 # Note that cPython ignores PyTrace_EXCEPTION,
6303 # but maybe some other profilers don't.
6305 profile_utility_code = UtilityCode(proto="""
6306 #ifndef CYTHON_PROFILE
6307 #define CYTHON_PROFILE 1
6310 #ifndef CYTHON_PROFILE_REUSE_FRAME
6311 #define CYTHON_PROFILE_REUSE_FRAME 0
6316 #include "compile.h"
6317 #include "frameobject.h"
6318 #include "traceback.h"
6320 #if CYTHON_PROFILE_REUSE_FRAME
6321 #define CYTHON_FRAME_MODIFIER static
6322 #define CYTHON_FRAME_DEL
6324 #define CYTHON_FRAME_MODIFIER
6325 #define CYTHON_FRAME_DEL Py_DECREF(%(FRAME)s)
6328 #define __Pyx_TraceDeclarations \\
6329 static PyCodeObject *%(FRAME_CODE)s = NULL; \\
6330 CYTHON_FRAME_MODIFIER PyFrameObject *%(FRAME)s = NULL; \\
6331 int __Pyx_use_tracing = 0;
6333 #define __Pyx_TraceCall(funcname, srcfile, firstlineno) \\
6334 if (unlikely(PyThreadState_GET()->use_tracing && PyThreadState_GET()->c_profilefunc)) { \\
6335 __Pyx_use_tracing = __Pyx_TraceSetupAndCall(&%(FRAME_CODE)s, &%(FRAME)s, funcname, srcfile, firstlineno); \\
6338 #define __Pyx_TraceException() \\
6339 if (unlikely(__Pyx_use_tracing( && PyThreadState_GET()->use_tracing && PyThreadState_GET()->c_profilefunc) { \\
6340 PyObject *exc_info = __Pyx_GetExceptionTuple(); \\
6342 PyThreadState_GET()->c_profilefunc( \\
6343 PyThreadState_GET()->c_profileobj, %(FRAME)s, PyTrace_EXCEPTION, exc_info); \\
6344 Py_DECREF(exc_info); \\
6348 #define __Pyx_TraceReturn(result) \\
6349 if (unlikely(__Pyx_use_tracing) && PyThreadState_GET()->use_tracing && PyThreadState_GET()->c_profilefunc) { \\
6350 PyThreadState_GET()->c_profilefunc( \\
6351 PyThreadState_GET()->c_profileobj, %(FRAME)s, PyTrace_RETURN, (PyObject*)result); \\
6352 CYTHON_FRAME_DEL; \\
6355 static PyCodeObject *__Pyx_createFrameCodeObject(const char *funcname, const char *srcfile, int firstlineno); /*proto*/
6356 static int __Pyx_TraceSetupAndCall(PyCodeObject** code, PyFrameObject** frame, const char *funcname, const char *srcfile, int firstlineno); /*proto*/
6360 #define __Pyx_TraceDeclarations
6361 #define __Pyx_TraceCall(funcname, srcfile, firstlineno)
6362 #define __Pyx_TraceException()
6363 #define __Pyx_TraceReturn(result)
6365 #endif /* CYTHON_PROFILE */
6368 "FRAME": Naming.frame_cname,
6369 "FRAME_CODE": Naming.frame_code_cname,
6375 static int __Pyx_TraceSetupAndCall(PyCodeObject** code,
6376 PyFrameObject** frame,
6377 const char *funcname,
6378 const char *srcfile,
6380 if (*frame == NULL || !CYTHON_PROFILE_REUSE_FRAME) {
6381 if (*code == NULL) {
6382 *code = __Pyx_createFrameCodeObject(funcname, srcfile, firstlineno);
6383 if (*code == NULL) return 0;
6385 *frame = PyFrame_New(
6386 PyThreadState_GET(), /*PyThreadState *tstate*/
6387 *code, /*PyCodeObject *code*/
6388 PyModule_GetDict(%(MODULE)s), /*PyObject *globals*/
6389 0 /*PyObject *locals*/
6391 if (*frame == NULL) return 0;
6394 (*frame)->f_tstate = PyThreadState_GET();
6396 return PyThreadState_GET()->c_profilefunc(PyThreadState_GET()->c_profileobj, *frame, PyTrace_CALL, NULL) == 0;
6399 static PyCodeObject *__Pyx_createFrameCodeObject(const char *funcname, const char *srcfile, int firstlineno) {
6400 PyObject *py_srcfile = 0;
6401 PyObject *py_funcname = 0;
6402 PyCodeObject *py_code = 0;
6404 #if PY_MAJOR_VERSION < 3
6405 py_funcname = PyString_FromString(funcname);
6406 py_srcfile = PyString_FromString(srcfile);
6408 py_funcname = PyUnicode_FromString(funcname);
6409 py_srcfile = PyUnicode_FromString(srcfile);
6411 if (!py_funcname | !py_srcfile) goto bad;
6413 py_code = PyCode_New(
6414 0, /*int argcount,*/
6415 #if PY_MAJOR_VERSION >= 3
6416 0, /*int kwonlyargcount,*/
6419 0, /*int stacksize,*/
6421 %(EMPTY_BYTES)s, /*PyObject *code,*/
6422 %(EMPTY_TUPLE)s, /*PyObject *consts,*/
6423 %(EMPTY_TUPLE)s, /*PyObject *names,*/
6424 %(EMPTY_TUPLE)s, /*PyObject *varnames,*/
6425 %(EMPTY_TUPLE)s, /*PyObject *freevars,*/
6426 %(EMPTY_TUPLE)s, /*PyObject *cellvars,*/
6427 py_srcfile, /*PyObject *filename,*/
6428 py_funcname, /*PyObject *name,*/
6429 firstlineno, /*int firstlineno,*/
6430 %(EMPTY_BYTES)s /*PyObject *lnotab*/
6434 Py_XDECREF(py_srcfile);
6435 Py_XDECREF(py_funcname);
6440 #endif /* CYTHON_PROFILE */
6442 'EMPTY_TUPLE' : Naming.empty_tuple,
6443 'EMPTY_BYTES' : Naming.empty_bytes,
6444 "MODULE": Naming.module_cname,