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_cfunction:
612 "Function cannot return a function")
613 func_type = PyrexTypes.CFuncType(
614 return_type, func_type_args, self.has_varargs,
615 optional_arg_count = self.optional_arg_count,
616 exception_value = exc_val, exception_check = exc_check,
617 calling_convention = self.base.calling_convention,
618 nogil = self.nogil, with_gil = self.with_gil, is_overridable = self.overridable)
619 if self.optional_arg_count:
620 func_type.op_arg_struct = PyrexTypes.c_ptr_type(self.op_args_struct.type)
621 callspec = env.directives['callspec']
623 current = func_type.calling_convention
624 if current and current != callspec:
625 error(self.pos, "cannot have both '%s' and '%s' "
626 "calling conventions" % (current, callspec))
627 func_type.calling_convention = callspec
628 return self.base.analyse(func_type, env)
631 class CArgDeclNode(Node):
632 # Item in a function declaration argument list.
634 # base_type CBaseTypeNode
635 # declarator CDeclaratorNode
636 # not_none boolean Tagged with 'not None'
637 # or_none boolean Tagged with 'or None'
638 # accept_none boolean Resolved boolean for not_none/or_none
639 # default ExprNode or None
640 # default_value PyObjectConst constant for default value
641 # annotation ExprNode or None Py3 function arg annotation
642 # is_self_arg boolean Is the "self" arg of an extension type method
643 # is_type_arg boolean Is the "class" arg of an extension type classmethod
644 # is_kw_only boolean Is a keyword-only argument
646 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 is_basic_c_type = False
743 def analyse(self, env, could_be_name = False):
744 # Return type descriptor.
745 #print "CSimpleBaseTypeNode.analyse: is_self_arg =", self.is_self_arg ###
747 if self.is_basic_c_type:
748 type = PyrexTypes.simple_c_type(self.signed, self.longness, self.name)
750 error(self.pos, "Unrecognised type modifier combination")
751 elif self.name == "object" and not self.module_path:
752 type = py_object_type
753 elif self.name is None:
754 if self.is_self_arg and env.is_c_class_scope:
755 #print "CSimpleBaseTypeNode.analyse: defaulting to parent type" ###
756 type = env.parent_type
757 ## elif self.is_type_arg and env.is_c_class_scope:
758 ## type = Builtin.type_type
760 type = py_object_type
763 scope = env.find_imported_module(self.module_path, self.pos)
767 if scope.is_c_class_scope:
768 scope = scope.global_scope()
769 entry = scope.lookup(self.name)
770 if entry and entry.is_type:
773 if self.is_self_arg and env.is_c_class_scope:
774 type = env.parent_type
775 ## elif self.is_type_arg and env.is_c_class_scope:
776 ## type = Builtin.type_type
778 type = py_object_type
779 self.arg_name = self.name
782 if not self.name in self.templates:
783 error(self.pos, "'%s' is not a type identifier" % self.name)
784 type = PyrexTypes.TemplatePlaceholderType(self.name)
786 error(self.pos, "'%s' is not a type identifier" % self.name)
788 if not type.is_numeric or type.is_complex:
789 error(self.pos, "can only complexify c numeric types")
790 type = PyrexTypes.CComplexType(type)
791 type.create_declaration_utility_code(env)
792 elif type is Builtin.complex_type:
793 # Special case: optimise builtin complex type into C's
794 # double complex. The parser cannot do this (as for the
795 # normal scalar types) as the user may have redeclared the
796 # 'complex' type. Testing for the exact type here works.
797 type = PyrexTypes.c_double_complex_type
798 type.create_declaration_utility_code(env)
803 return PyrexTypes.error_type
805 class CNestedBaseTypeNode(CBaseTypeNode):
806 # For C++ classes that live inside other C++ classes.
809 # base_type CBaseTypeNode
811 child_attrs = ['base_type']
813 def analyse(self, env, could_be_name = None):
814 base_type = self.base_type.analyse(env)
815 if base_type is PyrexTypes.error_type:
816 return PyrexTypes.error_type
817 if not base_type.is_cpp_class:
818 error(self.pos, "'%s' is not a valid type scope" % base_type)
819 return PyrexTypes.error_type
820 type_entry = base_type.scope.lookup_here(self.name)
821 if not type_entry or not type_entry.is_type:
822 error(self.pos, "'%s.%s' is not a type identifier" % (base_type, self.name))
823 return PyrexTypes.error_type
824 return type_entry.type
826 class TemplatedTypeNode(CBaseTypeNode):
828 # positional_args [ExprNode] List of positional arguments
829 # keyword_args DictNode Keyword arguments
830 # base_type_node CBaseTypeNode
833 # type PyrexTypes.BufferType or PyrexTypes.CppClassType ...containing the right options
836 child_attrs = ["base_type_node", "positional_args",
837 "keyword_args", "dtype_node"]
843 def analyse(self, env, could_be_name = False, base_type = None):
844 if base_type is None:
845 base_type = self.base_type_node.analyse(env)
846 if base_type.is_error: return base_type
848 if base_type.is_cpp_class:
850 if self.keyword_args and self.keyword_args.key_value_pairs:
851 error(self.pos, "c++ templates cannot take keyword arguments");
852 self.type = PyrexTypes.error_type
855 for template_node in self.positional_args:
856 type = template_node.analyse_as_type(env)
858 error(template_node.pos, "unknown type in template argument")
860 template_types.append(type)
861 self.type = base_type.specialize_here(self.pos, template_types)
863 elif base_type.is_pyobject:
867 options = Buffer.analyse_buffer_options(
870 self.positional_args,
872 base_type.buffer_defaults)
874 if sys.version_info[0] < 3:
875 # Py 2.x enforces byte strings as keyword arguments ...
876 options = dict([ (name.encode('ASCII'), value)
877 for name, value in options.items() ])
879 self.type = PyrexTypes.BufferType(base_type, **options)
883 empty_declarator = CNameDeclaratorNode(self.pos, name="", cname=None)
884 if len(self.positional_args) > 1 or self.keyword_args.key_value_pairs:
885 error(self.pos, "invalid array declaration")
886 self.type = PyrexTypes.error_type
888 # It would be nice to merge this class with CArrayDeclaratorNode,
889 # but arrays are part of the declaration, not the type...
890 if not self.positional_args:
893 dimension = self.positional_args[0]
894 self.array_declarator = CArrayDeclaratorNode(self.pos,
895 base = empty_declarator,
896 dimension = dimension)
897 self.type = self.array_declarator.analyse(base_type, env)[1]
901 class CComplexBaseTypeNode(CBaseTypeNode):
902 # base_type CBaseTypeNode
903 # declarator CDeclaratorNode
905 child_attrs = ["base_type", "declarator"]
907 def analyse(self, env, could_be_name = False):
908 base = self.base_type.analyse(env, could_be_name)
909 _, type = self.declarator.analyse(base, env)
913 class CVarDefNode(StatNode):
914 # C variable definition or forward/extern function declaration.
916 # visibility 'private' or 'public' or 'extern'
917 # base_type CBaseTypeNode
918 # declarators [CDeclaratorNode]
922 # decorators [cython.locals(...)] or None
923 # directive_locals { string : NameNode } locals defined by cython.locals(...)
925 child_attrs = ["base_type", "declarators"]
928 directive_locals = {}
930 def analyse_declarations(self, env, dest_scope = None):
933 self.dest_scope = dest_scope
934 base_type = self.base_type.analyse(env)
936 # If the field is an external typedef, we cannot be sure about the type,
937 # so do conversion ourself rather than rely on the CPython mechanism (through
938 # a property; made in AnalyseDeclarationsTransform).
939 if (dest_scope.is_c_class_scope
940 and self.visibility in ('public', 'readonly')):
943 need_property = False
944 visibility = self.visibility
946 for declarator in self.declarators:
947 name_declarator, type = declarator.analyse(base_type, env)
948 if not type.is_complete():
949 if not (self.visibility == 'extern' and type.is_array):
950 error(declarator.pos,
951 "Variable type '%s' is incomplete" % type)
952 if self.visibility == 'extern' and type.is_pyobject:
953 error(declarator.pos,
954 "Python object cannot be declared extern")
955 name = name_declarator.name
956 cname = name_declarator.cname
958 error(declarator.pos, "Missing name in declaration.")
960 if type.is_cfunction:
961 entry = dest_scope.declare_cfunction(name, type, declarator.pos,
962 cname = cname, visibility = self.visibility, in_pxd = self.in_pxd,
964 if entry is not None:
965 entry.directive_locals = self.directive_locals
967 if self.directive_locals:
968 error(self.pos, "Decorators can only be followed by functions")
969 if self.in_pxd and self.visibility != 'extern':
971 "Only 'extern' C variable declaration allowed in .pxd file")
972 entry = dest_scope.declare_var(name, type, declarator.pos,
973 cname = cname, visibility = visibility, is_cdef = 1)
974 entry.needs_property = need_property
977 class CStructOrUnionDefNode(StatNode):
979 # cname string or None
980 # kind "struct" or "union"
981 # typedef_flag boolean
982 # visibility "public" or "private"
984 # attributes [CVarDefNode] or None
988 child_attrs = ["attributes"]
990 def analyse_declarations(self, env):
992 if self.visibility == 'extern' and self.packed:
993 error(self.pos, "Cannot declare extern struct as 'packed'")
994 if self.attributes is not None:
995 scope = StructOrUnionScope(self.name)
996 self.entry = env.declare_struct_or_union(
997 self.name, self.kind, scope, self.typedef_flag, self.pos,
998 self.cname, visibility = self.visibility, packed = self.packed)
999 if self.attributes is not None:
1000 if self.in_pxd and not env.in_cinclude:
1001 self.entry.defined_in_pxd = 1
1002 for attr in self.attributes:
1003 attr.analyse_declarations(env, scope)
1004 if self.visibility != 'extern':
1005 need_typedef_indirection = False
1006 for attr in scope.var_entries:
1008 while type.is_array:
1009 type = type.base_type
1010 if type == self.entry.type:
1011 error(attr.pos, "Struct cannot contain itself as a member.")
1012 if self.typedef_flag:
1014 type = type.base_type
1015 if type == self.entry.type:
1016 need_typedef_indirection = True
1017 if need_typedef_indirection:
1018 # C can't handle typedef structs that refer to themselves.
1019 struct_entry = self.entry
1020 self.entry = env.declare_typedef(
1021 self.name, struct_entry.type, self.pos,
1022 cname = self.cname, visibility='ignore')
1023 struct_entry.type.typedef_flag = False
1024 # FIXME: this might be considered a hack ;-)
1025 struct_entry.cname = struct_entry.type.cname = \
1026 '_' + self.entry.type.typedef_cname
1028 def analyse_expressions(self, env):
1031 def generate_execution_code(self, code):
1035 class CppClassNode(CStructOrUnionDefNode):
1038 # cname string or None
1039 # visibility "extern"
1041 # attributes [CVarDefNode] or None
1043 # base_classes [string]
1044 # templates [string] or None
1046 def analyse_declarations(self, env):
1048 if self.attributes is not None:
1049 scope = CppClassScope(self.name, env)
1050 base_class_types = []
1051 for base_class_name in self.base_classes:
1052 base_class_entry = env.lookup(base_class_name)
1053 if base_class_entry is None:
1054 error(self.pos, "'%s' not found" % base_class_name)
1055 elif not base_class_entry.is_type or not base_class_entry.type.is_cpp_class:
1056 error(self.pos, "'%s' is not a cpp class type" % base_class_name)
1058 base_class_types.append(base_class_entry.type)
1059 if self.templates is None:
1060 template_types = None
1062 template_types = [PyrexTypes.TemplatePlaceholderType(template_name) for template_name in self.templates]
1063 self.entry = env.declare_cpp_class(
1064 self.name, scope, self.pos,
1065 self.cname, base_class_types, visibility = self.visibility, templates = template_types)
1066 if self.entry is None:
1068 self.entry.is_cpp_class = 1
1069 if self.attributes is not None:
1070 if self.in_pxd and not env.in_cinclude:
1071 self.entry.defined_in_pxd = 1
1072 for attr in self.attributes:
1073 attr.analyse_declarations(scope)
1075 class CEnumDefNode(StatNode):
1076 # name string or None
1077 # cname string or None
1078 # items [CEnumDefItemNode]
1079 # typedef_flag boolean
1080 # visibility "public" or "private"
1084 child_attrs = ["items"]
1086 def analyse_declarations(self, env):
1087 self.entry = env.declare_enum(self.name, self.pos,
1088 cname = self.cname, typedef_flag = self.typedef_flag,
1089 visibility = self.visibility)
1090 if self.items is not None:
1091 if self.in_pxd and not env.in_cinclude:
1092 self.entry.defined_in_pxd = 1
1093 for item in self.items:
1094 item.analyse_declarations(env, self.entry)
1096 def analyse_expressions(self, env):
1099 def generate_execution_code(self, code):
1100 if self.visibility == 'public':
1101 temp = code.funcstate.allocate_temp(PyrexTypes.py_object_type, manage_ref=True)
1102 for item in self.entry.enum_values:
1103 code.putln("%s = PyInt_FromLong(%s); %s" % (
1106 code.error_goto_if_null(temp, item.pos)))
1107 code.put_gotref(temp)
1108 code.putln('if (__Pyx_SetAttrString(%s, "%s", %s) < 0) %s' % (
1109 Naming.module_cname,
1112 code.error_goto(item.pos)))
1113 code.put_decref_clear(temp, PyrexTypes.py_object_type)
1114 code.funcstate.release_temp(temp)
1117 class CEnumDefItemNode(StatNode):
1119 # cname string or None
1120 # value ExprNode or None
1122 child_attrs = ["value"]
1124 def analyse_declarations(self, env, enum_entry):
1126 self.value.analyse_const_expression(env)
1127 if not self.value.type.is_int:
1128 self.value = self.value.coerce_to(PyrexTypes.c_int_type, env)
1129 self.value.analyse_const_expression(env)
1130 entry = env.declare_const(self.name, enum_entry.type,
1131 self.value, self.pos, cname = self.cname,
1132 visibility = enum_entry.visibility)
1133 enum_entry.enum_values.append(entry)
1136 class CTypeDefNode(StatNode):
1137 # base_type CBaseTypeNode
1138 # declarator CDeclaratorNode
1139 # visibility "public" or "private"
1142 child_attrs = ["base_type", "declarator"]
1144 def analyse_declarations(self, env):
1145 base = self.base_type.analyse(env)
1146 name_declarator, type = self.declarator.analyse(base, env)
1147 name = name_declarator.name
1148 cname = name_declarator.cname
1149 entry = env.declare_typedef(name, type, self.pos,
1150 cname = cname, visibility = self.visibility)
1151 if self.in_pxd and not env.in_cinclude:
1152 entry.defined_in_pxd = 1
1154 def analyse_expressions(self, env):
1156 def generate_execution_code(self, code):
1160 class FuncDefNode(StatNode, BlockNode):
1161 # Base class for function definition nodes.
1163 # return_type PyrexType
1164 # #filename string C name of filename string const
1165 # entry Symtab.Entry
1166 # needs_closure boolean Whether or not this function has inner functions/classes/yield
1167 # needs_outer_scope boolean Whether or not this function requires outer scope
1168 # directive_locals { string : NameNode } locals defined by cython.locals(...)
1172 needs_closure = False
1173 needs_outer_scope = False
1176 def analyse_default_values(self, env):
1177 genv = env.global_scope()
1179 for arg in self.args:
1183 arg.default.analyse_types(env)
1184 arg.default = arg.default.coerce_to(arg.type, genv)
1187 "This argument cannot have a default value")
1192 error(arg.pos, "Non-default argument following default argument")
1194 def need_gil_acquisition(self, lenv):
1197 def create_local_scope(self, env):
1199 while genv.is_py_class_scope or genv.is_c_class_scope:
1200 genv = genv.outer_scope
1201 if self.needs_closure:
1202 lenv = ClosureScope(name=self.entry.name,
1204 scope_name=self.entry.cname)
1206 lenv = LocalScope(name=self.entry.name,
1209 lenv.return_type = self.return_type
1210 type = self.entry.type
1211 if type.is_cfunction:
1212 lenv.nogil = type.nogil and not type.with_gil
1213 self.local_scope = lenv
1214 lenv.directives = env.directives
1217 def generate_function_definitions(self, env, code):
1220 lenv = self.local_scope
1221 if lenv.is_closure_scope and not lenv.is_passthrough:
1222 outer_scope_cname = "%s->%s" % (Naming.cur_scope_cname,
1223 Naming.outer_scope_cname)
1225 outer_scope_cname = Naming.outer_scope_cname
1226 lenv.mangle_closure_cnames(outer_scope_cname)
1227 # Generate closure function definitions
1228 self.body.generate_function_definitions(lenv, code)
1229 # generate lambda function definitions
1230 self.generate_lambda_definitions(lenv, code)
1232 is_getbuffer_slot = (self.entry.name == "__getbuffer__" and
1233 self.entry.scope.is_c_class_scope)
1234 is_releasebuffer_slot = (self.entry.name == "__releasebuffer__" and
1235 self.entry.scope.is_c_class_scope)
1236 is_buffer_slot = is_getbuffer_slot or is_releasebuffer_slot
1238 if 'cython_unused' not in self.modifiers:
1239 self.modifiers = self.modifiers + ['cython_unused']
1241 preprocessor_guard = None
1242 if self.entry.is_special and not is_buffer_slot:
1243 slot = TypeSlots.method_name_to_slot.get(self.entry.name)
1245 preprocessor_guard = slot.preprocessor_guard_code()
1246 if (self.entry.name == '__long__' and
1247 not self.entry.scope.lookup_here('__int__')):
1248 preprocessor_guard = None
1250 profile = code.globalstate.directives['profile']
1253 error(self.pos, "Cannot profile nogil function.")
1254 code.globalstate.use_utility_code(profile_utility_code)
1256 # Generate C code for header and body of function
1257 code.enter_cfunc_scope()
1258 code.return_from_error_cleanup_label = code.new_label()
1260 # ----- Top-level constants used by this function
1261 code.mark_pos(self.pos)
1262 self.generate_cached_builtins_decls(lenv, code)
1263 # ----- Function header
1266 if preprocessor_guard:
1267 code.putln(preprocessor_guard)
1269 with_pymethdef = self.needs_assignment_synthesis(env, code)
1271 self.py_func.generate_function_header(code,
1272 with_pymethdef = with_pymethdef,
1274 self.generate_function_header(code,
1275 with_pymethdef = with_pymethdef)
1276 # ----- Local variable declarations
1277 # Find function scope
1279 while cenv.is_py_class_scope or cenv.is_c_class_scope:
1280 cenv = cenv.outer_scope
1281 if self.needs_closure:
1282 code.put(lenv.scope_class.type.declaration_code(Naming.cur_scope_cname))
1284 elif self.needs_outer_scope:
1285 if lenv.is_passthrough:
1286 code.put(lenv.scope_class.type.declaration_code(Naming.cur_scope_cname))
1288 code.put(cenv.scope_class.type.declaration_code(Naming.outer_scope_cname))
1290 self.generate_argument_declarations(lenv, code)
1291 for entry in lenv.var_entries:
1292 if not entry.in_closure:
1293 code.put_var_declaration(entry)
1295 if not self.return_type.is_void:
1296 if self.return_type.is_pyobject:
1300 (self.return_type.declaration_code(Naming.retval_cname),
1302 tempvardecl_code = code.insertion_point()
1303 self.generate_keyword_list(code)
1305 code.put_trace_declarations()
1306 # ----- Extern library function declarations
1307 lenv.generate_library_function_declarations(code)
1308 # ----- GIL acquisition
1309 acquire_gil = self.acquire_gil
1311 env.use_utility_code(force_init_threads_utility_code)
1312 code.putln("#ifdef WITH_THREAD")
1313 code.putln("PyGILState_STATE _save = PyGILState_Ensure();")
1314 code.putln("#endif")
1315 # ----- set up refnanny
1317 code.put_setup_refcount_context(self.entry.name)
1318 # ----- Automatic lead-ins for certain special functions
1319 if is_getbuffer_slot:
1320 self.getbuffer_init(code)
1321 # ----- Create closure scope object
1322 if self.needs_closure:
1323 code.putln("%s = (%s)%s->tp_new(%s, %s, NULL);" % (
1324 Naming.cur_scope_cname,
1325 lenv.scope_class.type.declaration_code(''),
1326 lenv.scope_class.type.typeptr_cname,
1327 lenv.scope_class.type.typeptr_cname,
1328 Naming.empty_tuple))
1329 code.putln("if (unlikely(!%s)) {" % Naming.cur_scope_cname)
1330 if is_getbuffer_slot:
1331 self.getbuffer_error_cleanup(code)
1333 code.put_finish_refcount_context()
1334 # FIXME: what if the error return value is a Python value?
1335 code.putln("return %s;" % self.error_value())
1337 code.put_gotref(Naming.cur_scope_cname)
1338 # Note that it is unsafe to decref the scope at this point.
1339 if self.needs_outer_scope:
1340 code.putln("%s = (%s)%s;" % (
1342 cenv.scope_class.type.declaration_code(''),
1344 if lenv.is_passthrough:
1345 code.putln("%s = %s;" % (Naming.cur_scope_cname, outer_scope_cname));
1346 elif self.needs_closure:
1347 # inner closures own a reference to their outer parent
1348 code.put_incref(outer_scope_cname, cenv.scope_class.type)
1349 code.put_giveref(outer_scope_cname)
1350 # ----- Trace function call
1352 # this looks a bit late, but if we don't get here due to a
1353 # fatal error before hand, it's not really worth tracing
1354 code.put_trace_call(self.entry.name, self.pos)
1355 # ----- Fetch arguments
1356 self.generate_argument_parsing_code(env, code)
1357 # If an argument is assigned to in the body, we must
1358 # incref it to properly keep track of refcounts.
1359 for entry in lenv.arg_entries:
1360 if entry.type.is_pyobject:
1361 if (acquire_gil or entry.assignments) and not entry.in_closure:
1362 code.put_var_incref(entry)
1363 # ----- Initialise local variables
1364 for entry in lenv.var_entries:
1365 if entry.type.is_pyobject and entry.init_to_none and entry.used:
1366 code.put_init_var_to_py_none(entry)
1367 # ----- Initialise local buffer auxiliary variables
1368 for entry in lenv.var_entries + lenv.arg_entries:
1369 if entry.type.is_buffer and entry.buffer_aux.buffer_info_var.used:
1370 code.putln("%s.buf = NULL;" %
1371 entry.buffer_aux.buffer_info_var.cname)
1372 # ----- Check and convert arguments
1373 self.generate_argument_type_tests(code)
1374 # ----- Acquire buffer arguments
1375 for entry in lenv.arg_entries:
1376 if entry.type.is_buffer:
1377 Buffer.put_acquire_arg_buffer(entry, code, self.pos)
1379 # -------------------------
1380 # ----- Function body -----
1381 # -------------------------
1382 self.body.generate_execution_code(code)
1384 # ----- Default return value
1386 if self.return_type.is_pyobject:
1387 #if self.return_type.is_extension_type:
1388 # lhs = "(PyObject *)%s" % Naming.retval_cname
1390 lhs = Naming.retval_cname
1391 code.put_init_to_py_none(lhs, self.return_type)
1393 val = self.return_type.default_value
1395 code.putln("%s = %s;" % (Naming.retval_cname, val))
1396 # ----- Error cleanup
1397 if code.error_label in code.labels_used:
1398 code.put_goto(code.return_label)
1399 code.put_label(code.error_label)
1400 for cname, type in code.funcstate.all_managed_temps():
1401 code.put_xdecref(cname, type)
1403 # Clean up buffers -- this calls a Python function
1404 # so need to save and restore error state
1405 buffers_present = len(lenv.buffer_entries) > 0
1407 code.globalstate.use_utility_code(restore_exception_utility_code)
1408 code.putln("{ PyObject *__pyx_type, *__pyx_value, *__pyx_tb;")
1409 code.putln("__Pyx_ErrFetch(&__pyx_type, &__pyx_value, &__pyx_tb);")
1410 for entry in lenv.buffer_entries:
1411 Buffer.put_release_buffer_code(code, entry)
1412 #code.putln("%s = 0;" % entry.cname)
1413 code.putln("__Pyx_ErrRestore(__pyx_type, __pyx_value, __pyx_tb);}")
1415 err_val = self.error_value()
1416 exc_check = self.caller_will_check_exceptions()
1417 if err_val is not None or exc_check:
1418 # TODO: Fix exception tracing (though currently unused by cProfile).
1419 # code.globalstate.use_utility_code(get_exception_tuple_utility_code)
1420 # code.put_trace_exception()
1421 code.putln('__Pyx_AddTraceback("%s");' % self.entry.qualified_name)
1423 warning(self.entry.pos, "Unraisable exception in function '%s'." \
1424 % self.entry.qualified_name, 0)
1426 '__Pyx_WriteUnraisable("%s");' %
1427 self.entry.qualified_name)
1428 env.use_utility_code(unraisable_exception_utility_code)
1429 env.use_utility_code(restore_exception_utility_code)
1430 default_retval = self.return_type.default_value
1431 if err_val is None and default_retval:
1432 err_val = default_retval
1433 if err_val is not None:
1434 code.putln("%s = %s;" % (Naming.retval_cname, err_val))
1436 if is_getbuffer_slot:
1437 self.getbuffer_error_cleanup(code)
1439 # If we are using the non-error cleanup section we should
1440 # jump past it if we have an error. The if-test below determine
1441 # whether this section is used.
1442 if buffers_present or is_getbuffer_slot:
1443 code.put_goto(code.return_from_error_cleanup_label)
1446 # ----- Non-error return cleanup
1447 code.put_label(code.return_label)
1448 for entry in lenv.buffer_entries:
1450 Buffer.put_release_buffer_code(code, entry)
1451 if is_getbuffer_slot:
1452 self.getbuffer_normal_cleanup(code)
1453 # ----- Return cleanup for both error and no-error return
1454 code.put_label(code.return_from_error_cleanup_label)
1455 if not Options.init_local_none:
1456 for entry in lenv.var_entries:
1457 if lenv.control_flow.get_state((entry.name, 'initialized')) is not True:
1458 entry.xdecref_cleanup = 1
1460 for entry in lenv.var_entries:
1461 if entry.type.is_pyobject:
1462 if entry.used and not entry.in_closure:
1463 code.put_var_decref(entry)
1464 elif entry.in_closure and self.needs_closure:
1465 code.put_giveref(entry.cname)
1466 # Decref any increfed args
1467 for entry in lenv.arg_entries:
1468 if entry.type.is_pyobject:
1469 if entry.in_closure:
1470 code.put_var_giveref(entry)
1471 elif acquire_gil or entry.assignments:
1472 code.put_var_decref(entry)
1473 if self.needs_closure:
1474 code.put_decref(Naming.cur_scope_cname, lenv.scope_class.type)
1477 # This code is duplicated in ModuleNode.generate_module_init_func
1479 default_retval = self.return_type.default_value
1480 err_val = self.error_value()
1481 if err_val is None and default_retval:
1482 err_val = default_retval
1483 if self.return_type.is_pyobject:
1484 code.put_xgiveref(self.return_type.as_pyobject(Naming.retval_cname))
1486 if self.entry.is_special and self.entry.name == "__hash__":
1487 # Returning -1 for __hash__ is supposed to signal an error
1488 # We do as Python instances and coerce -1 into -2.
1489 code.putln("if (unlikely(%s == -1) && !PyErr_Occurred()) %s = -2;" % (
1490 Naming.retval_cname, Naming.retval_cname))
1493 if self.return_type.is_pyobject:
1494 code.put_trace_return(Naming.retval_cname)
1496 code.put_trace_return("Py_None")
1498 code.put_finish_refcount_context()
1501 code.putln("#ifdef WITH_THREAD")
1502 code.putln("PyGILState_Release(_save);")
1503 code.putln("#endif")
1505 if not self.return_type.is_void:
1506 code.putln("return %s;" % Naming.retval_cname)
1510 if preprocessor_guard:
1511 code.putln("#endif /*!(%s)*/" % preprocessor_guard)
1513 # ----- Go back and insert temp variable declarations
1514 tempvardecl_code.put_temp_declarations(code.funcstate)
1515 # ----- Python version
1516 code.exit_cfunc_scope()
1518 self.py_func.generate_function_definitions(env, code)
1519 self.generate_wrapper_functions(code)
1521 def declare_argument(self, env, arg):
1522 if arg.type.is_void:
1523 error(arg.pos, "Invalid use of 'void'")
1524 elif not arg.type.is_complete() and not arg.type.is_array:
1526 "Argument type '%s' is incomplete" % arg.type)
1527 return env.declare_arg(arg.name, arg.type, arg.pos)
1529 def generate_arg_type_test(self, arg, code):
1530 # Generate type test for one argument.
1531 if arg.type.typeobj_is_available():
1532 code.globalstate.use_utility_code(arg_type_test_utility_code)
1533 typeptr_cname = arg.type.typeptr_cname
1534 arg_code = "((PyObject *)%s)" % arg.entry.cname
1536 'if (unlikely(!__Pyx_ArgTypeTest(%s, %s, %d, "%s", %s))) %s' % (
1541 arg.type.is_builtin_type,
1542 code.error_goto(arg.pos)))
1544 error(arg.pos, "Cannot test type of extern C class "
1545 "without type object name specification")
1547 def generate_arg_none_check(self, arg, code):
1548 # Generate None check for one argument.
1549 code.putln('if (unlikely(((PyObject *)%s) == Py_None)) {' % arg.entry.cname)
1550 code.putln('''PyErr_Format(PyExc_TypeError, "Argument '%s' must not be None"); %s''' % (
1552 code.error_goto(arg.pos)))
1555 def generate_wrapper_functions(self, code):
1558 def generate_execution_code(self, code):
1559 # Evaluate and store argument default values
1560 for arg in self.args:
1561 default = arg.default
1563 if not default.is_literal:
1564 default.generate_evaluation_code(code)
1565 default.make_owned_reference(code)
1566 result = default.result_as(arg.type)
1569 arg.calculate_default_value_code(code),
1571 if arg.type.is_pyobject:
1572 code.put_giveref(default.result())
1573 default.generate_post_assignment_code(code)
1574 default.free_temps(code)
1575 # For Python class methods, create and store function object
1577 self.assmt.generate_execution_code(code)
1580 # Special code for the __getbuffer__ function
1582 def getbuffer_init(self, code):
1583 info = self.local_scope.arg_entries[1].cname
1584 # Python 3.0 betas have a bug in memoryview which makes it call
1585 # getbuffer with a NULL parameter. For now we work around this;
1586 # the following line should be removed when this bug is fixed.
1587 code.putln("if (%s == NULL) return 0;" % info)
1588 code.putln("%s->obj = Py_None; __Pyx_INCREF(Py_None);" % info)
1589 code.put_giveref("%s->obj" % info) # Do not refnanny object within structs
1591 def getbuffer_error_cleanup(self, code):
1592 info = self.local_scope.arg_entries[1].cname
1593 code.put_gotref("%s->obj" % info)
1594 code.putln("__Pyx_DECREF(%s->obj); %s->obj = NULL;" %
1597 def getbuffer_normal_cleanup(self, code):
1598 info = self.local_scope.arg_entries[1].cname
1599 code.putln("if (%s->obj == Py_None) {" % info)
1600 code.put_gotref("Py_None")
1601 code.putln("__Pyx_DECREF(Py_None); %s->obj = NULL;" % info)
1604 class CFuncDefNode(FuncDefNode):
1605 # C function definition.
1607 # modifiers ['inline']
1608 # visibility 'private' or 'public' or 'extern'
1609 # base_type CBaseTypeNode
1610 # declarator CDeclaratorNode
1613 # decorators [DecoratorNode] list of decorators
1615 # with_gil boolean Acquire GIL around body
1617 # py_func wrapper for calling from Python
1618 # overridable whether or not this is a cpdef function
1619 # inline_in_pxd whether this is an inline function in a pxd file
1621 child_attrs = ["base_type", "declarator", "body", "py_func"]
1623 inline_in_pxd = False
1625 directive_locals = {}
1627 def unqualified_name(self):
1628 return self.entry.name
1630 def analyse_declarations(self, env):
1631 self.directive_locals.update(env.directives['locals'])
1632 base_type = self.base_type.analyse(env)
1633 # The 2 here is because we need both function and argument names.
1634 name_declarator, type = self.declarator.analyse(base_type, env, nonempty = 2 * (self.body is not None))
1635 if not type.is_cfunction:
1637 "Suite attached to non-function declaration")
1638 # Remember the actual type according to the function header
1639 # written here, because the type in the symbol table entry
1640 # may be different if we're overriding a C method inherited
1641 # from the base type of an extension type.
1643 type.is_overridable = self.overridable
1644 declarator = self.declarator
1645 while not hasattr(declarator, 'args'):
1646 declarator = declarator.base
1647 self.args = declarator.args
1648 for formal_arg, type_arg in zip(self.args, type.args):
1649 formal_arg.type = type_arg.type
1650 formal_arg.name = type_arg.name
1651 formal_arg.cname = type_arg.cname
1652 if type_arg.type.is_buffer and 'inline' in self.modifiers:
1653 warning(formal_arg.pos, "Buffer unpacking not optimized away.", 1)
1654 name = name_declarator.name
1655 cname = name_declarator.cname
1656 self.entry = env.declare_cfunction(
1657 name, type, self.pos,
1658 cname = cname, visibility = self.visibility,
1659 defining = self.body is not None,
1660 api = self.api, modifiers = self.modifiers)
1661 self.entry.inline_func_in_pxd = self.inline_in_pxd
1662 self.return_type = type.return_type
1663 if self.return_type.is_array and visibility != 'extern':
1665 "Function cannot return an array")
1667 if self.overridable and not env.is_module_scope:
1668 if len(self.args) < 1 or not self.args[0].type.is_pyobject:
1669 # An error will be produced in the cdef function
1670 self.overridable = False
1672 if self.overridable:
1674 py_func_body = self.call_self_node(is_module_scope = env.is_module_scope)
1675 self.py_func = DefNode(pos = self.pos,
1676 name = self.entry.name,
1679 starstar_arg = None,
1681 body = py_func_body,
1683 self.py_func.is_module_scope = env.is_module_scope
1684 self.py_func.analyse_declarations(env)
1685 self.entry.as_variable = self.py_func.entry
1686 # Reset scope entry the above cfunction
1687 env.entries[name] = self.entry
1688 if not env.is_module_scope or Options.lookup_module_cpdef:
1689 self.override = OverrideCheckNode(self.pos, py_func = self.py_func)
1690 self.body = StatListNode(self.pos, stats=[self.override, self.body])
1691 self.create_local_scope(env)
1693 def call_self_node(self, omit_optional_args=0, is_module_scope=0):
1695 args = self.type.args
1696 if omit_optional_args:
1697 args = args[:len(args) - self.type.optional_arg_count]
1698 arg_names = [arg.name for arg in args]
1700 cfunc = ExprNodes.NameNode(self.pos, name=self.entry.name)
1702 self_arg = ExprNodes.NameNode(self.pos, name=arg_names[0])
1703 cfunc = ExprNodes.AttributeNode(self.pos, obj=self_arg, attribute=self.entry.name)
1704 skip_dispatch = not is_module_scope or Options.lookup_module_cpdef
1705 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)
1706 return ReturnStatNode(pos=self.pos, return_type=PyrexTypes.py_object_type, value=c_call)
1708 def declare_arguments(self, env):
1709 for arg in self.type.args:
1711 error(arg.pos, "Missing argument name")
1712 self.declare_argument(env, arg)
1714 def need_gil_acquisition(self, lenv):
1715 return self.type.with_gil
1717 def nogil_check(self, env):
1719 with_gil = type.with_gil
1720 if type.nogil and not with_gil:
1721 if type.return_type.is_pyobject:
1723 "Function with Python return type cannot be declared nogil")
1724 for entry in self.local_scope.var_entries:
1725 if entry.type.is_pyobject:
1726 error(self.pos, "Function declared nogil has Python locals or temporaries")
1728 def analyse_expressions(self, env):
1729 self.local_scope.directives = env.directives
1730 if self.py_func is not None:
1731 # this will also analyse the default values
1732 self.py_func.analyse_expressions(env)
1734 self.analyse_default_values(env)
1735 self.acquire_gil = self.need_gil_acquisition(self.local_scope)
1737 def needs_assignment_synthesis(self, env, code=None):
1740 def generate_function_header(self, code, with_pymethdef, with_opt_args = 1, with_dispatch = 1, cname = None):
1743 visibility = self.entry.visibility
1744 for arg in type.args[:len(type.args)-type.optional_arg_count]:
1745 arg_decls.append(arg.declaration_code())
1746 if with_dispatch and self.overridable:
1747 arg_decls.append(PyrexTypes.c_int_type.declaration_code(Naming.skip_dispatch_cname))
1748 if type.optional_arg_count and with_opt_args:
1749 arg_decls.append(type.op_arg_struct.declaration_code(Naming.optional_args_cname))
1750 if type.has_varargs:
1751 arg_decls.append("...")
1753 arg_decls = ["void"]
1755 cname = self.entry.func_cname
1756 entity = type.function_header_code(cname, ', '.join(arg_decls))
1757 if visibility == 'public':
1758 dll_linkage = "DL_EXPORT"
1761 header = self.return_type.declaration_code(entity,
1762 dll_linkage = dll_linkage)
1763 if visibility == 'extern':
1764 storage_class = "%s " % Naming.extern_c_macro
1765 elif visibility == 'public':
1768 storage_class = "static "
1769 if 'inline' in self.modifiers:
1770 self.modifiers[self.modifiers.index('inline')] = 'cython_inline'
1771 code.putln("%s%s %s {" % (
1773 ' '.join(self.modifiers).upper(), # macro forms
1776 def generate_argument_declarations(self, env, code):
1777 for arg in self.args:
1779 result = arg.calculate_default_value_code(code)
1780 code.putln('%s = %s;' % (
1781 arg.type.declaration_code(arg.cname), result))
1783 def generate_keyword_list(self, code):
1786 def generate_argument_parsing_code(self, env, code):
1788 if self.type.optional_arg_count:
1789 code.putln('if (%s) {' % Naming.optional_args_cname)
1790 for arg in self.args:
1792 code.putln('if (%s->%sn > %s) {' % (Naming.optional_args_cname, Naming.pyrex_prefix, i))
1793 declarator = arg.declarator
1794 while not hasattr(declarator, 'name'):
1795 declarator = declarator.base
1796 code.putln('%s = %s->%s;' % (arg.cname, Naming.optional_args_cname, self.type.opt_arg_cname(declarator.name)))
1798 for _ in range(self.type.optional_arg_count):
1802 def generate_argument_conversion_code(self, code):
1805 def generate_argument_type_tests(self, code):
1806 # Generate type tests for args whose type in a parent
1807 # class is a supertype of the declared type.
1808 for arg in self.type.args:
1809 if arg.needs_type_test:
1810 self.generate_arg_type_test(arg, code)
1811 elif arg.type.is_pyobject and not arg.accept_none:
1812 self.generate_arg_none_check(arg, code)
1814 def error_value(self):
1815 if self.return_type.is_pyobject:
1819 return self.entry.type.exception_value
1821 def caller_will_check_exceptions(self):
1822 return self.entry.type.exception_check
1824 def generate_wrapper_functions(self, code):
1825 # If the C signature of a function has changed, we need to generate
1826 # wrappers to put in the slots here.
1829 func_type = entry.type
1830 while entry.prev_entry is not None:
1832 entry = entry.prev_entry
1833 entry.func_cname = "%s%swrap_%s" % (self.entry.func_cname, Naming.pyrex_prefix, k)
1835 self.generate_function_header(code,
1837 with_dispatch = entry.type.is_overridable,
1838 with_opt_args = entry.type.optional_arg_count,
1839 cname = entry.func_cname)
1840 if not self.return_type.is_void:
1842 args = self.type.args
1843 arglist = [arg.cname for arg in args[:len(args)-self.type.optional_arg_count]]
1844 if entry.type.is_overridable:
1845 arglist.append(Naming.skip_dispatch_cname)
1846 elif func_type.is_overridable:
1848 if entry.type.optional_arg_count:
1849 arglist.append(Naming.optional_args_cname)
1850 elif func_type.optional_arg_count:
1851 arglist.append('NULL')
1852 code.putln('%s(%s);' % (self.entry.func_cname, ', '.join(arglist)))
1856 class PyArgDeclNode(Node):
1857 # Argument which must be a Python object (used
1858 # for * and ** arguments).
1861 # entry Symtab.Entry
1862 # annotation ExprNode or None Py3 argument annotation
1865 def generate_function_definitions(self, env, code):
1866 self.entry.generate_function_definitions(env, code)
1868 class DecoratorNode(Node):
1871 # decorator NameNode or CallNode or AttributeNode
1872 child_attrs = ['decorator']
1875 class DefNode(FuncDefNode):
1876 # A Python function definition.
1878 # name string the Python name of the function
1879 # lambda_name string the internal name of a lambda 'function'
1880 # decorators [DecoratorNode] list of decorators
1881 # args [CArgDeclNode] formal arguments
1882 # star_arg PyArgDeclNode or None * argument
1883 # starstar_arg PyArgDeclNode or None ** argument
1884 # doc EncodedString or None
1886 # return_type_annotation
1887 # ExprNode or None the Py3 return type annotation
1889 # The following subnode is constructed internally
1890 # when the def statement is inside a Python class definition.
1892 # assmt AssignmentNode Function construction/assignment
1894 child_attrs = ["args", "star_arg", "starstar_arg", "body", "decorators"]
1899 num_required_kw_args = 0
1900 reqd_kw_flags_cname = "0"
1903 return_type_annotation = None
1911 def __init__(self, pos, **kwds):
1912 FuncDefNode.__init__(self, pos, **kwds)
1914 for arg in self.args:
1921 self.num_kwonly_args = k
1922 self.num_required_kw_args = rk
1923 self.num_required_args = r
1925 def as_cfunction(self, cfunc=None, scope=None):
1927 error(self.star_arg.pos, "cdef function cannot have star argument")
1928 if self.starstar_arg:
1929 error(self.starstar_arg.pos, "cdef function cannot have starstar argument")
1932 for formal_arg in self.args:
1933 name_declarator, type = formal_arg.analyse(scope, nonempty=1)
1934 cfunc_args.append(PyrexTypes.CFuncTypeArg(name = name_declarator.name,
1936 type = py_object_type,
1937 pos = formal_arg.pos))
1938 cfunc_type = PyrexTypes.CFuncType(return_type = py_object_type,
1940 has_varargs = False,
1941 exception_value = None,
1942 exception_check = False,
1945 is_overridable = True)
1946 cfunc = CVarDefNode(self.pos, type=cfunc_type)
1950 cfunc_type = cfunc.type
1951 if len(self.args) != len(cfunc_type.args) or cfunc_type.has_varargs:
1952 error(self.pos, "wrong number of arguments")
1953 error(cfunc.pos, "previous declaration here")
1954 for i, (formal_arg, type_arg) in enumerate(zip(self.args, cfunc_type.args)):
1955 name_declarator, type = formal_arg.analyse(scope, nonempty=1,
1956 is_self_arg = (i == 0 and scope.is_c_class_scope))
1957 if type is None or type is PyrexTypes.py_object_type:
1958 formal_arg.type = type_arg.type
1959 formal_arg.name_declarator = name_declarator
1961 if cfunc_type.exception_value is None:
1962 exception_value = None
1964 exception_value = ExprNodes.ConstNode(self.pos, value=cfunc_type.exception_value, type=cfunc_type.return_type)
1965 declarator = CFuncDeclaratorNode(self.pos,
1966 base = CNameDeclaratorNode(self.pos, name=self.name, cname=None),
1968 has_varargs = False,
1969 exception_check = cfunc_type.exception_check,
1970 exception_value = exception_value,
1971 with_gil = cfunc_type.with_gil,
1972 nogil = cfunc_type.nogil)
1973 return CFuncDefNode(self.pos,
1975 base_type = CAnalysedBaseTypeNode(self.pos, type=cfunc_type.return_type),
1976 declarator = declarator,
1979 overridable = cfunc_type.is_overridable,
1981 with_gil = cfunc_type.with_gil,
1982 nogil = cfunc_type.nogil,
1983 visibility = 'private',
1985 directive_locals = getattr(cfunc, 'directive_locals', {}))
1987 def analyse_declarations(self, env):
1988 self.is_classmethod = self.is_staticmethod = False
1990 for decorator in self.decorators:
1991 func = decorator.decorator
1993 self.is_classmethod |= func.name == 'classmethod'
1994 self.is_staticmethod |= func.name == 'staticmethod'
1996 if self.is_classmethod and env.lookup_here('classmethod'):
1997 # classmethod() was overridden - not much we can do here ...
1998 self.is_classmethod = False
1999 if self.is_staticmethod and env.lookup_here('staticmethod'):
2000 # staticmethod() was overridden - not much we can do here ...
2001 self.is_staticmethod = False
2003 if self.name == '__new__' and env.is_py_class_scope:
2004 self.is_staticmethod = 1
2006 self.analyse_argument_types(env)
2007 if self.name == '<lambda>':
2008 self.declare_lambda_function(env)
2010 self.declare_pyfunction(env)
2011 self.analyse_signature(env)
2012 self.return_type = self.entry.signature.return_type()
2013 self.create_local_scope(env)
2015 def analyse_argument_types(self, env):
2016 directive_locals = self.directive_locals = env.directives['locals']
2017 allow_none_for_extension_args = env.directives['allow_none_for_extension_args']
2018 for arg in self.args:
2019 if hasattr(arg, 'name'):
2021 name_declarator = None
2023 base_type = arg.base_type.analyse(env)
2024 name_declarator, type = \
2025 arg.declarator.analyse(base_type, env)
2026 arg.name = name_declarator.name
2027 if arg.name in directive_locals:
2028 type_node = directive_locals[arg.name]
2029 other_type = type_node.analyse_as_type(env)
2030 if other_type is None:
2031 error(type_node.pos, "Not a type")
2032 elif (type is not PyrexTypes.py_object_type
2033 and not type.same_as(other_type)):
2034 error(arg.base_type.pos, "Signature does not agree with previous declaration")
2035 error(type_node.pos, "Previous declaration here")
2038 if name_declarator and name_declarator.cname:
2040 "Python function argument cannot have C name specification")
2041 arg.type = type.as_argument_type()
2043 arg.needs_conversion = 0
2044 arg.needs_type_test = 0
2046 if arg.type.is_pyobject:
2048 arg.accept_none = True
2050 arg.accept_none = False
2051 elif arg.type.is_extension_type or arg.type.is_builtin_type:
2052 if arg.default and arg.default.constant_result is None:
2053 # special case: def func(MyType obj = None)
2054 arg.accept_none = True
2056 # default depends on compiler directive
2057 arg.accept_none = allow_none_for_extension_args
2059 # probably just a plain 'object'
2060 arg.accept_none = True
2062 arg.accept_none = True # won't be used, but must be there
2064 error(arg.pos, "Only Python type arguments can have 'not None'")
2066 error(arg.pos, "Only Python type arguments can have 'or None'")
2068 def analyse_signature(self, env):
2069 if self.entry.is_special:
2071 error(self.pos, "special functions of cdef classes cannot have decorators")
2072 self.entry.trivial_signature = len(self.args) == 1 and not (self.star_arg or self.starstar_arg)
2073 elif not env.directives['always_allow_keywords'] and not (self.star_arg or self.starstar_arg):
2074 # Use the simpler calling signature for zero- and one-argument functions.
2075 if self.entry.signature is TypeSlots.pyfunction_signature:
2076 if len(self.args) == 0:
2077 self.entry.signature = TypeSlots.pyfunction_noargs
2078 elif len(self.args) == 1:
2079 if self.args[0].default is None and not self.args[0].kw_only:
2080 self.entry.signature = TypeSlots.pyfunction_onearg
2081 elif self.entry.signature is TypeSlots.pymethod_signature:
2082 if len(self.args) == 1:
2083 self.entry.signature = TypeSlots.unaryfunc
2084 elif len(self.args) == 2:
2085 if self.args[1].default is None and not self.args[1].kw_only:
2086 self.entry.signature = TypeSlots.ibinaryfunc
2088 sig = self.entry.signature
2089 nfixed = sig.num_fixed_args()
2090 if sig is TypeSlots.pymethod_signature and nfixed == 1 \
2091 and len(self.args) == 0 and self.star_arg:
2092 # this is the only case where a diverging number of
2093 # arguments is not an error - when we have no explicit
2094 # 'self' parameter as in method(*args)
2095 sig = self.entry.signature = TypeSlots.pyfunction_signature # self is not 'really' used
2096 self.self_in_stararg = 1
2099 for i in range(min(nfixed, len(self.args))):
2102 if sig.is_self_arg(i) and not self.is_staticmethod:
2103 if self.is_classmethod:
2105 arg.hdr_type = arg.type = Builtin.type_type
2108 arg.hdr_type = arg.type = env.parent_type
2109 arg.needs_conversion = 0
2111 arg.hdr_type = sig.fixed_arg_type(i)
2112 if not arg.type.same_as(arg.hdr_type):
2113 if arg.hdr_type.is_pyobject and arg.type.is_pyobject:
2114 arg.needs_type_test = 1
2116 arg.needs_conversion = 1
2117 if arg.needs_conversion:
2118 arg.hdr_cname = Naming.arg_prefix + arg.name
2120 arg.hdr_cname = Naming.var_prefix + arg.name
2122 if nfixed > len(self.args):
2123 self.bad_signature()
2125 elif nfixed < len(self.args):
2126 if not sig.has_generic_args:
2127 self.bad_signature()
2128 for arg in self.args:
2129 if arg.is_generic and \
2130 (arg.type.is_extension_type or arg.type.is_builtin_type):
2131 arg.needs_type_test = 1
2133 def bad_signature(self):
2134 sig = self.entry.signature
2135 expected_str = "%d" % sig.num_fixed_args()
2136 if sig.has_generic_args:
2137 expected_str = expected_str + " or more"
2139 if name.startswith("__") and name.endswith("__"):
2140 desc = "Special method"
2144 "%s %s has wrong number of arguments "
2145 "(%d declared, %s expected)" % (
2146 desc, self.name, len(self.args), expected_str))
2148 def signature_has_nongeneric_args(self):
2149 argcount = len(self.args)
2150 if argcount == 0 or (
2151 argcount == 1 and (self.args[0].is_self_arg or
2152 self.args[0].is_type_arg)):
2156 def signature_has_generic_args(self):
2157 return self.entry.signature.has_generic_args
2159 def declare_pyfunction(self, env):
2160 #print "DefNode.declare_pyfunction:", self.name, "in", env ###
2162 entry = env.lookup_here(name)
2163 if entry and entry.type.is_cfunction and not self.is_wrapper:
2164 warning(self.pos, "Overriding cdef method with def method.", 5)
2165 entry = env.declare_pyfunction(name, self.pos, allow_redefine=not self.is_wrapper)
2167 prefix = env.next_id(env.scope_prefix)
2169 entry.func_cname = \
2170 Naming.pyfunc_prefix + prefix + name
2171 entry.pymethdef_cname = \
2172 Naming.pymethdef_prefix + prefix + name
2173 if Options.docstrings:
2174 entry.doc = embed_position(self.pos, self.doc)
2176 Naming.funcdoc_prefix + prefix + name
2177 if entry.is_special:
2178 if entry.name in TypeSlots.invisible or not entry.doc or (entry.name in '__getattr__' and env.directives['fast_getattr']):
2179 entry.wrapperbase_cname = None
2181 entry.wrapperbase_cname = Naming.wrapperbase_prefix + prefix + name
2185 def declare_lambda_function(self, env):
2187 prefix = env.scope_prefix
2189 Naming.lambda_func_prefix + u'funcdef' + prefix + self.lambda_name
2190 entry = env.declare_lambda_function(func_cname, self.pos)
2191 entry.pymethdef_cname = \
2192 Naming.lambda_func_prefix + u'methdef' + prefix + self.lambda_name
2193 entry.qualified_name = env.qualify_name(self.lambda_name)
2197 def declare_arguments(self, env):
2198 for arg in self.args:
2200 error(arg.pos, "Missing argument name")
2202 env.control_flow.set_state((), (arg.name, 'source'), 'arg')
2203 env.control_flow.set_state((), (arg.name, 'initialized'), True)
2204 if arg.needs_conversion:
2205 arg.entry = env.declare_var(arg.name, arg.type, arg.pos)
2206 if arg.type.is_pyobject:
2207 arg.entry.init = "0"
2208 arg.entry.init_to_none = 0
2210 arg.entry = self.declare_argument(env, arg)
2212 arg.entry.is_self_arg = arg.is_self_arg
2214 if arg.is_self_arg or arg.is_type_arg or \
2215 (arg.type.is_extension_type and not arg.hdr_type.is_extension_type):
2216 arg.entry.is_declared_generic = 1
2217 self.declare_python_arg(env, self.star_arg)
2218 self.declare_python_arg(env, self.starstar_arg)
2220 def declare_python_arg(self, env, arg):
2222 if env.directives['infer_types'] != False:
2223 type = PyrexTypes.unspecified_type
2225 type = py_object_type
2226 entry = env.declare_var(arg.name, type, arg.pos)
2229 entry.init_to_none = 0
2230 entry.xdecref_cleanup = 1
2232 env.control_flow.set_state((), (arg.name, 'initialized'), True)
2234 def analyse_expressions(self, env):
2235 self.local_scope.directives = env.directives
2236 self.analyse_default_values(env)
2237 if self.needs_assignment_synthesis(env):
2238 # Shouldn't we be doing this at the module level too?
2239 self.synthesize_assignment_node(env)
2241 def needs_assignment_synthesis(self, env, code=None):
2242 # Should enable for module level as well, that will require more testing...
2243 if self.entry.is_anonymous:
2245 if env.is_module_scope:
2247 return env.directives['binding']
2249 return code.globalstate.directives['binding']
2250 return env.is_py_class_scope or env.is_closure_scope
2252 def synthesize_assignment_node(self, env):
2255 while genv.is_py_class_scope or genv.is_c_class_scope:
2256 genv = genv.outer_scope
2258 if genv.is_closure_scope:
2259 rhs = ExprNodes.InnerFunctionNode(
2260 self.pos, pymethdef_cname = self.entry.pymethdef_cname)
2262 rhs = ExprNodes.PyCFunctionNode(
2263 self.pos, pymethdef_cname = self.entry.pymethdef_cname, binding = env.directives['binding'])
2265 if env.is_py_class_scope:
2266 if not self.is_staticmethod and not self.is_classmethod:
2269 self.assmt = SingleAssignmentNode(self.pos,
2270 lhs = ExprNodes.NameNode(self.pos, name = self.name),
2272 self.assmt.analyse_declarations(env)
2273 self.assmt.analyse_expressions(env)
2275 def generate_function_header(self, code, with_pymethdef, proto_only=0):
2277 sig = self.entry.signature
2278 if sig.has_dummy_arg or self.self_in_stararg:
2279 arg_code_list.append(
2280 "PyObject *%s" % Naming.self_cname)
2281 for arg in self.args:
2282 if not arg.is_generic:
2283 if arg.is_self_arg or arg.is_type_arg:
2284 arg_code_list.append("PyObject *%s" % arg.hdr_cname)
2286 arg_code_list.append(
2287 arg.hdr_type.declaration_code(arg.hdr_cname))
2288 if not self.entry.is_special and sig.method_flags() == [TypeSlots.method_noargs]:
2289 arg_code_list.append("CYTHON_UNUSED PyObject *unused")
2290 if (self.entry.scope.is_c_class_scope and self.entry.name == "__ipow__"):
2291 arg_code_list.append("CYTHON_UNUSED PyObject *unused")
2292 if sig.has_generic_args:
2293 arg_code_list.append(
2294 "PyObject *%s, PyObject *%s"
2295 % (Naming.args_cname, Naming.kwds_cname))
2296 arg_code = ", ".join(arg_code_list)
2297 dc = self.return_type.declaration_code(self.entry.func_cname)
2298 mf = " ".join(self.modifiers).upper()
2300 header = "static %s%s(%s)" % (mf, dc, arg_code)
2301 code.putln("%s; /*proto*/" % header)
2304 if (Options.docstrings and self.entry.doc and
2305 not self.entry.scope.is_property_scope and
2306 (not self.entry.is_special or self.entry.wrapperbase_cname)):
2307 docstr = self.entry.doc
2308 if docstr.is_unicode:
2309 docstr = docstr.utf8encode()
2311 'static char %s[] = "%s";' % (
2312 self.entry.doc_cname,
2313 split_string_literal(escape_byte_string(docstr))))
2314 if self.entry.is_special:
2316 "struct wrapperbase %s;" % self.entry.wrapperbase_cname)
2319 "static PyMethodDef %s = " %
2320 self.entry.pymethdef_cname)
2321 code.put_pymethoddef(self.entry, ";", allow_skip=False)
2322 code.putln("%s {" % header)
2324 def generate_argument_declarations(self, env, code):
2325 for arg in self.args:
2326 if arg.is_generic: # or arg.needs_conversion:
2327 if arg.needs_conversion:
2328 code.putln("PyObject *%s = 0;" % arg.hdr_cname)
2329 elif not arg.entry.in_closure:
2330 code.put_var_declaration(arg.entry)
2332 def generate_keyword_list(self, code):
2333 if self.signature_has_generic_args() and \
2334 self.signature_has_nongeneric_args():
2336 "static PyObject **%s[] = {" %
2337 Naming.pykwdlist_cname)
2338 for arg in self.args:
2340 pystring_cname = code.intern_identifier(arg.name)
2341 code.put('&%s,' % pystring_cname)
2344 def generate_argument_parsing_code(self, env, code):
2345 # Generate PyArg_ParseTuple call for generic
2346 # arguments, if any.
2347 if self.entry.signature.has_dummy_arg and not self.self_in_stararg:
2348 # get rid of unused argument warning
2349 code.putln("%s = %s;" % (Naming.self_cname, Naming.self_cname))
2351 old_error_label = code.new_error_label()
2352 our_error_label = code.error_label
2353 end_label = code.new_label("argument_unpacking_done")
2355 has_kwonly_args = self.num_kwonly_args > 0
2356 has_star_or_kw_args = self.star_arg is not None \
2357 or self.starstar_arg is not None or has_kwonly_args
2359 for arg in self.args:
2360 if not arg.type.is_pyobject:
2361 done = arg.type.create_from_py_utility_code(env)
2362 if not done: pass # will fail later
2364 if not self.signature_has_generic_args():
2365 if has_star_or_kw_args:
2366 error(self.pos, "This method cannot have * or keyword arguments")
2367 self.generate_argument_conversion_code(code)
2369 elif not self.signature_has_nongeneric_args():
2370 # func(*args) or func(**kw) or func(*args, **kw)
2371 self.generate_stararg_copy_code(code)
2374 positional_args = []
2376 for arg in self.args:
2377 arg_entry = arg.entry
2380 if not arg.is_self_arg and not arg.is_type_arg:
2382 kw_only_args.append(arg)
2384 positional_args.append(arg)
2386 kw_only_args.append(arg)
2387 elif not arg.is_self_arg and not arg.is_type_arg:
2388 positional_args.append(arg)
2390 self.generate_tuple_and_keyword_parsing_code(
2391 positional_args, kw_only_args, end_label, code)
2393 code.error_label = old_error_label
2394 if code.label_used(our_error_label):
2395 if not code.label_used(end_label):
2396 code.put_goto(end_label)
2397 code.put_label(our_error_label)
2398 if has_star_or_kw_args:
2399 self.generate_arg_decref(self.star_arg, code)
2400 if self.starstar_arg:
2401 if self.starstar_arg.entry.xdecref_cleanup:
2402 code.put_var_xdecref_clear(self.starstar_arg.entry)
2404 code.put_var_decref_clear(self.starstar_arg.entry)
2405 code.putln('__Pyx_AddTraceback("%s");' % self.entry.qualified_name)
2406 # The arguments are put into the closure one after the
2407 # other, so when type errors are found, all references in
2408 # the closure instance must be properly ref-counted to
2409 # facilitate generic closure instance deallocation. In
2410 # the case of an argument type error, it's best to just
2411 # DECREF+clear the already handled references, as this
2412 # frees their references as early as possible.
2413 for arg in self.args:
2414 if arg.type.is_pyobject and arg.entry.in_closure:
2415 code.put_var_xdecref_clear(arg.entry)
2416 if self.needs_closure:
2417 code.put_decref(Naming.cur_scope_cname, self.local_scope.scope_class.type)
2418 code.put_finish_refcount_context()
2419 code.putln("return %s;" % self.error_value())
2420 if code.label_used(end_label):
2421 code.put_label(end_label)
2423 def generate_arg_assignment(self, arg, item, code):
2424 if arg.type.is_pyobject:
2426 item = PyrexTypes.typecast(arg.type, PyrexTypes.py_object_type, item)
2428 code.putln("%s = %s;" % (entry.cname, item))
2429 if entry.in_closure:
2430 code.put_var_incref(entry)
2432 func = arg.type.from_py_function
2434 code.putln("%s = %s(%s); %s" % (
2438 code.error_goto_if(arg.type.error_condition(arg.entry.cname), arg.pos)))
2440 error(arg.pos, "Cannot convert Python object argument to type '%s'" % arg.type)
2442 def generate_arg_xdecref(self, arg, code):
2444 code.put_var_xdecref_clear(arg.entry)
2446 def generate_arg_decref(self, arg, code):
2448 code.put_var_decref_clear(arg.entry)
2450 def generate_stararg_copy_code(self, code):
2451 if not self.star_arg:
2452 code.globalstate.use_utility_code(raise_argtuple_invalid_utility_code)
2453 code.putln("if (unlikely(PyTuple_GET_SIZE(%s) > 0)) {" %
2455 code.put('__Pyx_RaiseArgtupleInvalid("%s", 1, 0, 0, PyTuple_GET_SIZE(%s)); return %s;' % (
2456 self.name, Naming.args_cname, self.error_value()))
2459 if self.starstar_arg:
2461 kwarg_check = "unlikely(%s)" % Naming.kwds_cname
2463 kwarg_check = "%s" % Naming.kwds_cname
2465 kwarg_check = "unlikely(%s) && unlikely(PyDict_Size(%s) > 0)" % (
2466 Naming.kwds_cname, Naming.kwds_cname)
2467 code.globalstate.use_utility_code(keyword_string_check_utility_code)
2469 "if (%s && unlikely(!__Pyx_CheckKeywordStrings(%s, \"%s\", %d))) return %s;" % (
2470 kwarg_check, Naming.kwds_cname, self.name,
2471 bool(self.starstar_arg), self.error_value()))
2473 if self.starstar_arg:
2474 code.putln("%s = (%s) ? PyDict_Copy(%s) : PyDict_New();" % (
2475 self.starstar_arg.entry.cname,
2478 code.putln("if (unlikely(!%s)) return %s;" % (
2479 self.starstar_arg.entry.cname, self.error_value()))
2480 self.starstar_arg.entry.xdecref_cleanup = 0
2481 code.put_gotref(self.starstar_arg.entry.cname)
2483 if self.self_in_stararg:
2484 # need to create a new tuple with 'self' inserted as first item
2485 code.put("%s = PyTuple_New(PyTuple_GET_SIZE(%s)+1); if (unlikely(!%s)) " % (
2486 self.star_arg.entry.cname,
2488 self.star_arg.entry.cname))
2489 if self.starstar_arg:
2491 code.put_decref_clear(self.starstar_arg.entry.cname, py_object_type)
2492 code.putln("return %s;" % self.error_value())
2495 code.putln("return %s;" % self.error_value())
2496 code.put_gotref(self.star_arg.entry.cname)
2497 code.put_incref(Naming.self_cname, py_object_type)
2498 code.put_giveref(Naming.self_cname)
2499 code.putln("PyTuple_SET_ITEM(%s, 0, %s);" % (
2500 self.star_arg.entry.cname, Naming.self_cname))
2501 temp = code.funcstate.allocate_temp(PyrexTypes.c_py_ssize_t_type, manage_ref=False)
2502 code.putln("for (%s=0; %s < PyTuple_GET_SIZE(%s); %s++) {" % (
2503 temp, temp, Naming.args_cname, temp))
2504 code.putln("PyObject* item = PyTuple_GET_ITEM(%s, %s);" % (
2505 Naming.args_cname, temp))
2506 code.put_incref("item", py_object_type)
2507 code.put_giveref("item")
2508 code.putln("PyTuple_SET_ITEM(%s, %s+1, item);" % (
2509 self.star_arg.entry.cname, temp))
2511 code.funcstate.release_temp(temp)
2512 self.star_arg.entry.xdecref_cleanup = 0
2514 code.put_incref(Naming.args_cname, py_object_type)
2515 code.putln("%s = %s;" % (
2516 self.star_arg.entry.cname,
2518 self.star_arg.entry.xdecref_cleanup = 0
2520 def generate_tuple_and_keyword_parsing_code(self, positional_args,
2521 kw_only_args, success_label, code):
2522 argtuple_error_label = code.new_label("argtuple_error")
2524 min_positional_args = self.num_required_args - self.num_required_kw_args
2525 if len(self.args) > 0 and (self.args[0].is_self_arg or self.args[0].is_type_arg):
2526 min_positional_args -= 1
2527 max_positional_args = len(positional_args)
2528 has_fixed_positional_count = not self.star_arg and \
2529 min_positional_args == max_positional_args
2531 if self.num_required_kw_args:
2532 code.globalstate.use_utility_code(raise_keyword_required_utility_code)
2534 if self.starstar_arg or self.star_arg:
2535 self.generate_stararg_init_code(max_positional_args, code)
2537 # --- optimised code when we receive keyword arguments
2538 if self.num_required_kw_args:
2539 likely_hint = "likely"
2541 likely_hint = "unlikely"
2542 code.putln("if (%s(%s)) {" % (likely_hint, Naming.kwds_cname))
2543 self.generate_keyword_unpacking_code(
2544 min_positional_args, max_positional_args,
2545 has_fixed_positional_count,
2546 positional_args, kw_only_args, argtuple_error_label, code)
2548 # --- optimised code when we do not receive any keyword arguments
2549 if (self.num_required_kw_args and min_positional_args > 0) or min_positional_args == max_positional_args:
2550 # Python raises arg tuple related errors first, so we must
2551 # check the length here
2552 if min_positional_args == max_positional_args and not self.star_arg:
2556 code.putln('} else if (PyTuple_GET_SIZE(%s) %s %d) {' % (
2557 Naming.args_cname, compare, min_positional_args))
2558 code.put_goto(argtuple_error_label)
2560 if self.num_required_kw_args:
2561 # pure error case: keywords required but not passed
2562 if max_positional_args > min_positional_args and not self.star_arg:
2563 code.putln('} else if (PyTuple_GET_SIZE(%s) > %d) {' % (
2564 Naming.args_cname, max_positional_args))
2565 code.put_goto(argtuple_error_label)
2566 code.putln('} else {')
2567 for i, arg in enumerate(kw_only_args):
2569 pystring_cname = code.intern_identifier(arg.name)
2570 # required keyword-only argument missing
2571 code.put('__Pyx_RaiseKeywordRequired("%s", %s); ' % (
2574 code.putln(code.error_goto(self.pos))
2577 elif min_positional_args == max_positional_args:
2578 # parse the exact number of positional arguments from the
2580 code.putln('} else {')
2581 for i, arg in enumerate(positional_args):
2582 item = "PyTuple_GET_ITEM(%s, %d)" % (Naming.args_cname, i)
2583 self.generate_arg_assignment(arg, item, code)
2584 self.generate_arg_default_assignments(code)
2587 # parse the positional arguments from the variable length
2589 code.putln('} else {')
2590 self.generate_arg_default_assignments(code)
2591 code.putln('switch (PyTuple_GET_SIZE(%s)) {' % Naming.args_cname)
2593 code.putln('default:')
2594 reversed_args = list(enumerate(positional_args))[::-1]
2595 for i, arg in reversed_args:
2596 if i >= min_positional_args-1:
2597 if min_positional_args > 1:
2598 code.putln('case %2d:' % (i+1)) # pure code beautification
2600 code.put('case %2d: ' % (i+1))
2601 item = "PyTuple_GET_ITEM(%s, %d)" % (Naming.args_cname, i)
2602 self.generate_arg_assignment(arg, item, code)
2603 if min_positional_args == 0:
2604 code.put('case 0: ')
2605 code.putln('break;')
2607 if min_positional_args:
2608 for i in range(min_positional_args-1, -1, -1):
2609 code.putln('case %2d:' % i)
2610 code.put_goto(argtuple_error_label)
2612 code.put('default: ')
2613 code.put_goto(argtuple_error_label)
2618 if code.label_used(argtuple_error_label):
2619 code.put_goto(success_label)
2620 code.put_label(argtuple_error_label)
2621 code.globalstate.use_utility_code(raise_argtuple_invalid_utility_code)
2622 code.put('__Pyx_RaiseArgtupleInvalid("%s", %d, %d, %d, PyTuple_GET_SIZE(%s)); ' % (
2623 self.name, has_fixed_positional_count,
2624 min_positional_args, max_positional_args,
2626 code.putln(code.error_goto(self.pos))
2628 def generate_arg_default_assignments(self, code):
2629 for arg in self.args:
2630 if arg.is_generic and arg.default:
2634 arg.calculate_default_value_code(code)))
2636 def generate_stararg_init_code(self, max_positional_args, code):
2637 if self.starstar_arg:
2638 self.starstar_arg.entry.xdecref_cleanup = 0
2639 code.putln('%s = PyDict_New(); if (unlikely(!%s)) return %s;' % (
2640 self.starstar_arg.entry.cname,
2641 self.starstar_arg.entry.cname,
2642 self.error_value()))
2643 code.put_gotref(self.starstar_arg.entry.cname)
2645 self.star_arg.entry.xdecref_cleanup = 0
2646 code.putln('if (PyTuple_GET_SIZE(%s) > %d) {' % (
2648 max_positional_args))
2649 code.put('%s = PyTuple_GetSlice(%s, %d, PyTuple_GET_SIZE(%s)); ' % (
2650 self.star_arg.entry.cname, Naming.args_cname,
2651 max_positional_args, Naming.args_cname))
2652 code.put_gotref(self.star_arg.entry.cname)
2653 if self.starstar_arg:
2655 code.putln("if (unlikely(!%s)) {" % self.star_arg.entry.cname)
2656 code.put_decref_clear(self.starstar_arg.entry.cname, py_object_type)
2657 code.putln('return %s;' % self.error_value())
2660 code.putln("if (unlikely(!%s)) return %s;" % (
2661 self.star_arg.entry.cname, self.error_value()))
2662 code.putln('} else {')
2663 code.put("%s = %s; " % (self.star_arg.entry.cname, Naming.empty_tuple))
2664 code.put_incref(Naming.empty_tuple, py_object_type)
2667 def generate_keyword_unpacking_code(self, min_positional_args, max_positional_args,
2668 has_fixed_positional_count, positional_args,
2669 kw_only_args, argtuple_error_label, code):
2670 all_args = tuple(positional_args) + tuple(kw_only_args)
2671 max_args = len(all_args)
2673 code.putln("Py_ssize_t kw_args = PyDict_Size(%s);" %
2675 # the 'values' array collects borrowed references to arguments
2676 # before doing any type coercion etc.
2677 code.putln("PyObject* values[%d] = {%s};" % (
2678 max_args, ','.join('0'*max_args)))
2680 # assign borrowed Python default values to the values array,
2681 # so that they can be overwritten by received arguments below
2682 for i, arg in enumerate(all_args):
2683 if arg.default and arg.type.is_pyobject:
2684 default_value = arg.calculate_default_value_code(code)
2685 code.putln('values[%d] = %s;' % (i, arg.type.as_pyobject(default_value)))
2687 # parse the args tuple and check that it's not too long
2688 code.putln('switch (PyTuple_GET_SIZE(%s)) {' % Naming.args_cname)
2690 code.putln('default:')
2691 for i in range(max_positional_args-1, -1, -1):
2692 code.put('case %2d: ' % (i+1))
2693 code.putln("values[%d] = PyTuple_GET_ITEM(%s, %d);" % (
2694 i, Naming.args_cname, i))
2695 code.putln('case 0: break;')
2696 if not self.star_arg:
2697 code.put('default: ') # more arguments than allowed
2698 code.put_goto(argtuple_error_label)
2701 # now fill up the positional/required arguments with values
2703 if self.num_required_args or max_positional_args > 0:
2704 last_required_arg = -1
2705 for i, arg in enumerate(all_args):
2707 last_required_arg = i
2708 if last_required_arg < max_positional_args:
2709 last_required_arg = max_positional_args-1
2710 num_required_args = self.num_required_args
2711 if max_positional_args > 0:
2712 code.putln('switch (PyTuple_GET_SIZE(%s)) {' % Naming.args_cname)
2713 for i, arg in enumerate(all_args[:last_required_arg+1]):
2714 if max_positional_args > 0 and i <= max_positional_args:
2715 if self.star_arg and i == max_positional_args:
2716 code.putln('default:')
2718 code.putln('case %2d:' % i)
2719 pystring_cname = code.intern_identifier(arg.name)
2722 # handled separately below
2724 code.putln('if (kw_args > 0) {')
2725 code.putln('PyObject* value = PyDict_GetItem(%s, %s);' % (
2726 Naming.kwds_cname, pystring_cname))
2727 code.putln('if (value) { values[%d] = value; kw_args--; }' % i)
2730 num_required_args -= 1
2731 code.putln('values[%d] = PyDict_GetItem(%s, %s);' % (
2732 i, Naming.kwds_cname, pystring_cname))
2733 code.putln('if (likely(values[%d])) kw_args--;' % i);
2734 if i < min_positional_args:
2736 # special case: we know arg 0 is missing
2738 code.put_goto(argtuple_error_label)
2740 # print the correct number of values (args or
2741 # kwargs) that were passed into positional
2742 # arguments up to this point
2743 code.putln('else {')
2744 code.globalstate.use_utility_code(raise_argtuple_invalid_utility_code)
2745 code.put('__Pyx_RaiseArgtupleInvalid("%s", %d, %d, %d, %d); ' % (
2746 self.name, has_fixed_positional_count,
2747 min_positional_args, max_positional_args, i))
2748 code.putln(code.error_goto(self.pos))
2751 code.putln('else {')
2752 code.put('__Pyx_RaiseKeywordRequired("%s", %s); ' %(
2753 self.name, pystring_cname))
2754 code.putln(code.error_goto(self.pos))
2756 if max_positional_args > 0:
2759 if kw_only_args and not self.starstar_arg:
2760 # unpack optional keyword-only arguments
2761 # checking for interned strings in a dict is faster than iterating
2762 # but it's too likely that we must iterate if we expect **kwargs
2764 for i, arg in enumerate(all_args[max_positional_args:]):
2765 if not arg.kw_only or not arg.default:
2767 optional_args.append((i+max_positional_args, arg))
2769 # this mimics an unrolled loop so that we can "break" out of it
2770 code.putln('while (kw_args > 0) {')
2771 code.putln('PyObject* value;')
2772 for i, arg in optional_args:
2773 pystring_cname = code.intern_identifier(arg.name)
2775 'value = PyDict_GetItem(%s, %s);' % (
2776 Naming.kwds_cname, pystring_cname))
2778 'if (value) { values[%d] = value; if (!(--kw_args)) break; }' % i)
2779 code.putln('break;')
2782 code.putln('if (unlikely(kw_args > 0)) {')
2783 # non-positional/-required kw args left in dict: default args,
2784 # kw-only args, **kwargs or error
2786 # This is sort of a catch-all: except for checking required
2787 # arguments, this will always do the right thing for unpacking
2788 # keyword arguments, so that we can concentrate on optimising
2789 # common cases above.
2790 if max_positional_args == 0:
2793 code.putln("const Py_ssize_t used_pos_args = (PyTuple_GET_SIZE(%s) < %d) ? PyTuple_GET_SIZE(%s) : %d;" % (
2794 Naming.args_cname, max_positional_args,
2795 Naming.args_cname, max_positional_args))
2796 pos_arg_count = "used_pos_args"
2798 pos_arg_count = "PyTuple_GET_SIZE(%s)" % Naming.args_cname
2799 code.globalstate.use_utility_code(parse_keywords_utility_code)
2801 'if (unlikely(__Pyx_ParseOptionalKeywords(%s, %s, %s, values, %s, "%s") < 0)) ' % (
2803 Naming.pykwdlist_cname,
2804 self.starstar_arg and self.starstar_arg.entry.cname or '0',
2807 code.putln(code.error_goto(self.pos))
2810 # convert arg values to their final type and assign them
2811 for i, arg in enumerate(all_args):
2812 if arg.default and not arg.type.is_pyobject:
2813 code.putln("if (values[%d]) {" % i)
2814 self.generate_arg_assignment(arg, "values[%d]" % i, code)
2815 if arg.default and not arg.type.is_pyobject:
2816 code.putln('} else {')
2820 arg.calculate_default_value_code(code)))
2823 def generate_argument_conversion_code(self, code):
2824 # Generate code to convert arguments from signature type to
2825 # declared type, if needed. Also copies signature arguments
2826 # into closure fields.
2827 for arg in self.args:
2828 if arg.needs_conversion:
2829 self.generate_arg_conversion(arg, code)
2830 elif arg.entry.in_closure:
2831 code.putln('%s = %s;' % (arg.entry.cname, arg.hdr_cname))
2832 if arg.type.is_pyobject:
2833 code.put_var_incref(arg.entry)
2835 def generate_arg_conversion(self, arg, code):
2836 # Generate conversion code for one argument.
2837 old_type = arg.hdr_type
2839 if old_type.is_pyobject:
2841 code.putln("if (%s) {" % arg.hdr_cname)
2843 code.putln("assert(%s); {" % arg.hdr_cname)
2844 self.generate_arg_conversion_from_pyobject(arg, code)
2846 elif new_type.is_pyobject:
2847 self.generate_arg_conversion_to_pyobject(arg, code)
2849 if new_type.assignable_from(old_type):
2851 "%s = %s;" % (arg.entry.cname, arg.hdr_cname))
2854 "Cannot convert 1 argument from '%s' to '%s'" %
2855 (old_type, new_type))
2857 def generate_arg_conversion_from_pyobject(self, arg, code):
2859 func = new_type.from_py_function
2860 # copied from CoerceFromPyTypeNode
2862 lhs = arg.entry.cname
2863 rhs = "%s(%s)" % (func, arg.hdr_cname)
2864 if new_type.is_enum:
2865 rhs = PyrexTypes.typecast(new_type, PyrexTypes.c_long_type, rhs)
2866 code.putln("%s = %s; %s" % (
2869 code.error_goto_if(new_type.error_condition(arg.entry.cname), arg.pos)))
2872 "Cannot convert Python object argument to type '%s'"
2875 def generate_arg_conversion_to_pyobject(self, arg, code):
2876 old_type = arg.hdr_type
2877 func = old_type.to_py_function
2879 code.putln("%s = %s(%s); %s" % (
2883 code.error_goto_if_null(arg.entry.cname, arg.pos)))
2884 code.put_var_gotref(arg.entry)
2887 "Cannot convert argument of type '%s' to Python object"
2890 def generate_argument_type_tests(self, code):
2891 # Generate type tests for args whose signature
2892 # type is PyObject * and whose declared type is
2893 # a subtype thereof.
2894 for arg in self.args:
2895 if arg.needs_type_test:
2896 self.generate_arg_type_test(arg, code)
2897 elif not arg.accept_none and arg.type.is_pyobject:
2898 self.generate_arg_none_check(arg, code)
2900 def error_value(self):
2901 return self.entry.signature.error_value
2903 def caller_will_check_exceptions(self):
2906 class OverrideCheckNode(StatNode):
2907 # A Node for dispatching to the def method if it
2916 child_attrs = ['body']
2920 def analyse_expressions(self, env):
2921 self.args = env.arg_entries
2922 if self.py_func.is_module_scope:
2927 self.func_node = ExprNodes.RawCNameExprNode(self.pos, py_object_type)
2928 call_tuple = ExprNodes.TupleNode(self.pos, args=[ExprNodes.NameNode(self.pos, name=arg.name) for arg in self.args[first_arg:]])
2929 call_node = ExprNodes.SimpleCallNode(self.pos,
2930 function=self.func_node,
2931 args=[ExprNodes.NameNode(self.pos, name=arg.name) for arg in self.args[first_arg:]])
2932 self.body = ReturnStatNode(self.pos, value=call_node)
2933 self.body.analyse_expressions(env)
2935 def generate_execution_code(self, code):
2936 interned_attr_cname = code.intern_identifier(self.py_func.entry.name)
2937 # Check to see if we are an extension type
2938 if self.py_func.is_module_scope:
2939 self_arg = "((PyObject *)%s)" % Naming.module_cname
2941 self_arg = "((PyObject *)%s)" % self.args[0].cname
2942 code.putln("/* Check if called by wrapper */")
2943 code.putln("if (unlikely(%s)) ;" % Naming.skip_dispatch_cname)
2944 code.putln("/* Check if overriden in Python */")
2945 if self.py_func.is_module_scope:
2946 code.putln("else {")
2948 code.putln("else if (unlikely(Py_TYPE(%s)->tp_dictoffset != 0)) {" % self_arg)
2949 func_node_temp = code.funcstate.allocate_temp(py_object_type, manage_ref=True)
2950 self.func_node.set_cname(func_node_temp)
2951 # need to get attribute manually--scope would return cdef method
2952 err = code.error_goto_if_null(func_node_temp, self.pos)
2953 code.putln("%s = PyObject_GetAttr(%s, %s); %s" % (
2954 func_node_temp, self_arg, interned_attr_cname, err))
2955 code.put_gotref(func_node_temp)
2956 is_builtin_function_or_method = "PyCFunction_Check(%s)" % func_node_temp
2957 is_overridden = "(PyCFunction_GET_FUNCTION(%s) != (void *)&%s)" % (
2958 func_node_temp, self.py_func.entry.func_cname)
2959 code.putln("if (!%s || %s) {" % (is_builtin_function_or_method, is_overridden))
2960 self.body.generate_execution_code(code)
2962 code.put_decref_clear(func_node_temp, PyrexTypes.py_object_type)
2963 code.funcstate.release_temp(func_node_temp)
2966 class ClassDefNode(StatNode, BlockNode):
2969 class PyClassDefNode(ClassDefNode):
2970 # A Python class definition.
2972 # name EncodedString Name of the class
2973 # doc string or None
2974 # body StatNode Attribute definition code
2975 # entry Symtab.Entry
2976 # scope PyClassScope
2977 # decorators [DecoratorNode] list of decorators or None
2979 # The following subnodes are constructed internally:
2981 # dict DictNode Class dictionary or Py3 namespace
2982 # classobj ClassNode Class object
2983 # target NameNode Variable to assign class object to
2985 child_attrs = ["body", "dict", "metaclass", "mkw", "bases", "classobj", "target"]
2987 py3_style_class = False # Python3 style class (bases+kwargs)
2989 def __init__(self, pos, name, bases, doc, body, decorators = None,
2990 keyword_args = None, starstar_arg = None):
2991 StatNode.__init__(self, pos)
2995 self.decorators = decorators
2997 if self.doc and Options.docstrings:
2998 doc = embed_position(self.pos, self.doc)
2999 doc_node = ExprNodes.StringNode(pos, value = doc)
3002 if keyword_args or starstar_arg:
3003 self.py3_style_class = True
3005 self.metaclass = None
3006 if keyword_args and not starstar_arg:
3007 for i, item in list(enumerate(keyword_args.key_value_pairs))[::-1]:
3008 if item.key.value == 'metaclass':
3009 if self.metaclass is not None:
3010 error(item.pos, "keyword argument 'metaclass' passed multiple times")
3011 # special case: we already know the metaclass,
3012 # so we don't need to do the "build kwargs,
3013 # find metaclass" dance at runtime
3014 self.metaclass = item.value
3015 del keyword_args.key_value_pairs[i]
3016 if starstar_arg or (keyword_args and keyword_args.key_value_pairs):
3017 self.mkw = ExprNodes.KeywordArgsNode(
3018 pos, keyword_args = keyword_args, starstar_arg = starstar_arg)
3020 self.mkw = ExprNodes.NullNode(pos)
3021 if self.metaclass is None:
3022 self.metaclass = ExprNodes.PyClassMetaclassNode(
3023 pos, mkw = self.mkw, bases = self.bases)
3024 self.dict = ExprNodes.PyClassNamespaceNode(pos, name = name,
3025 doc = doc_node, metaclass = self.metaclass, bases = self.bases,
3027 self.classobj = ExprNodes.Py3ClassNode(pos, name = name,
3028 bases = self.bases, dict = self.dict, doc = doc_node,
3029 metaclass = self.metaclass, mkw = self.mkw)
3031 self.dict = ExprNodes.DictNode(pos, key_value_pairs = [])
3032 self.metaclass = None
3035 self.classobj = ExprNodes.ClassNode(pos, name = name,
3036 bases = bases, dict = self.dict, doc = doc_node)
3037 self.target = ExprNodes.NameNode(pos, name = name)
3039 def as_cclass(self):
3041 Return this node as if it were declared as an extension class
3043 if self.py3_style_class:
3044 error(self.classobj.pos, "Python3 style class could not be represented as C class")
3046 bases = self.classobj.bases.args
3048 base_class_name = None
3049 base_class_module = None
3050 elif len(bases) == 1:
3053 from ExprNodes import AttributeNode, NameNode
3054 while isinstance(base, AttributeNode):
3055 path.insert(0, base.attribute)
3057 if isinstance(base, NameNode):
3058 path.insert(0, base.name)
3059 base_class_name = path[-1]
3061 base_class_module = u'.'.join(path[:-1])
3063 base_class_module = None
3065 error(self.classobj.bases.args.pos, "Invalid base class")
3067 error(self.classobj.bases.args.pos, "C class may only have one base class")
3070 return CClassDefNode(self.pos,
3071 visibility = 'private',
3073 class_name = self.name,
3074 base_class_module = base_class_module,
3075 base_class_name = base_class_name,
3076 decorators = self.decorators,
3081 def create_scope(self, env):
3083 while genv.is_py_class_scope or genv.is_c_class_scope:
3084 genv = genv.outer_scope
3085 cenv = self.scope = PyClassScope(name = self.name, outer_scope = genv)
3088 def analyse_declarations(self, env):
3089 self.target.analyse_target_declaration(env)
3090 cenv = self.create_scope(env)
3091 cenv.directives = env.directives
3092 cenv.class_obj_cname = self.target.entry.cname
3093 self.body.analyse_declarations(cenv)
3095 def analyse_expressions(self, env):
3096 if self.py3_style_class:
3097 self.bases.analyse_expressions(env)
3098 self.metaclass.analyse_expressions(env)
3099 self.mkw.analyse_expressions(env)
3100 self.dict.analyse_expressions(env)
3101 self.classobj.analyse_expressions(env)
3102 genv = env.global_scope()
3104 self.body.analyse_expressions(cenv)
3105 self.target.analyse_target_expression(env, self.classobj)
3107 def generate_function_definitions(self, env, code):
3108 self.generate_lambda_definitions(self.scope, code)
3109 self.body.generate_function_definitions(self.scope, code)
3111 def generate_execution_code(self, code):
3112 code.pyclass_stack.append(self)
3114 if self.py3_style_class:
3115 self.bases.generate_evaluation_code(code)
3116 self.mkw.generate_evaluation_code(code)
3117 self.metaclass.generate_evaluation_code(code)
3118 self.dict.generate_evaluation_code(code)
3119 cenv.namespace_cname = cenv.class_obj_cname = self.dict.result()
3120 self.body.generate_execution_code(code)
3121 self.classobj.generate_evaluation_code(code)
3122 cenv.namespace_cname = cenv.class_obj_cname = self.classobj.result()
3123 self.target.generate_assignment_code(self.classobj, code)
3124 self.dict.generate_disposal_code(code)
3125 self.dict.free_temps(code)
3126 if self.py3_style_class:
3127 self.mkw.generate_disposal_code(code)
3128 self.mkw.free_temps(code)
3129 self.metaclass.generate_disposal_code(code)
3130 self.metaclass.free_temps(code)
3131 self.bases.generate_disposal_code(code)
3132 self.bases.free_temps(code)
3133 code.pyclass_stack.pop()
3135 class CClassDefNode(ClassDefNode):
3136 # An extension type definition.
3138 # visibility 'private' or 'public' or 'extern'
3139 # typedef_flag boolean
3141 # module_name string or None For import of extern type objects
3142 # class_name string Unqualified name of class
3143 # as_name string or None Name to declare as in this scope
3144 # base_class_module string or None Module containing the base class
3145 # base_class_name string or None Name of the base class
3146 # objstruct_name string or None Specified C name of object struct
3147 # typeobj_name string or None Specified C name of type object
3148 # in_pxd boolean Is in a .pxd file
3149 # decorators [DecoratorNode] list of decorators or None
3150 # doc string or None
3151 # body StatNode or None
3152 # entry Symtab.Entry
3153 # base_type PyExtensionType or None
3154 # buffer_defaults_node DictNode or None Declares defaults for a buffer
3155 # buffer_defaults_pos
3157 child_attrs = ["body"]
3158 buffer_defaults_node = None
3159 buffer_defaults_pos = None
3160 typedef_flag = False
3162 objstruct_name = None
3167 def analyse_declarations(self, env):
3168 #print "CClassDefNode.analyse_declarations:", self.class_name
3169 #print "...visibility =", self.visibility
3170 #print "...module_name =", self.module_name
3173 if self.buffer_defaults_node:
3174 buffer_defaults = Buffer.analyse_buffer_options(self.buffer_defaults_pos,
3175 env, [], self.buffer_defaults_node,
3176 need_complete=False)
3178 buffer_defaults = None
3180 if env.in_cinclude and not self.objstruct_name:
3181 error(self.pos, "Object struct name specification required for "
3182 "C class defined in 'extern from' block")
3183 self.base_type = None
3184 # Now that module imports are cached, we need to
3185 # import the modules for extern classes.
3186 if self.module_name:
3188 for module in env.cimported_modules:
3189 if module.name == self.module_name:
3190 self.module = module
3191 if self.module is None:
3192 self.module = ModuleScope(self.module_name, None, env.context)
3193 self.module.has_extern_class = 1
3194 env.add_imported_module(self.module)
3196 if self.base_class_name:
3197 if self.base_class_module:
3198 base_class_scope = env.find_module(self.base_class_module, self.pos)
3200 base_class_scope = env
3201 if self.base_class_name == 'object':
3202 # extension classes are special and don't need to inherit from object
3203 if base_class_scope is None or base_class_scope.lookup('object') is None:
3204 self.base_class_name = None
3205 self.base_class_module = None
3206 base_class_scope = None
3207 if base_class_scope:
3208 base_class_entry = base_class_scope.find(self.base_class_name, self.pos)
3209 if base_class_entry:
3210 if not base_class_entry.is_type:
3211 error(self.pos, "'%s' is not a type name" % self.base_class_name)
3212 elif not base_class_entry.type.is_extension_type and \
3213 not (base_class_entry.type.is_builtin_type and \
3214 base_class_entry.type.objstruct_cname):
3215 error(self.pos, "'%s' is not an extension type" % self.base_class_name)
3216 elif not base_class_entry.type.is_complete():
3217 error(self.pos, "Base class '%s' of type '%s' is incomplete" % (
3218 self.base_class_name, self.class_name))
3219 elif base_class_entry.type.scope and base_class_entry.type.scope.directives and \
3220 base_class_entry.type.scope.directives['final']:
3221 error(self.pos, "Base class '%s' of type '%s' is final" % (
3222 self.base_class_name, self.class_name))
3223 elif base_class_entry.type.is_builtin_type and \
3224 base_class_entry.type.name in ('tuple', 'str', 'bytes'):
3225 error(self.pos, "inheritance from PyVarObject types like '%s' is not currently supported"
3226 % base_class_entry.type.name)
3228 self.base_type = base_class_entry.type
3229 has_body = self.body is not None
3230 if self.module_name and self.visibility != 'extern':
3231 module_path = self.module_name.split(".")
3232 home_scope = env.find_imported_module(module_path, self.pos)
3238 if self.visibility == 'extern':
3239 if (self.module_name == '__builtin__' and
3240 self.class_name in Builtin.builtin_types and
3241 env.qualified_name[:8] != 'cpython.'): # allow overloaded names for cimporting from cpython
3242 warning(self.pos, "%s already a builtin Cython type" % self.class_name, 1)
3244 self.entry = home_scope.declare_c_class(
3245 name = self.class_name,
3247 defining = has_body and self.in_pxd,
3248 implementing = has_body and not self.in_pxd,
3249 module_name = self.module_name,
3250 base_type = self.base_type,
3251 objstruct_cname = self.objstruct_name,
3252 typeobj_cname = self.typeobj_name,
3253 visibility = self.visibility,
3254 typedef_flag = self.typedef_flag,
3256 buffer_defaults = buffer_defaults,
3257 shadow = self.shadow)
3259 home_scope.lookup(self.class_name).as_variable = self.entry
3260 if home_scope is not env and self.visibility == 'extern':
3261 env.add_imported_entry(self.class_name, self.entry, self.pos)
3262 self.scope = scope = self.entry.type.scope
3263 if scope is not None:
3264 scope.directives = env.directives
3266 if self.doc and Options.docstrings:
3267 scope.doc = embed_position(self.pos, self.doc)
3270 self.body.analyse_declarations(scope)
3274 scope.implemented = 1
3275 env.allocate_vtable_names(self.entry)
3277 def analyse_expressions(self, env):
3279 scope = self.entry.type.scope
3280 self.body.analyse_expressions(scope)
3282 def generate_function_definitions(self, env, code):
3284 self.generate_lambda_definitions(self.scope, code)
3285 self.body.generate_function_definitions(self.scope, code)
3287 def generate_execution_code(self, code):
3288 # This is needed to generate evaluation code for
3289 # default values of method arguments.
3291 self.body.generate_execution_code(code)
3293 def annotate(self, code):
3295 self.body.annotate(code)
3298 class PropertyNode(StatNode):
3299 # Definition of a property in an extension type.
3302 # doc EncodedString or None Doc string
3305 child_attrs = ["body"]
3307 def analyse_declarations(self, env):
3308 entry = env.declare_property(self.name, self.doc, self.pos)
3310 entry.scope.directives = env.directives
3311 self.body.analyse_declarations(entry.scope)
3313 def analyse_expressions(self, env):
3314 self.body.analyse_expressions(env)
3316 def generate_function_definitions(self, env, code):
3317 self.body.generate_function_definitions(env, code)
3319 def generate_execution_code(self, code):
3322 def annotate(self, code):
3323 self.body.annotate(code)
3326 class GlobalNode(StatNode):
3327 # Global variable declaration.
3333 def analyse_declarations(self, env):
3334 for name in self.names:
3335 env.declare_global(name, self.pos)
3337 def analyse_expressions(self, env):
3340 def generate_execution_code(self, code):
3344 class ExprStatNode(StatNode):
3345 # Expression used as a statement.
3349 child_attrs = ["expr"]
3351 def analyse_declarations(self, env):
3353 if isinstance(self.expr, ExprNodes.GeneralCallNode):
3354 func = self.expr.function.as_cython_attribute()
3355 if func == u'declare':
3356 args, kwds = self.expr.explicit_args_kwds()
3358 error(self.expr.pos, "Variable names must be specified.")
3359 for var, type_node in kwds.key_value_pairs:
3360 type = type_node.analyse_as_type(env)
3362 error(type_node.pos, "Unknown type")
3364 env.declare_var(var.value, type, var.pos, is_cdef = True)
3365 self.__class__ = PassStatNode
3367 def analyse_expressions(self, env):
3368 self.expr.analyse_expressions(env)
3370 def nogil_check(self, env):
3371 if self.expr.type.is_pyobject and self.expr.is_temp:
3374 gil_message = "Discarding owned Python object"
3376 def generate_execution_code(self, code):
3377 self.expr.generate_evaluation_code(code)
3378 if not self.expr.is_temp and self.expr.result():
3379 code.putln("%s;" % self.expr.result())
3380 self.expr.generate_disposal_code(code)
3381 self.expr.free_temps(code)
3383 def generate_function_definitions(self, env, code):
3384 self.expr.generate_function_definitions(env, code)
3386 def annotate(self, code):
3387 self.expr.annotate(code)
3390 class AssignmentNode(StatNode):
3391 # Abstract base class for assignment nodes.
3393 # The analyse_expressions and generate_execution_code
3394 # phases of assignments are split into two sub-phases
3395 # each, to enable all the right hand sides of a
3396 # parallel assignment to be evaluated before assigning
3397 # to any of the left hand sides.
3399 def analyse_expressions(self, env):
3400 self.analyse_types(env)
3402 # def analyse_expressions(self, env):
3403 # self.analyse_expressions_1(env)
3404 # self.analyse_expressions_2(env)
3406 def generate_execution_code(self, code):
3407 self.generate_rhs_evaluation_code(code)
3408 self.generate_assignment_code(code)
3411 class SingleAssignmentNode(AssignmentNode):
3412 # The simplest case:
3416 # lhs ExprNode Left hand side
3417 # rhs ExprNode Right hand side
3418 # first bool Is this guaranteed the first assignment to lhs?
3420 child_attrs = ["lhs", "rhs"]
3422 declaration_only = False
3424 def analyse_declarations(self, env):
3427 # handle declarations of the form x = cython.foo()
3428 if isinstance(self.rhs, ExprNodes.CallNode):
3429 func_name = self.rhs.function.as_cython_attribute()
3431 args, kwds = self.rhs.explicit_args_kwds()
3433 if func_name in ['declare', 'typedef']:
3434 if len(args) > 2 or kwds is not None:
3435 error(self.rhs.pos, "Can only declare one type at a time.")
3437 type = args[0].analyse_as_type(env)
3439 error(args[0].pos, "Unknown type")
3442 if func_name == 'declare':
3443 if isinstance(lhs, ExprNodes.NameNode):
3444 vars = [(lhs.name, lhs.pos)]
3445 elif isinstance(lhs, ExprNodes.TupleNode):
3446 vars = [(var.name, var.pos) for var in lhs.args]
3448 error(lhs.pos, "Invalid declaration")
3450 for var, pos in vars:
3451 env.declare_var(var, type, pos, is_cdef = True)
3456 self.declaration_only = True
3458 self.declaration_only = True
3459 if not isinstance(lhs, ExprNodes.NameNode):
3460 error(lhs.pos, "Invalid declaration.")
3461 env.declare_typedef(lhs.name, type, self.pos, visibility='private')
3463 elif func_name in ['struct', 'union']:
3464 self.declaration_only = True
3465 if len(args) > 0 or kwds is None:
3466 error(self.rhs.pos, "Struct or union members must be given by name.")
3469 for member, type_node in kwds.key_value_pairs:
3470 type = type_node.analyse_as_type(env)
3472 error(type_node.pos, "Unknown type")
3474 members.append((member.value, type, member.pos))
3475 if len(members) < len(kwds.key_value_pairs):
3477 if not isinstance(self.lhs, ExprNodes.NameNode):
3478 error(self.lhs.pos, "Invalid declaration.")
3479 name = self.lhs.name
3480 scope = StructOrUnionScope(name)
3481 env.declare_struct_or_union(name, func_name, scope, False, self.rhs.pos)
3482 for member, type, pos in members:
3483 scope.declare_var(member, type, pos)
3485 if self.declaration_only:
3488 self.lhs.analyse_target_declaration(env)
3490 def analyse_types(self, env, use_temp = 0):
3491 self.rhs.analyse_types(env)
3492 self.lhs.analyse_target_types(env)
3493 self.lhs.gil_assignment_check(env)
3494 self.rhs = self.rhs.coerce_to(self.lhs.type, env)
3496 self.rhs = self.rhs.coerce_to_temp(env)
3498 def generate_rhs_evaluation_code(self, code):
3499 self.rhs.generate_evaluation_code(code)
3501 def generate_assignment_code(self, code):
3502 self.lhs.generate_assignment_code(self.rhs, code)
3504 def generate_function_definitions(self, env, code):
3505 self.rhs.generate_function_definitions(env, code)
3507 def annotate(self, code):
3508 self.lhs.annotate(code)
3509 self.rhs.annotate(code)
3512 class CascadedAssignmentNode(AssignmentNode):
3513 # An assignment with multiple left hand sides:
3517 # lhs_list [ExprNode] Left hand sides
3518 # rhs ExprNode Right hand sides
3522 # coerced_rhs_list [ExprNode] RHS coerced to type of each LHS
3524 child_attrs = ["lhs_list", "rhs", "coerced_rhs_list"]
3525 coerced_rhs_list = None
3527 def analyse_declarations(self, env):
3528 for lhs in self.lhs_list:
3529 lhs.analyse_target_declaration(env)
3531 def analyse_types(self, env, use_temp = 0):
3532 self.rhs.analyse_types(env)
3533 if not self.rhs.is_simple():
3535 self.rhs = self.rhs.coerce_to_temp(env)
3537 self.rhs = self.rhs.coerce_to_simple(env)
3538 from ExprNodes import CloneNode
3539 self.coerced_rhs_list = []
3540 for lhs in self.lhs_list:
3541 lhs.analyse_target_types(env)
3542 lhs.gil_assignment_check(env)
3543 rhs = CloneNode(self.rhs)
3544 rhs = rhs.coerce_to(lhs.type, env)
3545 self.coerced_rhs_list.append(rhs)
3547 def generate_rhs_evaluation_code(self, code):
3548 self.rhs.generate_evaluation_code(code)
3550 def generate_assignment_code(self, code):
3551 for i in range(len(self.lhs_list)):
3552 lhs = self.lhs_list[i]
3553 rhs = self.coerced_rhs_list[i]
3554 rhs.generate_evaluation_code(code)
3555 lhs.generate_assignment_code(rhs, code)
3556 # Assignment has disposed of the cloned RHS
3557 self.rhs.generate_disposal_code(code)
3558 self.rhs.free_temps(code)
3560 def generate_function_definitions(self, env, code):
3561 self.rhs.generate_function_definitions(env, code)
3563 def annotate(self, code):
3564 for i in range(len(self.lhs_list)):
3565 lhs = self.lhs_list[i].annotate(code)
3566 rhs = self.coerced_rhs_list[i].annotate(code)
3567 self.rhs.annotate(code)
3570 class ParallelAssignmentNode(AssignmentNode):
3571 # A combined packing/unpacking assignment:
3575 # This has been rearranged by the parser into
3577 # a = d ; b = e ; c = f
3579 # but we must evaluate all the right hand sides
3580 # before assigning to any of the left hand sides.
3582 # stats [AssignmentNode] The constituent assignments
3584 child_attrs = ["stats"]
3586 def analyse_declarations(self, env):
3587 for stat in self.stats:
3588 stat.analyse_declarations(env)
3590 def analyse_expressions(self, env):
3591 for stat in self.stats:
3592 stat.analyse_types(env, use_temp = 1)
3594 # def analyse_expressions(self, env):
3595 # for stat in self.stats:
3596 # stat.analyse_expressions_1(env, use_temp = 1)
3597 # for stat in self.stats:
3598 # stat.analyse_expressions_2(env)
3600 def generate_execution_code(self, code):
3601 for stat in self.stats:
3602 stat.generate_rhs_evaluation_code(code)
3603 for stat in self.stats:
3604 stat.generate_assignment_code(code)
3606 def generate_function_definitions(self, env, code):
3607 for stat in self.stats:
3608 stat.generate_function_definitions(env, code)
3610 def annotate(self, code):
3611 for stat in self.stats:
3615 class InPlaceAssignmentNode(AssignmentNode):
3616 # An in place arithmetic operand:
3622 # lhs ExprNode Left hand side
3623 # rhs ExprNode Right hand side
3624 # op char one of "+-*/%^&|"
3625 # dup (ExprNode) copy of lhs used for operation (auto-generated)
3627 # This code is a bit tricky because in order to obey Python
3628 # semantics the sub-expressions (e.g. indices) of the lhs must
3629 # not be evaluated twice. So we must re-use the values calculated
3630 # in evaluation phase for the assignment phase as well.
3631 # Fortunately, the type of the lhs node is fairly constrained
3632 # (it must be a NameNode, AttributeNode, or IndexNode).
3634 child_attrs = ["lhs", "rhs"]
3636 def analyse_declarations(self, env):
3637 self.lhs.analyse_target_declaration(env)
3639 def analyse_types(self, env):
3640 self.rhs.analyse_types(env)
3641 self.lhs.analyse_target_types(env)
3643 def generate_execution_code(self, code):
3645 self.rhs.generate_evaluation_code(code)
3646 self.lhs.generate_subexpr_evaluation_code(code)
3647 c_op = self.operator
3651 error(self.pos, "No C inplace power operator")
3652 if isinstance(self.lhs, ExprNodes.IndexNode) and self.lhs.is_buffer_access:
3653 if self.lhs.type.is_pyobject:
3654 error(self.pos, "In-place operators not allowed on object buffers in this release.")
3655 if c_op in ('/', '%') and self.lhs.type.is_int and not code.directives['cdivision']:
3656 error(self.pos, "In-place non-c divide operators not allowed on int buffers.")
3657 self.lhs.generate_buffer_setitem_code(self.rhs, code, c_op)
3660 # TODO: make sure overload is declared
3661 code.putln("%s %s= %s;" % (self.lhs.result(), c_op, self.rhs.result()))
3662 self.lhs.generate_subexpr_disposal_code(code)
3663 self.lhs.free_subexpr_temps(code)
3664 self.rhs.generate_disposal_code(code)
3665 self.rhs.free_temps(code)
3667 def annotate(self, code):
3668 self.lhs.annotate(code)
3669 self.rhs.annotate(code)
3671 def create_binop_node(self):
3673 return ExprNodes.binop_node(self.pos, self.operator, self.lhs, self.rhs)
3676 class PrintStatNode(StatNode):
3679 # arg_tuple TupleNode
3680 # stream ExprNode or None (stdout)
3681 # append_newline boolean
3683 child_attrs = ["arg_tuple", "stream"]
3685 def analyse_expressions(self, env):
3687 self.stream.analyse_expressions(env)
3688 self.stream = self.stream.coerce_to_pyobject(env)
3689 self.arg_tuple.analyse_expressions(env)
3690 self.arg_tuple = self.arg_tuple.coerce_to_pyobject(env)
3691 env.use_utility_code(printing_utility_code)
3692 if len(self.arg_tuple.args) == 1 and self.append_newline:
3693 env.use_utility_code(printing_one_utility_code)
3695 nogil_check = Node.gil_error
3696 gil_message = "Python print statement"
3698 def generate_execution_code(self, code):
3700 self.stream.generate_evaluation_code(code)
3701 stream_result = self.stream.py_result()
3704 if len(self.arg_tuple.args) == 1 and self.append_newline:
3705 arg = self.arg_tuple.args[0]
3706 arg.generate_evaluation_code(code)
3709 "if (__Pyx_PrintOne(%s, %s) < 0) %s" % (
3712 code.error_goto(self.pos)))
3713 arg.generate_disposal_code(code)
3714 arg.free_temps(code)
3716 self.arg_tuple.generate_evaluation_code(code)
3718 "if (__Pyx_Print(%s, %s, %d) < 0) %s" % (
3720 self.arg_tuple.py_result(),
3721 self.append_newline,
3722 code.error_goto(self.pos)))
3723 self.arg_tuple.generate_disposal_code(code)
3724 self.arg_tuple.free_temps(code)
3727 self.stream.generate_disposal_code(code)
3728 self.stream.free_temps(code)
3730 def generate_function_definitions(self, env, code):
3732 self.stream.generate_function_definitions(env, code)
3733 self.arg_tuple.generate_function_definitions(env, code)
3735 def annotate(self, code):
3737 self.stream.annotate(code)
3738 self.arg_tuple.annotate(code)
3741 class ExecStatNode(StatNode):
3746 child_attrs = ["args"]
3748 def analyse_expressions(self, env):
3749 for i, arg in enumerate(self.args):
3750 arg.analyse_expressions(env)
3751 arg = arg.coerce_to_pyobject(env)
3753 env.use_utility_code(Builtin.pyexec_utility_code)
3755 nogil_check = Node.gil_error
3756 gil_message = "Python exec statement"
3758 def generate_execution_code(self, code):
3760 for arg in self.args:
3761 arg.generate_evaluation_code(code)
3762 args.append( arg.py_result() )
3763 args = tuple(args + ['0', '0'][:3-len(args)])
3764 temp_result = code.funcstate.allocate_temp(PyrexTypes.py_object_type, manage_ref=True)
3765 code.putln("%s = __Pyx_PyRun(%s, %s, %s);" % (
3766 (temp_result,) + args))
3767 for arg in self.args:
3768 arg.generate_disposal_code(code)
3769 arg.free_temps(code)
3771 code.error_goto_if_null(temp_result, self.pos))
3772 code.put_gotref(temp_result)
3773 code.put_decref_clear(temp_result, py_object_type)
3774 code.funcstate.release_temp(temp_result)
3776 def annotate(self, code):
3777 for arg in self.args:
3781 class DelStatNode(StatNode):
3786 child_attrs = ["args"]
3788 def analyse_declarations(self, env):
3789 for arg in self.args:
3790 arg.analyse_target_declaration(env)
3792 def analyse_expressions(self, env):
3793 for arg in self.args:
3794 arg.analyse_target_expression(env, None)
3795 if arg.type.is_pyobject:
3797 elif arg.type.is_ptr and arg.type.base_type.is_cpp_class:
3799 elif arg.type.is_cpp_class:
3800 error(arg.pos, "Deletion of non-heap C++ object")
3802 error(arg.pos, "Deletion of non-Python, non-C++ object")
3803 #arg.release_target_temp(env)
3805 def nogil_check(self, env):
3806 for arg in self.args:
3807 if arg.type.is_pyobject:
3810 gil_message = "Deleting Python object"
3812 def generate_execution_code(self, code):
3813 for arg in self.args:
3814 if arg.type.is_pyobject:
3815 arg.generate_deletion_code(code)
3816 elif arg.type.is_ptr and arg.type.base_type.is_cpp_class:
3817 arg.generate_result_code(code)
3818 code.putln("delete %s;" % arg.result())
3819 # else error reported earlier
3821 def annotate(self, code):
3822 for arg in self.args:
3826 class PassStatNode(StatNode):
3831 def analyse_expressions(self, env):
3834 def generate_execution_code(self, code):
3838 class BreakStatNode(StatNode):
3842 def analyse_expressions(self, env):
3845 def generate_execution_code(self, code):
3846 if not code.break_label:
3847 error(self.pos, "break statement not inside loop")
3849 code.put_goto(code.break_label)
3852 class ContinueStatNode(StatNode):
3856 def analyse_expressions(self, env):
3859 def generate_execution_code(self, code):
3860 if code.funcstate.in_try_finally:
3861 error(self.pos, "continue statement inside try of try...finally")
3862 elif not code.continue_label:
3863 error(self.pos, "continue statement not inside loop")
3865 code.put_goto(code.continue_label)
3868 class ReturnStatNode(StatNode):
3871 # value ExprNode or None
3872 # return_type PyrexType
3874 child_attrs = ["value"]
3876 def analyse_expressions(self, env):
3877 return_type = env.return_type
3878 self.return_type = return_type
3880 error(self.pos, "Return not inside a function body")
3883 self.value.analyse_types(env)
3884 if return_type.is_void or return_type.is_returncode:
3885 error(self.value.pos,
3886 "Return with value in void function")
3888 self.value = self.value.coerce_to(env.return_type, env)
3890 if (not return_type.is_void
3891 and not return_type.is_pyobject
3892 and not return_type.is_returncode):
3893 error(self.pos, "Return value required")
3895 def nogil_check(self, env):
3896 if self.return_type.is_pyobject:
3899 gil_message = "Returning Python object"
3901 def generate_execution_code(self, code):
3902 code.mark_pos(self.pos)
3903 if not self.return_type:
3904 # error reported earlier
3906 if self.return_type.is_pyobject:
3907 code.put_xdecref(Naming.retval_cname,
3910 self.value.generate_evaluation_code(code)
3911 self.value.make_owned_reference(code)
3914 Naming.retval_cname,
3915 self.value.result_as(self.return_type)))
3916 self.value.generate_post_assignment_code(code)
3917 self.value.free_temps(code)
3919 if self.return_type.is_pyobject:
3920 code.put_init_to_py_none(Naming.retval_cname, self.return_type)
3921 elif self.return_type.is_returncode:
3924 Naming.retval_cname,
3925 self.return_type.default_value))
3926 for cname, type in code.funcstate.temps_holding_reference():
3927 code.put_decref_clear(cname, type)
3928 code.put_goto(code.return_label)
3930 def generate_function_definitions(self, env, code):
3931 if self.value is not None:
3932 self.value.generate_function_definitions(env, code)
3934 def annotate(self, code):
3936 self.value.annotate(code)
3939 class RaiseStatNode(StatNode):
3942 # exc_type ExprNode or None
3943 # exc_value ExprNode or None
3944 # exc_tb ExprNode or None
3946 child_attrs = ["exc_type", "exc_value", "exc_tb"]
3948 def analyse_expressions(self, env):
3950 self.exc_type.analyse_types(env)
3951 self.exc_type = self.exc_type.coerce_to_pyobject(env)
3953 self.exc_value.analyse_types(env)
3954 self.exc_value = self.exc_value.coerce_to_pyobject(env)
3956 self.exc_tb.analyse_types(env)
3957 self.exc_tb = self.exc_tb.coerce_to_pyobject(env)
3958 # special cases for builtin exceptions
3959 self.builtin_exc_name = None
3960 if self.exc_type and not self.exc_value and not self.exc_tb:
3963 if isinstance(exc, ExprNodes.SimpleCallNode) and not exc.args:
3964 exc = exc.function # extract the exception type
3965 if exc.is_name and exc.entry.is_builtin:
3966 self.builtin_exc_name = exc.name
3967 if self.builtin_exc_name == 'MemoryError':
3968 self.exc_type = None # has a separate implementation
3970 nogil_check = Node.gil_error
3971 gil_message = "Raising exception"
3973 def generate_execution_code(self, code):
3974 if self.builtin_exc_name == 'MemoryError':
3975 code.putln('PyErr_NoMemory(); %s' % code.error_goto(self.pos))
3979 self.exc_type.generate_evaluation_code(code)
3980 type_code = self.exc_type.py_result()
3984 self.exc_value.generate_evaluation_code(code)
3985 value_code = self.exc_value.py_result()
3989 self.exc_tb.generate_evaluation_code(code)
3990 tb_code = self.exc_tb.py_result()
3993 code.globalstate.use_utility_code(raise_utility_code)
3995 "__Pyx_Raise(%s, %s, %s);" % (
3999 for obj in (self.exc_type, self.exc_value, self.exc_tb):
4001 obj.generate_disposal_code(code)
4002 obj.free_temps(code)
4004 code.error_goto(self.pos))
4006 def generate_function_definitions(self, env, code):
4007 if self.exc_type is not None:
4008 self.exc_type.generate_function_definitions(env, code)
4009 if self.exc_value is not None:
4010 self.exc_value.generate_function_definitions(env, code)
4011 if self.exc_tb is not None:
4012 self.exc_tb.generate_function_definitions(env, code)
4014 def annotate(self, code):
4016 self.exc_type.annotate(code)
4018 self.exc_value.annotate(code)
4020 self.exc_tb.annotate(code)
4023 class ReraiseStatNode(StatNode):
4027 def analyse_expressions(self, env):
4028 env.use_utility_code(restore_exception_utility_code)
4030 nogil_check = Node.gil_error
4031 gil_message = "Raising exception"
4033 def generate_execution_code(self, code):
4034 vars = code.funcstate.exc_vars
4036 for varname in vars:
4037 code.put_giveref(varname)
4038 code.putln("__Pyx_ErrRestore(%s, %s, %s);" % tuple(vars))
4039 for varname in vars:
4040 code.put("%s = 0; " % varname)
4042 code.putln(code.error_goto(self.pos))
4044 error(self.pos, "Reraise not inside except clause")
4047 class AssertStatNode(StatNode):
4051 # value ExprNode or None
4053 child_attrs = ["cond", "value"]
4055 def analyse_expressions(self, env):
4056 self.cond = self.cond.analyse_boolean_expression(env)
4058 self.value.analyse_types(env)
4059 self.value = self.value.coerce_to_pyobject(env)
4061 nogil_check = Node.gil_error
4062 gil_message = "Raising exception"
4064 def generate_execution_code(self, code):
4065 code.putln("#ifndef CYTHON_WITHOUT_ASSERTIONS")
4066 self.cond.generate_evaluation_code(code)
4068 "if (unlikely(!%s)) {" %
4071 self.value.generate_evaluation_code(code)
4073 "PyErr_SetObject(PyExc_AssertionError, %s);" %
4074 self.value.py_result())
4075 self.value.generate_disposal_code(code)
4076 self.value.free_temps(code)
4079 "PyErr_SetNone(PyExc_AssertionError);")
4081 code.error_goto(self.pos))
4084 self.cond.generate_disposal_code(code)
4085 self.cond.free_temps(code)
4086 code.putln("#endif")
4088 def generate_function_definitions(self, env, code):
4089 self.cond.generate_function_definitions(env, code)
4090 if self.value is not None:
4091 self.value.generate_function_definitions(env, code)
4093 def annotate(self, code):
4094 self.cond.annotate(code)
4096 self.value.annotate(code)
4099 class IfStatNode(StatNode):
4102 # if_clauses [IfClauseNode]
4103 # else_clause StatNode or None
4105 child_attrs = ["if_clauses", "else_clause"]
4107 def analyse_control_flow(self, env):
4108 env.start_branching(self.pos)
4109 for if_clause in self.if_clauses:
4110 if_clause.analyse_control_flow(env)
4111 env.next_branch(if_clause.end_pos())
4112 if self.else_clause:
4113 self.else_clause.analyse_control_flow(env)
4114 env.finish_branching(self.end_pos())
4116 def analyse_declarations(self, env):
4117 for if_clause in self.if_clauses:
4118 if_clause.analyse_declarations(env)
4119 if self.else_clause:
4120 self.else_clause.analyse_declarations(env)
4122 def analyse_expressions(self, env):
4123 for if_clause in self.if_clauses:
4124 if_clause.analyse_expressions(env)
4125 if self.else_clause:
4126 self.else_clause.analyse_expressions(env)
4128 def generate_execution_code(self, code):
4129 code.mark_pos(self.pos)
4130 end_label = code.new_label()
4131 for if_clause in self.if_clauses:
4132 if_clause.generate_execution_code(code, end_label)
4133 if self.else_clause:
4134 code.putln("/*else*/ {")
4135 self.else_clause.generate_execution_code(code)
4137 code.put_label(end_label)
4139 def generate_function_definitions(self, env, code):
4140 for clause in self.if_clauses:
4141 clause.generate_function_definitions(env, code)
4142 if self.else_clause is not None:
4143 self.else_clause.generate_function_definitions(env, code)
4145 def annotate(self, code):
4146 for if_clause in self.if_clauses:
4147 if_clause.annotate(code)
4148 if self.else_clause:
4149 self.else_clause.annotate(code)
4152 class IfClauseNode(Node):
4153 # if or elif clause in an if statement
4155 # condition ExprNode
4158 child_attrs = ["condition", "body"]
4160 def analyse_control_flow(self, env):
4161 self.body.analyse_control_flow(env)
4163 def analyse_declarations(self, env):
4164 self.body.analyse_declarations(env)
4166 def analyse_expressions(self, env):
4168 self.condition.analyse_temp_boolean_expression(env)
4169 self.body.analyse_expressions(env)
4171 def get_constant_condition_result(self):
4172 if self.condition.has_constant_result():
4173 return bool(self.condition.constant_result)
4177 def generate_execution_code(self, code, end_label):
4178 self.condition.generate_evaluation_code(code)
4181 self.condition.result())
4182 self.condition.generate_disposal_code(code)
4183 self.condition.free_temps(code)
4184 self.body.generate_execution_code(code)
4185 code.put_goto(end_label)
4188 def generate_function_definitions(self, env, code):
4189 self.condition.generate_function_definitions(env, code)
4190 self.body.generate_function_definitions(env, code)
4192 def annotate(self, code):
4193 self.condition.annotate(code)
4194 self.body.annotate(code)
4197 class SwitchCaseNode(StatNode):
4198 # Generated in the optimization of an if-elif-else node
4200 # conditions [ExprNode]
4203 child_attrs = ['conditions', 'body']
4205 def generate_execution_code(self, code):
4206 for cond in self.conditions:
4207 code.mark_pos(cond.pos)
4208 cond.generate_evaluation_code(code)
4209 code.putln("case %s:" % cond.result())
4210 self.body.generate_execution_code(code)
4211 code.putln("break;")
4213 def generate_function_definitions(self, env, code):
4214 for cond in self.conditions:
4215 cond.generate_function_definitions(env, code)
4216 self.body.generate_function_definitions(env, code)
4218 def annotate(self, code):
4219 for cond in self.conditions:
4221 self.body.annotate(code)
4223 class SwitchStatNode(StatNode):
4224 # Generated in the optimization of an if-elif-else node
4227 # cases [SwitchCaseNode]
4228 # else_clause StatNode or None
4230 child_attrs = ['test', 'cases', 'else_clause']
4232 def generate_execution_code(self, code):
4233 self.test.generate_evaluation_code(code)
4234 code.putln("switch (%s) {" % self.test.result())
4235 for case in self.cases:
4236 case.generate_execution_code(code)
4237 if self.else_clause is not None:
4238 code.putln("default:")
4239 self.else_clause.generate_execution_code(code)
4240 code.putln("break;")
4243 def generate_function_definitions(self, env, code):
4244 self.test.generate_function_definitions(env, code)
4245 for case in self.cases:
4246 case.generate_function_definitions(env, code)
4247 if self.else_clause is not None:
4248 self.else_clause.generate_function_definitions(env, code)
4250 def annotate(self, code):
4251 self.test.annotate(code)
4252 for case in self.cases:
4254 if self.else_clause is not None:
4255 self.else_clause.annotate(code)
4257 class LoopNode(object):
4259 def analyse_control_flow(self, env):
4260 env.start_branching(self.pos)
4261 self.body.analyse_control_flow(env)
4262 env.next_branch(self.body.end_pos())
4263 if self.else_clause:
4264 self.else_clause.analyse_control_flow(env)
4265 env.finish_branching(self.end_pos())
4268 class WhileStatNode(LoopNode, StatNode):
4271 # condition ExprNode
4273 # else_clause StatNode
4275 child_attrs = ["condition", "body", "else_clause"]
4277 def analyse_declarations(self, env):
4278 self.body.analyse_declarations(env)
4279 if self.else_clause:
4280 self.else_clause.analyse_declarations(env)
4282 def analyse_expressions(self, env):
4284 self.condition.analyse_temp_boolean_expression(env)
4285 self.body.analyse_expressions(env)
4286 if self.else_clause:
4287 self.else_clause.analyse_expressions(env)
4289 def generate_execution_code(self, code):
4290 old_loop_labels = code.new_loop_labels()
4293 self.condition.generate_evaluation_code(code)
4294 self.condition.generate_disposal_code(code)
4297 self.condition.result())
4298 self.condition.free_temps(code)
4299 self.body.generate_execution_code(code)
4300 code.put_label(code.continue_label)
4302 break_label = code.break_label
4303 code.set_loop_labels(old_loop_labels)
4304 if self.else_clause:
4305 code.putln("/*else*/ {")
4306 self.else_clause.generate_execution_code(code)
4308 code.put_label(break_label)
4310 def generate_function_definitions(self, env, code):
4311 self.condition.generate_function_definitions(env, code)
4312 self.body.generate_function_definitions(env, code)
4313 if self.else_clause is not None:
4314 self.else_clause.generate_function_definitions(env, code)
4316 def annotate(self, code):
4317 self.condition.annotate(code)
4318 self.body.annotate(code)
4319 if self.else_clause:
4320 self.else_clause.annotate(code)
4323 def ForStatNode(pos, **kw):
4324 if 'iterator' in kw:
4325 return ForInStatNode(pos, **kw)
4327 return ForFromStatNode(pos, **kw)
4329 class ForInStatNode(LoopNode, StatNode):
4333 # iterator IteratorNode
4335 # else_clause StatNode
4336 # item NextNode used internally
4338 child_attrs = ["target", "iterator", "body", "else_clause"]
4341 def analyse_declarations(self, env):
4342 self.target.analyse_target_declaration(env)
4343 self.body.analyse_declarations(env)
4344 if self.else_clause:
4345 self.else_clause.analyse_declarations(env)
4347 def analyse_expressions(self, env):
4349 self.target.analyse_target_types(env)
4350 self.iterator.analyse_expressions(env)
4351 self.item = ExprNodes.NextNode(self.iterator, env)
4352 self.item = self.item.coerce_to(self.target.type, env)
4353 self.body.analyse_expressions(env)
4354 if self.else_clause:
4355 self.else_clause.analyse_expressions(env)
4357 def generate_execution_code(self, code):
4358 old_loop_labels = code.new_loop_labels()
4359 self.iterator.allocate_counter_temp(code)
4360 self.iterator.generate_evaluation_code(code)
4363 self.item.generate_evaluation_code(code)
4364 self.target.generate_assignment_code(self.item, code)
4365 self.body.generate_execution_code(code)
4366 code.put_label(code.continue_label)
4369 break_label = code.break_label
4370 code.set_loop_labels(old_loop_labels)
4372 if self.else_clause:
4373 # in nested loops, the 'else' block can contain a
4374 # 'continue' statement for the outer loop, but we may need
4375 # to generate cleanup code before taking that path, so we
4377 orig_continue_label = code.continue_label
4378 code.continue_label = code.new_label('outer_continue')
4380 code.putln("/*else*/ {")
4381 self.else_clause.generate_execution_code(code)
4384 if code.label_used(code.continue_label):
4385 code.put_goto(break_label)
4386 code.put_label(code.continue_label)
4387 self.iterator.generate_disposal_code(code)
4388 code.put_goto(orig_continue_label)
4389 code.set_loop_labels(old_loop_labels)
4391 if code.label_used(break_label):
4392 code.put_label(break_label)
4393 self.iterator.release_counter_temp(code)
4394 self.iterator.generate_disposal_code(code)
4395 self.iterator.free_temps(code)
4397 def generate_function_definitions(self, env, code):
4398 self.target.generate_function_definitions(env, code)
4399 self.iterator.generate_function_definitions(env, code)
4400 self.body.generate_function_definitions(env, code)
4401 if self.else_clause is not None:
4402 self.else_clause.generate_function_definitions(env, code)
4404 def annotate(self, code):
4405 self.target.annotate(code)
4406 self.iterator.annotate(code)
4407 self.body.annotate(code)
4408 if self.else_clause:
4409 self.else_clause.annotate(code)
4410 self.item.annotate(code)
4413 class ForFromStatNode(LoopNode, StatNode):
4414 # for name from expr rel name rel expr
4421 # step ExprNode or None
4423 # else_clause StatNode or None
4429 # loopvar_node ExprNode (usually a NameNode or temp node)
4430 # py_loopvar_node PyTempNode or None
4431 child_attrs = ["target", "bound1", "bound2", "step", "body", "else_clause"]
4433 is_py_target = False
4435 py_loopvar_node = None
4438 gil_message = "For-loop using object bounds or target"
4440 def nogil_check(self, env):
4441 for x in (self.target, self.bound1, self.bound2):
4442 if x.type.is_pyobject:
4445 def analyse_declarations(self, env):
4446 self.target.analyse_target_declaration(env)
4447 self.body.analyse_declarations(env)
4448 if self.else_clause:
4449 self.else_clause.analyse_declarations(env)
4451 def analyse_expressions(self, env):
4453 self.target.analyse_target_types(env)
4454 self.bound1.analyse_types(env)
4455 self.bound2.analyse_types(env)
4456 if self.step is not None:
4457 if isinstance(self.step, ExprNodes.UnaryMinusNode):
4458 warning(self.step.pos, "Probable infinite loop in for-from-by statment. Consider switching the directions of the relations.", 2)
4459 self.step.analyse_types(env)
4461 target_type = self.target.type
4462 if self.target.type.is_numeric:
4463 loop_type = self.target.type
4465 loop_type = PyrexTypes.c_int_type
4466 if not self.bound1.type.is_pyobject:
4467 loop_type = PyrexTypes.widest_numeric_type(loop_type, self.bound1.type)
4468 if not self.bound2.type.is_pyobject:
4469 loop_type = PyrexTypes.widest_numeric_type(loop_type, self.bound2.type)
4470 if self.step is not None and not self.step.type.is_pyobject:
4471 loop_type = PyrexTypes.widest_numeric_type(loop_type, self.step.type)
4472 self.bound1 = self.bound1.coerce_to(loop_type, env)
4473 self.bound2 = self.bound2.coerce_to(loop_type, env)
4474 if not self.bound2.is_literal:
4475 self.bound2 = self.bound2.coerce_to_temp(env)
4476 if self.step is not None:
4477 self.step = self.step.coerce_to(loop_type, env)
4478 if not self.step.is_literal:
4479 self.step = self.step.coerce_to_temp(env)
4481 target_type = self.target.type
4482 if not (target_type.is_pyobject or target_type.is_numeric):
4483 error(self.target.pos,
4484 "for-from loop variable must be c numeric type or Python object")
4485 if target_type.is_numeric:
4486 self.is_py_target = False
4487 if isinstance(self.target, ExprNodes.IndexNode) and self.target.is_buffer_access:
4488 raise error(self.pos, "Buffer indexing not allowed as for loop target.")
4489 self.loopvar_node = self.target
4490 self.py_loopvar_node = None
4492 self.is_py_target = True
4493 c_loopvar_node = ExprNodes.TempNode(self.pos, loop_type, env)
4494 self.loopvar_node = c_loopvar_node
4495 self.py_loopvar_node = \
4496 ExprNodes.CloneNode(c_loopvar_node).coerce_to_pyobject(env)
4497 self.body.analyse_expressions(env)
4498 if self.else_clause:
4499 self.else_clause.analyse_expressions(env)
4501 def generate_execution_code(self, code):
4502 old_loop_labels = code.new_loop_labels()
4503 from_range = self.from_range
4504 self.bound1.generate_evaluation_code(code)
4505 self.bound2.generate_evaluation_code(code)
4506 offset, incop = self.relation_table[self.relation1]
4507 if self.step is not None:
4508 self.step.generate_evaluation_code(code)
4509 step = self.step.result()
4510 incop = "%s=%s" % (incop[0], step)
4512 if isinstance(self.loopvar_node, ExprNodes.TempNode):
4513 self.loopvar_node.allocate(code)
4514 if isinstance(self.py_loopvar_node, ExprNodes.TempNode):
4515 self.py_loopvar_node.allocate(code)
4517 loopvar_name = code.funcstate.allocate_temp(self.target.type, False)
4519 loopvar_name = self.loopvar_node.result()
4521 "for (%s = %s%s; %s %s %s; %s%s) {" % (
4523 self.bound1.result(), offset,
4524 loopvar_name, self.relation2, self.bound2.result(),
4525 loopvar_name, incop))
4526 if self.py_loopvar_node:
4527 self.py_loopvar_node.generate_evaluation_code(code)
4528 self.target.generate_assignment_code(self.py_loopvar_node, code)
4530 code.putln("%s = %s;" % (
4531 self.target.result(), loopvar_name))
4532 self.body.generate_execution_code(code)
4533 code.put_label(code.continue_label)
4534 if self.py_loopvar_node:
4535 # This mess is to make for..from loops with python targets behave
4536 # exactly like those with C targets with regards to re-assignment
4537 # of the loop variable.
4539 if self.target.entry.is_pyglobal:
4540 # We know target is a NameNode, this is the only ugly case.
4541 target_node = ExprNodes.PyTempNode(self.target.pos, None)
4542 target_node.allocate(code)
4543 interned_cname = code.intern_identifier(self.target.entry.name)
4544 code.globalstate.use_utility_code(ExprNodes.get_name_interned_utility_code)
4545 code.putln("%s = __Pyx_GetName(%s, %s); %s" % (
4546 target_node.result(),
4547 Naming.module_cname,
4549 code.error_goto_if_null(target_node.result(), self.target.pos)))
4550 code.put_gotref(target_node.result())
4552 target_node = self.target
4553 from_py_node = ExprNodes.CoerceFromPyTypeNode(self.loopvar_node.type, target_node, None)
4554 from_py_node.temp_code = loopvar_name
4555 from_py_node.generate_result_code(code)
4556 if self.target.entry.is_pyglobal:
4557 code.put_decref(target_node.result(), target_node.type)
4558 target_node.release(code)
4560 if self.py_loopvar_node:
4561 # This is potentially wasteful, but we don't want the semantics to
4562 # depend on whether or not the loop is a python type.
4563 self.py_loopvar_node.generate_evaluation_code(code)
4564 self.target.generate_assignment_code(self.py_loopvar_node, code)
4566 code.funcstate.release_temp(loopvar_name)
4567 break_label = code.break_label
4568 code.set_loop_labels(old_loop_labels)
4569 if self.else_clause:
4570 code.putln("/*else*/ {")
4571 self.else_clause.generate_execution_code(code)
4573 code.put_label(break_label)
4574 self.bound1.generate_disposal_code(code)
4575 self.bound1.free_temps(code)
4576 self.bound2.generate_disposal_code(code)
4577 self.bound2.free_temps(code)
4578 if isinstance(self.loopvar_node, ExprNodes.TempNode):
4579 self.loopvar_node.release(code)
4580 if isinstance(self.py_loopvar_node, ExprNodes.TempNode):
4581 self.py_loopvar_node.release(code)
4582 if self.step is not None:
4583 self.step.generate_disposal_code(code)
4584 self.step.free_temps(code)
4587 # {relop : (initial offset, increment op)}
4594 def generate_function_definitions(self, env, code):
4595 self.target.generate_function_definitions(env, code)
4596 self.bound1.generate_function_definitions(env, code)
4597 self.bound2.generate_function_definitions(env, code)
4598 if self.step is not None:
4599 self.step.generate_function_definitions(env, code)
4600 self.body.generate_function_definitions(env, code)
4601 if self.else_clause is not None:
4602 self.else_clause.generate_function_definitions(env, code)
4604 def annotate(self, code):
4605 self.target.annotate(code)
4606 self.bound1.annotate(code)
4607 self.bound2.annotate(code)
4609 self.step.annotate(code)
4610 self.body.annotate(code)
4611 if self.else_clause:
4612 self.else_clause.annotate(code)
4615 class WithStatNode(StatNode):
4617 Represents a Python with statement.
4619 This is only used at parse tree level; and is not present in
4620 analysis or generation phases.
4622 # manager The with statement manager object
4623 # target Node (lhs expression)
4625 child_attrs = ["manager", "target", "body"]
4627 class TryExceptStatNode(StatNode):
4628 # try .. except statement
4631 # except_clauses [ExceptClauseNode]
4632 # else_clause StatNode or None
4634 child_attrs = ["body", "except_clauses", "else_clause"]
4636 def analyse_control_flow(self, env):
4637 env.start_branching(self.pos)
4638 self.body.analyse_control_flow(env)
4639 successful_try = env.control_flow # grab this for later
4640 env.next_branch(self.body.end_pos())
4641 env.finish_branching(self.body.end_pos())
4643 env.start_branching(self.except_clauses[0].pos)
4644 for except_clause in self.except_clauses:
4645 except_clause.analyse_control_flow(env)
4646 env.next_branch(except_clause.end_pos())
4648 # the else cause it executed only when the try clause finishes
4649 env.control_flow.incoming = successful_try
4650 if self.else_clause:
4651 self.else_clause.analyse_control_flow(env)
4652 env.finish_branching(self.end_pos())
4654 def analyse_declarations(self, env):
4655 self.body.analyse_declarations(env)
4656 for except_clause in self.except_clauses:
4657 except_clause.analyse_declarations(env)
4658 if self.else_clause:
4659 self.else_clause.analyse_declarations(env)
4660 env.use_utility_code(reset_exception_utility_code)
4662 def analyse_expressions(self, env):
4663 self.body.analyse_expressions(env)
4664 default_clause_seen = 0
4665 for except_clause in self.except_clauses:
4666 except_clause.analyse_expressions(env)
4667 if default_clause_seen:
4668 error(except_clause.pos, "default 'except:' must be last")
4669 if not except_clause.pattern:
4670 default_clause_seen = 1
4671 self.has_default_clause = default_clause_seen
4672 if self.else_clause:
4673 self.else_clause.analyse_expressions(env)
4675 nogil_check = Node.gil_error
4676 gil_message = "Try-except statement"
4678 def generate_execution_code(self, code):
4679 old_return_label = code.return_label
4680 old_break_label = code.break_label
4681 old_continue_label = code.continue_label
4682 old_error_label = code.new_error_label()
4683 our_error_label = code.error_label
4684 except_end_label = code.new_label('exception_handled')
4685 except_error_label = code.new_label('except_error')
4686 except_return_label = code.new_label('except_return')
4687 try_return_label = code.new_label('try_return')
4688 try_break_label = code.new_label('try_break')
4689 try_continue_label = code.new_label('try_continue')
4690 try_end_label = code.new_label('try_end')
4693 code.putln("PyObject %s;" %
4694 ', '.join(['*%s' % var for var in Naming.exc_save_vars]))
4695 code.putln("__Pyx_ExceptionSave(%s);" %
4696 ', '.join(['&%s' % var for var in Naming.exc_save_vars]))
4697 for var in Naming.exc_save_vars:
4698 code.put_xgotref(var)
4701 code.return_label = try_return_label
4702 code.break_label = try_break_label
4703 code.continue_label = try_continue_label
4704 self.body.generate_execution_code(code)
4707 temps_to_clean_up = code.funcstate.all_free_managed_temps()
4708 code.error_label = except_error_label
4709 code.return_label = except_return_label
4710 if self.else_clause:
4713 self.else_clause.generate_execution_code(code)
4716 for var in Naming.exc_save_vars:
4717 code.put_xdecref_clear(var, py_object_type)
4718 code.put_goto(try_end_label)
4719 if code.label_used(try_return_label):
4720 code.put_label(try_return_label)
4721 for var in Naming.exc_save_vars: code.put_xgiveref(var)
4722 code.putln("__Pyx_ExceptionReset(%s);" %
4723 ', '.join(Naming.exc_save_vars))
4724 code.put_goto(old_return_label)
4725 code.put_label(our_error_label)
4726 for temp_name, type in temps_to_clean_up:
4727 code.put_xdecref_clear(temp_name, type)
4728 for except_clause in self.except_clauses:
4729 except_clause.generate_handling_code(code, except_end_label)
4731 error_label_used = code.label_used(except_error_label)
4732 if error_label_used or not self.has_default_clause:
4733 if error_label_used:
4734 code.put_label(except_error_label)
4735 for var in Naming.exc_save_vars: code.put_xgiveref(var)
4736 code.putln("__Pyx_ExceptionReset(%s);" %
4737 ', '.join(Naming.exc_save_vars))
4738 code.put_goto(old_error_label)
4740 for exit_label, old_label in zip(
4741 [try_break_label, try_continue_label, except_return_label],
4742 [old_break_label, old_continue_label, old_return_label]):
4744 if code.label_used(exit_label):
4745 code.put_label(exit_label)
4746 for var in Naming.exc_save_vars: code.put_xgiveref(var)
4747 code.putln("__Pyx_ExceptionReset(%s);" %
4748 ', '.join(Naming.exc_save_vars))
4749 code.put_goto(old_label)
4751 if code.label_used(except_end_label):
4752 code.put_label(except_end_label)
4753 for var in Naming.exc_save_vars: code.put_xgiveref(var)
4754 code.putln("__Pyx_ExceptionReset(%s);" %
4755 ', '.join(Naming.exc_save_vars))
4756 code.put_label(try_end_label)
4759 code.return_label = old_return_label
4760 code.break_label = old_break_label
4761 code.continue_label = old_continue_label
4762 code.error_label = old_error_label
4764 def generate_function_definitions(self, env, code):
4765 self.body.generate_function_definitions(env, code)
4766 for except_clause in self.except_clauses:
4767 except_clause.generate_function_definitions(env, code)
4768 if self.else_clause is not None:
4769 self.else_clause.generate_function_definitions(env, code)
4771 def annotate(self, code):
4772 self.body.annotate(code)
4773 for except_node in self.except_clauses:
4774 except_node.annotate(code)
4775 if self.else_clause:
4776 self.else_clause.annotate(code)
4779 class ExceptClauseNode(Node):
4780 # Part of try ... except statement.
4782 # pattern [ExprNode]
4783 # target ExprNode or None
4785 # excinfo_target NameNode or None optional target for exception info
4786 # match_flag string result of exception match
4787 # exc_value ExcValueNode used internally
4788 # function_name string qualified name of enclosing function
4789 # exc_vars (string * 3) local exception variables
4791 # excinfo_target is never set by the parser, but can be set by a transform
4792 # in order to extract more extensive information about the exception as a
4793 # sys.exc_info()-style tuple into a target variable
4795 child_attrs = ["pattern", "target", "body", "exc_value", "excinfo_target"]
4798 excinfo_target = None
4800 def analyse_declarations(self, env):
4802 self.target.analyse_target_declaration(env)
4803 if self.excinfo_target is not None:
4804 self.excinfo_target.analyse_target_declaration(env)
4805 self.body.analyse_declarations(env)
4807 def analyse_expressions(self, env):
4809 genv = env.global_scope()
4810 self.function_name = env.qualified_name
4812 # normalise/unpack self.pattern into a list
4813 for i, pattern in enumerate(self.pattern):
4814 pattern.analyse_expressions(env)
4815 self.pattern[i] = pattern.coerce_to_pyobject(env)
4818 self.exc_value = ExprNodes.ExcValueNode(self.pos, env)
4819 self.target.analyse_target_expression(env, self.exc_value)
4820 if self.excinfo_target is not None:
4822 self.excinfo_tuple = ExprNodes.TupleNode(pos=self.pos, args=[
4823 ExprNodes.ExcValueNode(pos=self.pos, env=env) for x in range(3)])
4824 self.excinfo_tuple.analyse_expressions(env)
4825 self.excinfo_target.analyse_target_expression(env, self.excinfo_tuple)
4827 self.body.analyse_expressions(env)
4829 def generate_handling_code(self, code, end_label):
4830 code.mark_pos(self.pos)
4833 for pattern in self.pattern:
4834 pattern.generate_evaluation_code(code)
4835 exc_tests.append("PyErr_ExceptionMatches(%s)" % pattern.py_result())
4837 match_flag = code.funcstate.allocate_temp(PyrexTypes.c_int_type, False)
4839 "%s = %s;" % (match_flag, ' || '.join(exc_tests)))
4840 for pattern in self.pattern:
4841 pattern.generate_disposal_code(code)
4842 pattern.free_temps(code)
4846 code.funcstate.release_temp(match_flag)
4848 code.putln("/*except:*/ {")
4850 if not getattr(self.body, 'stats', True) and \
4851 self.excinfo_target is None and self.target is None:
4852 # most simple case: no exception variable, empty body (pass)
4853 # => reset the exception state, done
4854 code.putln("PyErr_Restore(0,0,0);")
4855 code.put_goto(end_label)
4859 exc_vars = [code.funcstate.allocate_temp(py_object_type,
4862 code.putln('__Pyx_AddTraceback("%s");' % self.function_name)
4863 # We always have to fetch the exception value even if
4864 # there is no target, because this also normalises the
4865 # exception and stores it in the thread state.
4866 code.globalstate.use_utility_code(get_exception_utility_code)
4867 exc_args = "&%s, &%s, &%s" % tuple(exc_vars)
4868 code.putln("if (__Pyx_GetException(%s) < 0) %s" % (exc_args,
4869 code.error_goto(self.pos)))
4873 self.exc_value.set_var(exc_vars[1])
4874 self.exc_value.generate_evaluation_code(code)
4875 self.target.generate_assignment_code(self.exc_value, code)
4876 if self.excinfo_target is not None:
4877 for tempvar, node in zip(exc_vars, self.excinfo_tuple.args):
4878 node.set_var(tempvar)
4879 self.excinfo_tuple.generate_evaluation_code(code)
4880 self.excinfo_target.generate_assignment_code(self.excinfo_tuple, code)
4882 old_break_label, old_continue_label = code.break_label, code.continue_label
4883 code.break_label = code.new_label('except_break')
4884 code.continue_label = code.new_label('except_continue')
4886 old_exc_vars = code.funcstate.exc_vars
4887 code.funcstate.exc_vars = exc_vars
4888 self.body.generate_execution_code(code)
4889 code.funcstate.exc_vars = old_exc_vars
4890 for var in exc_vars:
4891 code.putln("__Pyx_DECREF(%s); %s = 0;" % (var, var))
4892 code.put_goto(end_label)
4894 if code.label_used(code.break_label):
4895 code.put_label(code.break_label)
4896 for var in exc_vars:
4897 code.putln("__Pyx_DECREF(%s); %s = 0;" % (var, var))
4898 code.put_goto(old_break_label)
4899 code.break_label = old_break_label
4901 if code.label_used(code.continue_label):
4902 code.put_label(code.continue_label)
4903 for var in exc_vars:
4904 code.putln("__Pyx_DECREF(%s); %s = 0;" % (var, var))
4905 code.put_goto(old_continue_label)
4906 code.continue_label = old_continue_label
4908 for temp in exc_vars:
4909 code.funcstate.release_temp(temp)
4914 def generate_function_definitions(self, env, code):
4915 if self.target is not None:
4916 self.target.generate_function_definitions(env, code)
4917 self.body.generate_function_definitions(env, code)
4919 def annotate(self, code):
4921 for pattern in self.pattern:
4922 pattern.annotate(code)
4924 self.target.annotate(code)
4925 self.body.annotate(code)
4928 class TryFinallyStatNode(StatNode):
4929 # try ... finally statement
4932 # finally_clause StatNode
4934 # The plan is that we funnel all continue, break
4935 # return and error gotos into the beginning of the
4936 # finally block, setting a variable to remember which
4937 # one we're doing. At the end of the finally block, we
4938 # switch on the variable to figure out where to go.
4939 # In addition, if we're doing an error, we save the
4940 # exception on entry to the finally block and restore
4943 child_attrs = ["body", "finally_clause"]
4945 preserve_exception = 1
4947 disallow_continue_in_try_finally = 0
4948 # There doesn't seem to be any point in disallowing
4949 # continue in the try block, since we have no problem
4952 def create_analysed(pos, env, body, finally_clause):
4953 node = TryFinallyStatNode(pos, body=body, finally_clause=finally_clause)
4955 create_analysed = staticmethod(create_analysed)
4957 def analyse_control_flow(self, env):
4958 env.start_branching(self.pos)
4959 self.body.analyse_control_flow(env)
4960 env.next_branch(self.body.end_pos())
4961 env.finish_branching(self.body.end_pos())
4962 self.finally_clause.analyse_control_flow(env)
4964 def analyse_declarations(self, env):
4965 self.body.analyse_declarations(env)
4966 self.finally_clause.analyse_declarations(env)
4968 def analyse_expressions(self, env):
4969 self.body.analyse_expressions(env)
4970 self.finally_clause.analyse_expressions(env)
4972 nogil_check = Node.gil_error
4973 gil_message = "Try-finally statement"
4975 def generate_execution_code(self, code):
4976 old_error_label = code.error_label
4977 old_labels = code.all_new_labels()
4978 new_labels = code.get_all_labels()
4979 new_error_label = code.error_label
4980 catch_label = code.new_label()
4983 if self.disallow_continue_in_try_finally:
4984 was_in_try_finally = code.funcstate.in_try_finally
4985 code.funcstate.in_try_finally = 1
4986 self.body.generate_execution_code(code)
4987 if self.disallow_continue_in_try_finally:
4988 code.funcstate.in_try_finally = was_in_try_finally
4991 temps_to_clean_up = code.funcstate.all_free_managed_temps()
4992 code.mark_pos(self.finally_clause.pos)
4996 error_label_used = 0
4997 for i, new_label in enumerate(new_labels):
4998 if new_label in code.labels_used:
4999 cases_used.append(i)
5000 if new_label == new_error_label:
5001 error_label_used = 1
5002 error_label_case = i
5006 if error_label_used and self.preserve_exception:
5008 "PyObject *%s, *%s, *%s;" % Naming.exc_vars)
5010 "int %s;" % Naming.exc_lineno_name)
5011 exc_var_init_zero = ''.join(["%s = 0; " % var for var in Naming.exc_vars])
5012 exc_var_init_zero += '%s = 0;' % Naming.exc_lineno_name
5013 code.putln(exc_var_init_zero)
5015 exc_var_init_zero = None
5016 code.use_label(catch_label)
5018 "__pyx_why = 0; goto %s;" % catch_label)
5019 for i in cases_used:
5020 new_label = new_labels[i]
5021 #if new_label and new_label != "<try>":
5022 if new_label == new_error_label and self.preserve_exception:
5023 self.put_error_catcher(code,
5024 new_error_label, i+1, catch_label, temps_to_clean_up)
5026 code.put('%s: ' % new_label)
5027 if exc_var_init_zero:
5028 code.putln(exc_var_init_zero)
5029 code.putln("__pyx_why = %s; goto %s;" % (
5032 code.put_label(catch_label)
5033 code.set_all_labels(old_labels)
5034 if error_label_used:
5035 code.new_error_label()
5036 finally_error_label = code.error_label
5037 self.finally_clause.generate_execution_code(code)
5038 if error_label_used:
5039 if finally_error_label in code.labels_used and self.preserve_exception:
5040 over_label = code.new_label()
5041 code.put_goto(over_label);
5042 code.put_label(finally_error_label)
5043 code.putln("if (__pyx_why == %d) {" % (error_label_case + 1))
5044 for var in Naming.exc_vars:
5045 code.putln("Py_XDECREF(%s);" % var)
5047 code.put_goto(old_error_label)
5048 code.put_label(over_label)
5049 code.error_label = old_error_label
5052 "switch (__pyx_why) {")
5053 for i in cases_used:
5054 old_label = old_labels[i]
5055 if old_label == old_error_label and self.preserve_exception:
5056 self.put_error_uncatcher(code, i+1, old_error_label)
5058 code.use_label(old_label)
5060 "case %s: goto %s;" % (
5068 def generate_function_definitions(self, env, code):
5069 self.body.generate_function_definitions(env, code)
5070 self.finally_clause.generate_function_definitions(env, code)
5072 def put_error_catcher(self, code, error_label, i, catch_label, temps_to_clean_up):
5073 code.globalstate.use_utility_code(restore_exception_utility_code)
5080 for temp_name, type in temps_to_clean_up:
5081 code.put_xdecref_clear(temp_name, type)
5083 "__Pyx_ErrFetch(&%s, &%s, &%s);" %
5087 Naming.exc_lineno_name, Naming.lineno_cname))
5088 code.put_goto(catch_label)
5091 def put_error_uncatcher(self, code, i, error_label):
5092 code.globalstate.use_utility_code(restore_exception_utility_code)
5097 "__Pyx_ErrRestore(%s, %s, %s);" %
5101 Naming.lineno_cname, Naming.exc_lineno_name))
5102 for var in Naming.exc_vars:
5106 code.put_goto(error_label)
5110 def annotate(self, code):
5111 self.body.annotate(code)
5112 self.finally_clause.annotate(code)
5115 class GILStatNode(TryFinallyStatNode):
5116 # 'with gil' or 'with nogil' statement
5118 # state string 'gil' or 'nogil'
5122 preserve_exception = 0
5124 def __init__(self, pos, state, body):
5126 TryFinallyStatNode.__init__(self, pos,
5128 finally_clause = GILExitNode(pos, state = state))
5130 def analyse_expressions(self, env):
5131 env.use_utility_code(force_init_threads_utility_code)
5132 was_nogil = env.nogil
5134 TryFinallyStatNode.analyse_expressions(self, env)
5135 env.nogil = was_nogil
5139 def generate_execution_code(self, code):
5140 code.mark_pos(self.pos)
5142 if self.state == 'gil':
5143 code.putln("#ifdef WITH_THREAD")
5144 code.putln("PyGILState_STATE _save = PyGILState_Ensure();")
5145 code.putln("#endif")
5147 code.putln("#ifdef WITH_THREAD")
5148 code.putln("PyThreadState *_save = NULL;")
5149 code.putln("#endif")
5150 code.putln("Py_UNBLOCK_THREADS")
5151 TryFinallyStatNode.generate_execution_code(self, code)
5155 class GILExitNode(StatNode):
5156 # Used as the 'finally' block in a GILStatNode
5158 # state string 'gil' or 'nogil'
5162 def analyse_expressions(self, env):
5165 def generate_execution_code(self, code):
5166 if self.state == 'gil':
5167 code.putln("#ifdef WITH_THREAD")
5168 code.putln("PyGILState_Release(_save);")
5169 code.putln("#endif")
5171 code.putln("Py_BLOCK_THREADS")
5174 class CImportStatNode(StatNode):
5177 # module_name string Qualified name of module being imported
5178 # as_name string or None Name specified in "as" clause, if any
5182 def analyse_declarations(self, env):
5183 if not env.is_module_scope:
5184 error(self.pos, "cimport only allowed at module level")
5186 module_scope = env.find_module(self.module_name, self.pos)
5187 if "." in self.module_name:
5188 names = [EncodedString(name) for name in self.module_name.split(".")]
5190 top_module_scope = env.context.find_submodule(top_name)
5191 module_scope = top_module_scope
5192 for name in names[1:]:
5193 submodule_scope = module_scope.find_submodule(name)
5194 module_scope.declare_module(name, submodule_scope, self.pos)
5195 module_scope = submodule_scope
5197 env.declare_module(self.as_name, module_scope, self.pos)
5199 env.declare_module(top_name, top_module_scope, self.pos)
5201 name = self.as_name or self.module_name
5202 env.declare_module(name, module_scope, self.pos)
5204 def analyse_expressions(self, env):
5207 def generate_execution_code(self, code):
5211 class FromCImportStatNode(StatNode):
5212 # from ... cimport statement
5214 # module_name string Qualified name of module
5215 # imported_names [(pos, name, as_name, kind)] Names to be imported
5219 def analyse_declarations(self, env):
5220 if not env.is_module_scope:
5221 error(self.pos, "cimport only allowed at module level")
5223 module_scope = env.find_module(self.module_name, self.pos)
5224 env.add_imported_module(module_scope)
5225 for pos, name, as_name, kind in self.imported_names:
5227 for local_name, entry in module_scope.entries.items():
5228 env.add_imported_entry(local_name, entry, pos)
5230 entry = module_scope.lookup(name)
5232 if kind and not self.declaration_matches(entry, kind):
5233 entry.redeclared(pos)
5235 if kind == 'struct' or kind == 'union':
5236 entry = module_scope.declare_struct_or_union(name,
5237 kind = kind, scope = None, typedef_flag = 0, pos = pos)
5238 elif kind == 'class':
5239 entry = module_scope.declare_c_class(name, pos = pos,
5240 module_name = self.module_name)
5242 submodule_scope = env.context.find_module(name, relative_to = module_scope, pos = self.pos)
5243 if submodule_scope.parent_module is module_scope:
5244 env.declare_module(as_name or name, submodule_scope, self.pos)
5246 error(pos, "Name '%s' not declared in module '%s'"
5247 % (name, self.module_name))
5250 local_name = as_name or name
5251 env.add_imported_entry(local_name, entry, pos)
5253 def declaration_matches(self, entry, kind):
5254 if not entry.is_type:
5258 if not type.is_extension_type:
5261 if not type.is_struct_or_union:
5263 if kind != type.kind:
5267 def analyse_expressions(self, env):
5270 def generate_execution_code(self, code):
5274 class FromImportStatNode(StatNode):
5275 # from ... import statement
5278 # items [(string, NameNode)]
5279 # interned_items [(string, NameNode, ExprNode)]
5280 # item PyTempNode used internally
5281 # import_star boolean used internally
5283 child_attrs = ["module"]
5286 def analyse_declarations(self, env):
5287 for name, target in self.items:
5289 if not env.is_module_scope:
5290 error(self.pos, "import * only allowed at module level")
5292 env.has_import_star = 1
5293 self.import_star = 1
5295 target.analyse_target_declaration(env)
5297 def analyse_expressions(self, env):
5299 self.module.analyse_expressions(env)
5300 self.item = ExprNodes.RawCNameExprNode(self.pos, py_object_type)
5301 self.interned_items = []
5302 for name, target in self.items:
5304 for _, entry in env.entries.items():
5305 if not entry.is_type and entry.type.is_extension_type:
5306 env.use_utility_code(ExprNodes.type_test_utility_code)
5309 entry = env.lookup(target.name)
5310 # check whether or not entry is already cimported
5311 if (entry.is_type and entry.type.name == name
5312 and hasattr(entry.type, 'module_name')):
5313 if entry.type.module_name == self.module.module_name.value:
5314 # cimported with absolute name
5317 # cimported with relative name
5318 module = env.find_module(self.module.module_name.value,
5320 if entry.type.module_name == module.qualified_name:
5322 except AttributeError:
5324 target.analyse_target_expression(env, None)
5325 if target.type is py_object_type:
5328 coerced_item = self.item.coerce_to(target.type, env)
5329 self.interned_items.append((name, target, coerced_item))
5331 def generate_execution_code(self, code):
5332 self.module.generate_evaluation_code(code)
5333 if self.import_star:
5335 'if (%s(%s) < 0) %s;' % (
5337 self.module.py_result(),
5338 code.error_goto(self.pos)))
5339 item_temp = code.funcstate.allocate_temp(py_object_type, manage_ref=True)
5340 self.item.set_cname(item_temp)
5341 for name, target, coerced_item in self.interned_items:
5342 cname = code.intern_identifier(name)
5344 '%s = PyObject_GetAttr(%s, %s); %s' % (
5346 self.module.py_result(),
5348 code.error_goto_if_null(item_temp, self.pos)))
5349 code.put_gotref(item_temp)
5350 if coerced_item is None:
5351 target.generate_assignment_code(self.item, code)
5353 coerced_item.allocate_temp_result(code)
5354 coerced_item.generate_result_code(code)
5355 target.generate_assignment_code(coerced_item, code)
5356 code.put_decref_clear(item_temp, py_object_type)
5357 code.funcstate.release_temp(item_temp)
5358 self.module.generate_disposal_code(code)
5359 self.module.free_temps(code)
5363 #------------------------------------------------------------------------------------
5365 # Runtime support code
5367 #------------------------------------------------------------------------------------
5369 utility_function_predeclarations = \
5371 /* inline attribute */
5372 #ifndef CYTHON_INLINE
5373 #if defined(__GNUC__)
5374 #define CYTHON_INLINE __inline__
5375 #elif defined(_MSC_VER)
5376 #define CYTHON_INLINE __inline
5377 #elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
5378 #define CYTHON_INLINE inline
5380 #define CYTHON_INLINE
5384 /* unused attribute */
5385 #ifndef CYTHON_UNUSED
5386 # if defined(__GNUC__)
5387 # if !(defined(__cplusplus)) || (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4))
5388 # define CYTHON_UNUSED __attribute__ ((__unused__))
5390 # define CYTHON_UNUSED
5392 # elif defined(__ICC) || defined(__INTEL_COMPILER)
5393 # define CYTHON_UNUSED __attribute__ ((__unused__))
5395 # define CYTHON_UNUSED
5399 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*/
5403 if Options.gcc_branch_hints:
5404 branch_prediction_macros = \
5407 /* Test for GCC > 2.95 */
5408 #if __GNUC__ > 2 || (__GNUC__ == 2 && (__GNUC_MINOR__ > 95))
5409 #define likely(x) __builtin_expect(!!(x), 1)
5410 #define unlikely(x) __builtin_expect(!!(x), 0)
5411 #else /* __GNUC__ > 2 ... */
5412 #define likely(x) (x)
5413 #define unlikely(x) (x)
5414 #endif /* __GNUC__ > 2 ... */
5415 #else /* __GNUC__ */
5416 #define likely(x) (x)
5417 #define unlikely(x) (x)
5418 #endif /* __GNUC__ */
5421 branch_prediction_macros = \
5423 #define likely(x) (x)
5424 #define unlikely(x) (x)
5427 #get_name_predeclaration = \
5428 #"static PyObject *__Pyx_GetName(PyObject *dict, char *name); /*proto*/"
5430 #get_name_interned_predeclaration = \
5431 #"static PyObject *__Pyx_GetName(PyObject *dict, PyObject *name); /*proto*/"
5433 #------------------------------------------------------------------------------------
5435 printing_utility_code = UtilityCode(
5437 static int __Pyx_Print(PyObject*, PyObject *, int); /*proto*/
5438 #if PY_MAJOR_VERSION >= 3
5439 static PyObject* %s = 0;
5440 static PyObject* %s = 0;
5442 """ % (Naming.print_function, Naming.print_function_kwargs),
5444 #if PY_MAJOR_VERSION >= 3
5448 """ % (Naming.print_function, Naming.print_function_kwargs),
5450 #if PY_MAJOR_VERSION < 3
5451 static PyObject *__Pyx_GetStdout(void) {
5452 PyObject *f = PySys_GetObject((char *)"stdout");
5454 PyErr_SetString(PyExc_RuntimeError, "lost sys.stdout");
5459 static int __Pyx_Print(PyObject* f, PyObject *arg_tuple, int newline) {
5464 if (!(f = __Pyx_GetStdout()))
5467 for (i=0; i < PyTuple_GET_SIZE(arg_tuple); i++) {
5468 if (PyFile_SoftSpace(f, 1)) {
5469 if (PyFile_WriteString(" ", f) < 0)
5472 v = PyTuple_GET_ITEM(arg_tuple, i);
5473 if (PyFile_WriteObject(v, f, Py_PRINT_RAW) < 0)
5475 if (PyString_Check(v)) {
5476 char *s = PyString_AsString(v);
5477 Py_ssize_t len = PyString_Size(v);
5479 isspace(Py_CHARMASK(s[len-1])) &&
5481 PyFile_SoftSpace(f, 0);
5485 if (PyFile_WriteString("\n", f) < 0)
5487 PyFile_SoftSpace(f, 0);
5492 #else /* Python 3 has a print function */
5494 static int __Pyx_Print(PyObject* stream, PyObject *arg_tuple, int newline) {
5495 PyObject* kwargs = 0;
5496 PyObject* result = 0;
5497 PyObject* end_string;
5498 if (unlikely(!%(PRINT_FUNCTION)s)) {
5499 %(PRINT_FUNCTION)s = __Pyx_GetAttrString(%(BUILTINS)s, "print");
5500 if (!%(PRINT_FUNCTION)s)
5504 kwargs = PyDict_New();
5505 if (unlikely(!kwargs))
5507 if (unlikely(PyDict_SetItemString(kwargs, "file", stream) < 0))
5510 end_string = PyUnicode_FromStringAndSize(" ", 1);
5511 if (unlikely(!end_string))
5513 if (PyDict_SetItemString(kwargs, "end", end_string) < 0) {
5514 Py_DECREF(end_string);
5517 Py_DECREF(end_string);
5519 } else if (!newline) {
5520 if (unlikely(!%(PRINT_KWARGS)s)) {
5521 %(PRINT_KWARGS)s = PyDict_New();
5522 if (unlikely(!%(PRINT_KWARGS)s))
5524 end_string = PyUnicode_FromStringAndSize(" ", 1);
5525 if (unlikely(!end_string))
5527 if (PyDict_SetItemString(%(PRINT_KWARGS)s, "end", end_string) < 0) {
5528 Py_DECREF(end_string);
5531 Py_DECREF(end_string);
5533 kwargs = %(PRINT_KWARGS)s;
5535 result = PyObject_Call(%(PRINT_FUNCTION)s, arg_tuple, kwargs);
5536 if (unlikely(kwargs) && (kwargs != %(PRINT_KWARGS)s))
5543 if (kwargs != %(PRINT_KWARGS)s)
5549 """ % {'BUILTINS' : Naming.builtins_cname,
5550 'PRINT_FUNCTION' : Naming.print_function,
5551 'PRINT_KWARGS' : Naming.print_function_kwargs}
5555 printing_one_utility_code = UtilityCode(
5557 static int __Pyx_PrintOne(PyObject* stream, PyObject *o); /*proto*/
5560 #if PY_MAJOR_VERSION < 3
5562 static int __Pyx_PrintOne(PyObject* f, PyObject *o) {
5564 if (!(f = __Pyx_GetStdout()))
5567 if (PyFile_SoftSpace(f, 0)) {
5568 if (PyFile_WriteString(" ", f) < 0)
5571 if (PyFile_WriteObject(o, f, Py_PRINT_RAW) < 0)
5573 if (PyFile_WriteString("\n", f) < 0)
5576 /* the line below is just to avoid compiler
5577 * compiler warnings about unused functions */
5578 return __Pyx_Print(f, NULL, 0);
5581 #else /* Python 3 has a print function */
5583 static int __Pyx_PrintOne(PyObject* stream, PyObject *o) {
5585 PyObject* arg_tuple = PyTuple_New(1);
5586 if (unlikely(!arg_tuple))
5589 PyTuple_SET_ITEM(arg_tuple, 0, o);
5590 res = __Pyx_Print(stream, arg_tuple, 1);
5591 Py_DECREF(arg_tuple);
5597 requires=[printing_utility_code])
5601 #------------------------------------------------------------------------------------
5603 # Exception raising code
5605 # Exceptions are raised by __Pyx_Raise() and stored as plain
5606 # type/value/tb in PyThreadState->curexc_*. When being caught by an
5607 # 'except' statement, curexc_* is moved over to exc_* by
5608 # __Pyx_GetException()
5610 restore_exception_utility_code = UtilityCode(
5612 static CYTHON_INLINE void __Pyx_ErrRestore(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
5613 static CYTHON_INLINE void __Pyx_ErrFetch(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
5616 static CYTHON_INLINE void __Pyx_ErrRestore(PyObject *type, PyObject *value, PyObject *tb) {
5617 PyObject *tmp_type, *tmp_value, *tmp_tb;
5618 PyThreadState *tstate = PyThreadState_GET();
5620 tmp_type = tstate->curexc_type;
5621 tmp_value = tstate->curexc_value;
5622 tmp_tb = tstate->curexc_traceback;
5623 tstate->curexc_type = type;
5624 tstate->curexc_value = value;
5625 tstate->curexc_traceback = tb;
5626 Py_XDECREF(tmp_type);
5627 Py_XDECREF(tmp_value);
5631 static CYTHON_INLINE void __Pyx_ErrFetch(PyObject **type, PyObject **value, PyObject **tb) {
5632 PyThreadState *tstate = PyThreadState_GET();
5633 *type = tstate->curexc_type;
5634 *value = tstate->curexc_value;
5635 *tb = tstate->curexc_traceback;
5637 tstate->curexc_type = 0;
5638 tstate->curexc_value = 0;
5639 tstate->curexc_traceback = 0;
5644 # The following function is based on do_raise() from ceval.c. There
5645 # are separate versions for Python2 and Python3 as exception handling
5646 # has changed quite a lot between the two versions.
5648 raise_utility_code = UtilityCode(
5650 static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
5653 #if PY_MAJOR_VERSION < 3
5654 static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb) {
5658 /* First, check the traceback argument, replacing None with NULL. */
5659 if (tb == Py_None) {
5663 else if (tb != NULL && !PyTraceBack_Check(tb)) {
5664 PyErr_SetString(PyExc_TypeError,
5665 "raise: arg 3 must be a traceback or None");
5668 /* Next, replace a missing value with None */
5669 if (value == NULL) {
5673 #if PY_VERSION_HEX < 0x02050000
5674 if (!PyClass_Check(type))
5676 if (!PyType_Check(type))
5679 /* Raising an instance. The value should be a dummy. */
5680 if (value != Py_None) {
5681 PyErr_SetString(PyExc_TypeError,
5682 "instance exception may not have a separate value");
5685 /* Normalize to raise <class>, <instance> */
5688 #if PY_VERSION_HEX < 0x02050000
5689 if (PyInstance_Check(type)) {
5690 type = (PyObject*) ((PyInstanceObject*)type)->in_class;
5695 PyErr_SetString(PyExc_TypeError,
5696 "raise: exception must be an old-style class or instance");
5700 type = (PyObject*) Py_TYPE(type);
5702 if (!PyType_IsSubtype((PyTypeObject *)type, (PyTypeObject *)PyExc_BaseException)) {
5703 PyErr_SetString(PyExc_TypeError,
5704 "raise: exception class must be a subclass of BaseException");
5710 __Pyx_ErrRestore(type, value, tb);
5719 #else /* Python 3+ */
5721 static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb) {
5722 if (tb == Py_None) {
5724 } else if (tb && !PyTraceBack_Check(tb)) {
5725 PyErr_SetString(PyExc_TypeError,
5726 "raise: arg 3 must be a traceback or None");
5729 if (value == Py_None)
5732 if (PyExceptionInstance_Check(type)) {
5734 PyErr_SetString(PyExc_TypeError,
5735 "instance exception may not have a separate value");
5739 type = (PyObject*) Py_TYPE(value);
5740 } else if (!PyExceptionClass_Check(type)) {
5741 PyErr_SetString(PyExc_TypeError,
5742 "raise: exception class must be a subclass of BaseException");
5746 PyErr_SetObject(type, value);
5749 PyThreadState *tstate = PyThreadState_GET();
5750 PyObject* tmp_tb = tstate->curexc_traceback;
5753 tstate->curexc_traceback = tb;
5763 requires=[restore_exception_utility_code])
5765 #------------------------------------------------------------------------------------
5767 get_exception_utility_code = UtilityCode(
5769 static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
5772 static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb) {
5773 PyObject *local_type, *local_value, *local_tb;
5774 PyObject *tmp_type, *tmp_value, *tmp_tb;
5775 PyThreadState *tstate = PyThreadState_GET();
5776 local_type = tstate->curexc_type;
5777 local_value = tstate->curexc_value;
5778 local_tb = tstate->curexc_traceback;
5779 tstate->curexc_type = 0;
5780 tstate->curexc_value = 0;
5781 tstate->curexc_traceback = 0;
5782 PyErr_NormalizeException(&local_type, &local_value, &local_tb);
5783 if (unlikely(tstate->curexc_type))
5785 #if PY_MAJOR_VERSION >= 3
5786 if (unlikely(PyException_SetTraceback(local_value, local_tb) < 0))
5790 *value = local_value;
5792 Py_INCREF(local_type);
5793 Py_INCREF(local_value);
5794 Py_INCREF(local_tb);
5795 tmp_type = tstate->exc_type;
5796 tmp_value = tstate->exc_value;
5797 tmp_tb = tstate->exc_traceback;
5798 tstate->exc_type = local_type;
5799 tstate->exc_value = local_value;
5800 tstate->exc_traceback = local_tb;
5801 /* Make sure tstate is in a consistent state when we XDECREF
5802 these objects (XDECREF may run arbitrary code). */
5803 Py_XDECREF(tmp_type);
5804 Py_XDECREF(tmp_value);
5811 Py_XDECREF(local_type);
5812 Py_XDECREF(local_value);
5813 Py_XDECREF(local_tb);
5819 #------------------------------------------------------------------------------------
5821 get_exception_tuple_utility_code = UtilityCode(proto="""
5822 static PyObject *__Pyx_GetExceptionTuple(void); /*proto*/
5824 # I doubt that calling __Pyx_GetException() here is correct as it moves
5825 # the exception from tstate->curexc_* to tstate->exc_*, which prevents
5826 # exception handlers later on from receiving it.
5828 static PyObject *__Pyx_GetExceptionTuple(void) {
5829 PyObject *type = NULL, *value = NULL, *tb = NULL;
5830 if (__Pyx_GetException(&type, &value, &tb) == 0) {
5831 PyObject* exc_info = PyTuple_New(3);
5836 PyTuple_SET_ITEM(exc_info, 0, type);
5837 PyTuple_SET_ITEM(exc_info, 1, value);
5838 PyTuple_SET_ITEM(exc_info, 2, tb);
5845 requires=[get_exception_utility_code])
5847 #------------------------------------------------------------------------------------
5849 reset_exception_utility_code = UtilityCode(
5851 static CYTHON_INLINE void __Pyx_ExceptionSave(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
5852 static void __Pyx_ExceptionReset(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
5855 static CYTHON_INLINE void __Pyx_ExceptionSave(PyObject **type, PyObject **value, PyObject **tb) {
5856 PyThreadState *tstate = PyThreadState_GET();
5857 *type = tstate->exc_type;
5858 *value = tstate->exc_value;
5859 *tb = tstate->exc_traceback;
5865 static void __Pyx_ExceptionReset(PyObject *type, PyObject *value, PyObject *tb) {
5866 PyObject *tmp_type, *tmp_value, *tmp_tb;
5867 PyThreadState *tstate = PyThreadState_GET();
5868 tmp_type = tstate->exc_type;
5869 tmp_value = tstate->exc_value;
5870 tmp_tb = tstate->exc_traceback;
5871 tstate->exc_type = type;
5872 tstate->exc_value = value;
5873 tstate->exc_traceback = tb;
5874 Py_XDECREF(tmp_type);
5875 Py_XDECREF(tmp_value);
5880 #------------------------------------------------------------------------------------
5882 arg_type_test_utility_code = UtilityCode(
5884 static int __Pyx_ArgTypeTest(PyObject *obj, PyTypeObject *type, int none_allowed,
5885 const char *name, int exact); /*proto*/
5888 static int __Pyx_ArgTypeTest(PyObject *obj, PyTypeObject *type, int none_allowed,
5889 const char *name, int exact)
5892 PyErr_Format(PyExc_SystemError, "Missing type object");
5895 if (none_allowed && obj == Py_None) return 1;
5897 if (Py_TYPE(obj) == type) return 1;
5900 if (PyObject_TypeCheck(obj, type)) return 1;
5902 PyErr_Format(PyExc_TypeError,
5903 "Argument '%s' has incorrect type (expected %s, got %s)",
5904 name, type->tp_name, Py_TYPE(obj)->tp_name);
5909 #------------------------------------------------------------------------------------
5911 # __Pyx_RaiseArgtupleInvalid raises the correct exception when too
5912 # many or too few positional arguments were found. This handles
5913 # Py_ssize_t formatting correctly.
5915 raise_argtuple_invalid_utility_code = UtilityCode(
5917 static void __Pyx_RaiseArgtupleInvalid(const char* func_name, int exact,
5918 Py_ssize_t num_min, Py_ssize_t num_max, Py_ssize_t num_found); /*proto*/
5921 static void __Pyx_RaiseArgtupleInvalid(
5922 const char* func_name,
5926 Py_ssize_t num_found)
5928 Py_ssize_t num_expected;
5929 const char *number, *more_or_less;
5931 if (num_found < num_min) {
5932 num_expected = num_min;
5933 more_or_less = "at least";
5935 num_expected = num_max;
5936 more_or_less = "at most";
5939 more_or_less = "exactly";
5941 number = (num_expected == 1) ? "" : "s";
5942 PyErr_Format(PyExc_TypeError,
5943 #if PY_VERSION_HEX < 0x02050000
5944 "%s() takes %s %d positional argument%s (%d given)",
5946 "%s() takes %s %zd positional argument%s (%zd given)",
5948 func_name, more_or_less, num_expected, number, num_found);
5952 raise_keyword_required_utility_code = UtilityCode(
5954 static CYTHON_INLINE void __Pyx_RaiseKeywordRequired(const char* func_name, PyObject* kw_name); /*proto*/
5957 static CYTHON_INLINE void __Pyx_RaiseKeywordRequired(
5958 const char* func_name,
5961 PyErr_Format(PyExc_TypeError,
5962 #if PY_MAJOR_VERSION >= 3
5963 "%s() needs keyword-only argument %U", func_name, kw_name);
5965 "%s() needs keyword-only argument %s", func_name,
5966 PyString_AS_STRING(kw_name));
5971 raise_double_keywords_utility_code = UtilityCode(
5973 static void __Pyx_RaiseDoubleKeywordsError(
5974 const char* func_name, PyObject* kw_name); /*proto*/
5977 static void __Pyx_RaiseDoubleKeywordsError(
5978 const char* func_name,
5981 PyErr_Format(PyExc_TypeError,
5982 #if PY_MAJOR_VERSION >= 3
5983 "%s() got multiple values for keyword argument '%U'", func_name, kw_name);
5985 "%s() got multiple values for keyword argument '%s'", func_name,
5986 PyString_AS_STRING(kw_name));
5991 #------------------------------------------------------------------------------------
5993 # __Pyx_CheckKeywordStrings raises an error if non-string keywords
5994 # were passed to a function, or if any keywords were passed to a
5995 # function that does not accept them.
5997 keyword_string_check_utility_code = UtilityCode(
5999 static CYTHON_INLINE int __Pyx_CheckKeywordStrings(PyObject *kwdict,
6000 const char* function_name, int kw_allowed); /*proto*/
6003 static CYTHON_INLINE int __Pyx_CheckKeywordStrings(
6005 const char* function_name,
6010 while (PyDict_Next(kwdict, &pos, &key, 0)) {
6011 #if PY_MAJOR_VERSION < 3
6012 if (unlikely(!PyString_CheckExact(key)) && unlikely(!PyString_Check(key)))
6014 if (unlikely(!PyUnicode_CheckExact(key)) && unlikely(!PyUnicode_Check(key)))
6016 goto invalid_keyword_type;
6018 if ((!kw_allowed) && unlikely(key))
6019 goto invalid_keyword;
6021 invalid_keyword_type:
6022 PyErr_Format(PyExc_TypeError,
6023 "%s() keywords must be strings", function_name);
6026 PyErr_Format(PyExc_TypeError,
6027 #if PY_MAJOR_VERSION < 3
6028 "%s() got an unexpected keyword argument '%s'",
6029 function_name, PyString_AsString(key));
6031 "%s() got an unexpected keyword argument '%U'",
6032 function_name, key);
6038 #------------------------------------------------------------------------------------
6040 # __Pyx_ParseOptionalKeywords copies the optional/unknown keyword
6041 # arguments from the kwds dict into kwds2. If kwds2 is NULL, unknown
6042 # keywords will raise an invalid keyword error.
6044 # Three kinds of errors are checked: 1) non-string keywords, 2)
6045 # unexpected keywords and 3) overlap with positional arguments.
6047 # If num_posargs is greater 0, it denotes the number of positional
6048 # arguments that were passed and that must therefore not appear
6049 # amongst the keywords as well.
6051 # This method does not check for required keyword arguments.
6054 parse_keywords_utility_code = UtilityCode(
6056 static int __Pyx_ParseOptionalKeywords(PyObject *kwds, PyObject **argnames[], \
6057 PyObject *kwds2, PyObject *values[], Py_ssize_t num_pos_args, \
6058 const char* function_name); /*proto*/
6061 static int __Pyx_ParseOptionalKeywords(
6063 PyObject **argnames[],
6066 Py_ssize_t num_pos_args,
6067 const char* function_name)
6069 PyObject *key = 0, *value = 0;
6072 PyObject*** first_kw_arg = argnames + num_pos_args;
6074 while (PyDict_Next(kwds, &pos, &key, &value)) {
6075 name = first_kw_arg;
6076 while (*name && (**name != key)) name++;
6078 values[name-argnames] = value;
6080 #if PY_MAJOR_VERSION < 3
6081 if (unlikely(!PyString_CheckExact(key)) && unlikely(!PyString_Check(key))) {
6083 if (unlikely(!PyUnicode_CheckExact(key)) && unlikely(!PyUnicode_Check(key))) {
6085 goto invalid_keyword_type;
6087 for (name = first_kw_arg; *name; name++) {
6088 #if PY_MAJOR_VERSION >= 3
6089 if (PyUnicode_GET_SIZE(**name) == PyUnicode_GET_SIZE(key) &&
6090 PyUnicode_Compare(**name, key) == 0) break;
6092 if (PyString_GET_SIZE(**name) == PyString_GET_SIZE(key) &&
6093 _PyString_Eq(**name, key)) break;
6097 values[name-argnames] = value;
6099 /* unexpected keyword found */
6100 for (name=argnames; name != first_kw_arg; name++) {
6101 if (**name == key) goto arg_passed_twice;
6102 #if PY_MAJOR_VERSION >= 3
6103 if (PyUnicode_GET_SIZE(**name) == PyUnicode_GET_SIZE(key) &&
6104 PyUnicode_Compare(**name, key) == 0) goto arg_passed_twice;
6106 if (PyString_GET_SIZE(**name) == PyString_GET_SIZE(key) &&
6107 _PyString_Eq(**name, key)) goto arg_passed_twice;
6111 if (unlikely(PyDict_SetItem(kwds2, key, value))) goto bad;
6113 goto invalid_keyword;
6121 __Pyx_RaiseDoubleKeywordsError(function_name, **name);
6123 invalid_keyword_type:
6124 PyErr_Format(PyExc_TypeError,
6125 "%s() keywords must be strings", function_name);
6128 PyErr_Format(PyExc_TypeError,
6129 #if PY_MAJOR_VERSION < 3
6130 "%s() got an unexpected keyword argument '%s'",
6131 function_name, PyString_AsString(key));
6133 "%s() got an unexpected keyword argument '%U'",
6134 function_name, key);
6140 requires=[raise_double_keywords_utility_code])
6142 #------------------------------------------------------------------------------------
6144 traceback_utility_code = UtilityCode(
6146 static void __Pyx_AddTraceback(const char *funcname); /*proto*/
6149 #include "compile.h"
6150 #include "frameobject.h"
6151 #include "traceback.h"
6153 static void __Pyx_AddTraceback(const char *funcname) {
6154 PyObject *py_srcfile = 0;
6155 PyObject *py_funcname = 0;
6156 PyObject *py_globals = 0;
6157 PyCodeObject *py_code = 0;
6158 PyFrameObject *py_frame = 0;
6160 #if PY_MAJOR_VERSION < 3
6161 py_srcfile = PyString_FromString(%(FILENAME)s);
6163 py_srcfile = PyUnicode_FromString(%(FILENAME)s);
6165 if (!py_srcfile) goto bad;
6167 #if PY_MAJOR_VERSION < 3
6168 py_funcname = PyString_FromFormat( "%%s (%%s:%%d)", funcname, %(CFILENAME)s, %(CLINENO)s);
6170 py_funcname = PyUnicode_FromFormat( "%%s (%%s:%%d)", funcname, %(CFILENAME)s, %(CLINENO)s);
6174 #if PY_MAJOR_VERSION < 3
6175 py_funcname = PyString_FromString(funcname);
6177 py_funcname = PyUnicode_FromString(funcname);
6180 if (!py_funcname) goto bad;
6181 py_globals = PyModule_GetDict(%(GLOBALS)s);
6182 if (!py_globals) goto bad;
6183 py_code = PyCode_New(
6184 0, /*int argcount,*/
6185 #if PY_MAJOR_VERSION >= 3
6186 0, /*int kwonlyargcount,*/
6189 0, /*int stacksize,*/
6191 %(EMPTY_BYTES)s, /*PyObject *code,*/
6192 %(EMPTY_TUPLE)s, /*PyObject *consts,*/
6193 %(EMPTY_TUPLE)s, /*PyObject *names,*/
6194 %(EMPTY_TUPLE)s, /*PyObject *varnames,*/
6195 %(EMPTY_TUPLE)s, /*PyObject *freevars,*/
6196 %(EMPTY_TUPLE)s, /*PyObject *cellvars,*/
6197 py_srcfile, /*PyObject *filename,*/
6198 py_funcname, /*PyObject *name,*/
6199 %(LINENO)s, /*int firstlineno,*/
6200 %(EMPTY_BYTES)s /*PyObject *lnotab*/
6202 if (!py_code) goto bad;
6203 py_frame = PyFrame_New(
6204 PyThreadState_GET(), /*PyThreadState *tstate,*/
6205 py_code, /*PyCodeObject *code,*/
6206 py_globals, /*PyObject *globals,*/
6207 0 /*PyObject *locals*/
6209 if (!py_frame) goto bad;
6210 py_frame->f_lineno = %(LINENO)s;
6211 PyTraceBack_Here(py_frame);
6213 Py_XDECREF(py_srcfile);
6214 Py_XDECREF(py_funcname);
6215 Py_XDECREF(py_code);
6216 Py_XDECREF(py_frame);
6219 'FILENAME': Naming.filename_cname,
6220 'LINENO': Naming.lineno_cname,
6221 'CFILENAME': Naming.cfilenm_cname,
6222 'CLINENO': Naming.clineno_cname,
6223 'GLOBALS': Naming.module_cname,
6224 'EMPTY_TUPLE' : Naming.empty_tuple,
6225 'EMPTY_BYTES' : Naming.empty_bytes,
6228 #------------------------------------------------------------------------------------
6230 unraisable_exception_utility_code = UtilityCode(
6232 static void __Pyx_WriteUnraisable(const char *name); /*proto*/
6235 static void __Pyx_WriteUnraisable(const char *name) {
6236 PyObject *old_exc, *old_val, *old_tb;
6238 __Pyx_ErrFetch(&old_exc, &old_val, &old_tb);
6239 #if PY_MAJOR_VERSION < 3
6240 ctx = PyString_FromString(name);
6242 ctx = PyUnicode_FromString(name);
6244 __Pyx_ErrRestore(old_exc, old_val, old_tb);
6246 PyErr_WriteUnraisable(Py_None);
6248 PyErr_WriteUnraisable(ctx);
6253 requires=[restore_exception_utility_code])
6255 #------------------------------------------------------------------------------------
6257 set_vtable_utility_code = UtilityCode(
6259 static int __Pyx_SetVtable(PyObject *dict, void *vtable); /*proto*/
6262 static int __Pyx_SetVtable(PyObject *dict, void *vtable) {
6263 #if PY_VERSION_HEX >= 0x02070000 && !(PY_MAJOR_VERSION==3&&PY_MINOR_VERSION==0)
6264 PyObject *ob = PyCapsule_New(vtable, 0, 0);
6266 PyObject *ob = PyCObject_FromVoidPtr(vtable, 0);
6270 if (PyDict_SetItemString(dict, "__pyx_vtable__", ob) < 0)
6280 #------------------------------------------------------------------------------------
6282 get_vtable_utility_code = UtilityCode(
6284 static void* __Pyx_GetVtable(PyObject *dict); /*proto*/
6287 static void* __Pyx_GetVtable(PyObject *dict) {
6289 PyObject *ob = PyMapping_GetItemString(dict, (char *)"__pyx_vtable__");
6292 #if PY_VERSION_HEX >= 0x02070000 && !(PY_MAJOR_VERSION==3&&PY_MINOR_VERSION==0)
6293 ptr = PyCapsule_GetPointer(ob, 0);
6295 ptr = PyCObject_AsVoidPtr(ob);
6297 if (!ptr && !PyErr_Occurred())
6298 PyErr_SetString(PyExc_RuntimeError, "invalid vtable found for imported type");
6307 #------------------------------------------------------------------------------------
6309 init_string_tab_utility_code = UtilityCode(
6311 static int __Pyx_InitStrings(__Pyx_StringTabEntry *t); /*proto*/
6314 static int __Pyx_InitStrings(__Pyx_StringTabEntry *t) {
6316 #if PY_MAJOR_VERSION < 3
6317 if (t->is_unicode) {
6318 *t->p = PyUnicode_DecodeUTF8(t->s, t->n - 1, NULL);
6319 } else if (t->intern) {
6320 *t->p = PyString_InternFromString(t->s);
6322 *t->p = PyString_FromStringAndSize(t->s, t->n - 1);
6324 #else /* Python 3+ has unicode identifiers */
6325 if (t->is_unicode | t->is_str) {
6327 *t->p = PyUnicode_InternFromString(t->s);
6328 } else if (t->encoding) {
6329 *t->p = PyUnicode_Decode(t->s, t->n - 1, t->encoding, NULL);
6331 *t->p = PyUnicode_FromStringAndSize(t->s, t->n - 1);
6334 *t->p = PyBytes_FromStringAndSize(t->s, t->n - 1);
6345 #------------------------------------------------------------------------------------
6347 force_init_threads_utility_code = UtilityCode(
6349 #ifndef __PYX_FORCE_INIT_THREADS
6350 #if PY_VERSION_HEX < 0x02040200
6351 #define __PYX_FORCE_INIT_THREADS 1
6353 #define __PYX_FORCE_INIT_THREADS 0
6358 #------------------------------------------------------------------------------------
6360 # Note that cPython ignores PyTrace_EXCEPTION,
6361 # but maybe some other profilers don't.
6363 profile_utility_code = UtilityCode(proto="""
6364 #ifndef CYTHON_PROFILE
6365 #define CYTHON_PROFILE 1
6368 #ifndef CYTHON_PROFILE_REUSE_FRAME
6369 #define CYTHON_PROFILE_REUSE_FRAME 0
6374 #include "compile.h"
6375 #include "frameobject.h"
6376 #include "traceback.h"
6378 #if CYTHON_PROFILE_REUSE_FRAME
6379 #define CYTHON_FRAME_MODIFIER static
6380 #define CYTHON_FRAME_DEL
6382 #define CYTHON_FRAME_MODIFIER
6383 #define CYTHON_FRAME_DEL Py_DECREF(%(FRAME)s)
6386 #define __Pyx_TraceDeclarations \\
6387 static PyCodeObject *%(FRAME_CODE)s = NULL; \\
6388 CYTHON_FRAME_MODIFIER PyFrameObject *%(FRAME)s = NULL; \\
6389 int __Pyx_use_tracing = 0;
6391 #define __Pyx_TraceCall(funcname, srcfile, firstlineno) \\
6392 if (unlikely(PyThreadState_GET()->use_tracing && PyThreadState_GET()->c_profilefunc)) { \\
6393 __Pyx_use_tracing = __Pyx_TraceSetupAndCall(&%(FRAME_CODE)s, &%(FRAME)s, funcname, srcfile, firstlineno); \\
6396 #define __Pyx_TraceException() \\
6397 if (unlikely(__Pyx_use_tracing( && PyThreadState_GET()->use_tracing && PyThreadState_GET()->c_profilefunc) { \\
6398 PyObject *exc_info = __Pyx_GetExceptionTuple(); \\
6400 PyThreadState_GET()->c_profilefunc( \\
6401 PyThreadState_GET()->c_profileobj, %(FRAME)s, PyTrace_EXCEPTION, exc_info); \\
6402 Py_DECREF(exc_info); \\
6406 #define __Pyx_TraceReturn(result) \\
6407 if (unlikely(__Pyx_use_tracing) && PyThreadState_GET()->use_tracing && PyThreadState_GET()->c_profilefunc) { \\
6408 PyThreadState_GET()->c_profilefunc( \\
6409 PyThreadState_GET()->c_profileobj, %(FRAME)s, PyTrace_RETURN, (PyObject*)result); \\
6410 CYTHON_FRAME_DEL; \\
6413 static PyCodeObject *__Pyx_createFrameCodeObject(const char *funcname, const char *srcfile, int firstlineno); /*proto*/
6414 static int __Pyx_TraceSetupAndCall(PyCodeObject** code, PyFrameObject** frame, const char *funcname, const char *srcfile, int firstlineno); /*proto*/
6418 #define __Pyx_TraceDeclarations
6419 #define __Pyx_TraceCall(funcname, srcfile, firstlineno)
6420 #define __Pyx_TraceException()
6421 #define __Pyx_TraceReturn(result)
6423 #endif /* CYTHON_PROFILE */
6426 "FRAME": Naming.frame_cname,
6427 "FRAME_CODE": Naming.frame_code_cname,
6433 static int __Pyx_TraceSetupAndCall(PyCodeObject** code,
6434 PyFrameObject** frame,
6435 const char *funcname,
6436 const char *srcfile,
6438 if (*frame == NULL || !CYTHON_PROFILE_REUSE_FRAME) {
6439 if (*code == NULL) {
6440 *code = __Pyx_createFrameCodeObject(funcname, srcfile, firstlineno);
6441 if (*code == NULL) return 0;
6443 *frame = PyFrame_New(
6444 PyThreadState_GET(), /*PyThreadState *tstate*/
6445 *code, /*PyCodeObject *code*/
6446 PyModule_GetDict(%(MODULE)s), /*PyObject *globals*/
6447 0 /*PyObject *locals*/
6449 if (*frame == NULL) return 0;
6452 (*frame)->f_tstate = PyThreadState_GET();
6454 return PyThreadState_GET()->c_profilefunc(PyThreadState_GET()->c_profileobj, *frame, PyTrace_CALL, NULL) == 0;
6457 static PyCodeObject *__Pyx_createFrameCodeObject(const char *funcname, const char *srcfile, int firstlineno) {
6458 PyObject *py_srcfile = 0;
6459 PyObject *py_funcname = 0;
6460 PyCodeObject *py_code = 0;
6462 #if PY_MAJOR_VERSION < 3
6463 py_funcname = PyString_FromString(funcname);
6464 py_srcfile = PyString_FromString(srcfile);
6466 py_funcname = PyUnicode_FromString(funcname);
6467 py_srcfile = PyUnicode_FromString(srcfile);
6469 if (!py_funcname | !py_srcfile) goto bad;
6471 py_code = PyCode_New(
6472 0, /*int argcount,*/
6473 #if PY_MAJOR_VERSION >= 3
6474 0, /*int kwonlyargcount,*/
6477 0, /*int stacksize,*/
6479 %(EMPTY_BYTES)s, /*PyObject *code,*/
6480 %(EMPTY_TUPLE)s, /*PyObject *consts,*/
6481 %(EMPTY_TUPLE)s, /*PyObject *names,*/
6482 %(EMPTY_TUPLE)s, /*PyObject *varnames,*/
6483 %(EMPTY_TUPLE)s, /*PyObject *freevars,*/
6484 %(EMPTY_TUPLE)s, /*PyObject *cellvars,*/
6485 py_srcfile, /*PyObject *filename,*/
6486 py_funcname, /*PyObject *name,*/
6487 firstlineno, /*int firstlineno,*/
6488 %(EMPTY_BYTES)s /*PyObject *lnotab*/
6492 Py_XDECREF(py_srcfile);
6493 Py_XDECREF(py_funcname);
6498 #endif /* CYTHON_PROFILE */
6500 'EMPTY_TUPLE' : Naming.empty_tuple,
6501 'EMPTY_BYTES' : Naming.empty_bytes,
6502 "MODULE": Naming.module_cname,