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, ClosureTempAllocator
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, directive_locals = {}):
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 in directive_locals:
547 type_node = directive_locals[name]
548 other_type = type_node.analyse_as_type(env)
549 if other_type is None:
550 error(type_node.pos, "Not a type")
551 elif (type is not PyrexTypes.py_object_type
552 and not type.same_as(other_type)):
553 error(self.base.pos, "Signature does not agree with previous declaration")
554 error(type_node.pos, "Previous declaration here")
557 if name_declarator.cname:
559 "Function argument cannot have C name specification")
560 # Turn *[] argument into **
562 type = PyrexTypes.c_ptr_type(type.base_type)
563 # Catch attempted C-style func(void) decl
565 error(arg_node.pos, "Use spam() rather than spam(void) to declare a function with no arguments.")
566 func_type_args.append(
567 PyrexTypes.CFuncTypeArg(name, type, arg_node.pos))
569 self.optional_arg_count += 1
570 elif self.optional_arg_count:
571 error(self.pos, "Non-default argument follows default argument")
573 if self.optional_arg_count:
574 scope = StructOrUnionScope()
575 arg_count_member = '%sn' % Naming.pyrex_prefix
576 scope.declare_var(arg_count_member, PyrexTypes.c_int_type, self.pos)
577 for arg in func_type_args[len(func_type_args)-self.optional_arg_count:]:
578 scope.declare_var(arg.name, arg.type, arg.pos, allow_pyobject = 1)
579 struct_cname = env.mangle(Naming.opt_arg_prefix, self.base.name)
580 self.op_args_struct = env.global_scope().declare_struct_or_union(name = struct_cname,
585 cname = struct_cname)
586 self.op_args_struct.defined_in_pxd = 1
587 self.op_args_struct.used = 1
591 if self.exception_check == '+':
592 env.add_include_file('stdexcept')
593 if return_type.is_pyobject \
594 and (self.exception_value or self.exception_check) \
595 and self.exception_check != '+':
597 "Exception clause not allowed for function returning Python object")
599 if self.exception_value:
600 self.exception_value.analyse_const_expression(env)
601 if self.exception_check == '+':
602 self.exception_value.analyse_types(env)
603 exc_val_type = self.exception_value.type
604 if not exc_val_type.is_error and \
605 not exc_val_type.is_pyobject and \
606 not (exc_val_type.is_cfunction and not exc_val_type.return_type.is_pyobject and len(exc_val_type.args)==0):
607 error(self.exception_value.pos,
608 "Exception value must be a Python exception or cdef function with no arguments.")
609 exc_val = self.exception_value
611 self.exception_value = self.exception_value.coerce_to(return_type, env)
612 if self.exception_value.analyse_const_expression(env):
613 exc_val = self.exception_value.get_constant_c_result_code()
615 raise InternalError("get_constant_c_result_code not implemented for %s" %
616 self.exception_value.__class__.__name__)
617 if not return_type.assignable_from(self.exception_value.type):
618 error(self.exception_value.pos,
619 "Exception value incompatible with function return type")
620 exc_check = self.exception_check
621 if return_type.is_cfunction:
623 "Function cannot return a function")
624 func_type = PyrexTypes.CFuncType(
625 return_type, func_type_args, self.has_varargs,
626 optional_arg_count = self.optional_arg_count,
627 exception_value = exc_val, exception_check = exc_check,
628 calling_convention = self.base.calling_convention,
629 nogil = self.nogil, with_gil = self.with_gil, is_overridable = self.overridable)
630 if self.optional_arg_count:
631 func_type.op_arg_struct = PyrexTypes.c_ptr_type(self.op_args_struct.type)
632 callspec = env.directives['callspec']
634 current = func_type.calling_convention
635 if current and current != callspec:
636 error(self.pos, "cannot have both '%s' and '%s' "
637 "calling conventions" % (current, callspec))
638 func_type.calling_convention = callspec
639 return self.base.analyse(func_type, env)
642 class CArgDeclNode(Node):
643 # Item in a function declaration argument list.
645 # base_type CBaseTypeNode
646 # declarator CDeclaratorNode
647 # not_none boolean Tagged with 'not None'
648 # or_none boolean Tagged with 'or None'
649 # accept_none boolean Resolved boolean for not_none/or_none
650 # default ExprNode or None
651 # default_value PyObjectConst constant for default value
652 # annotation ExprNode or None Py3 function arg annotation
653 # is_self_arg boolean Is the "self" arg of an extension type method
654 # is_type_arg boolean Is the "class" arg of an extension type classmethod
655 # is_kw_only boolean Is a keyword-only argument
657 child_attrs = ["base_type", "declarator", "default"]
666 name_declarator = None
670 def analyse(self, env, nonempty = 0, is_self_arg = False):
672 self.base_type.is_self_arg = self.is_self_arg = True
673 if self.type is None:
674 # The parser may missinterpret names as types...
676 if isinstance(self.declarator, CNameDeclaratorNode) and self.declarator.name == '':
678 self.declarator.name = self.base_type.name
679 self.base_type.name = None
680 self.base_type.is_basic_c_type = False
683 could_be_name = False
684 base_type = self.base_type.analyse(env, could_be_name = could_be_name)
685 if hasattr(self.base_type, 'arg_name') and self.base_type.arg_name:
686 self.declarator.name = self.base_type.arg_name
687 # The parser is unable to resolve the ambiguity of [] as part of the
688 # type (e.g. in buffers) or empty declarator (as with arrays).
689 # This is only arises for empty multi-dimensional arrays.
690 if (base_type.is_array
691 and isinstance(self.base_type, TemplatedTypeNode)
692 and isinstance(self.declarator, CArrayDeclaratorNode)):
693 declarator = self.declarator
694 while isinstance(declarator.base, CArrayDeclaratorNode):
695 declarator = declarator.base
696 declarator.base = self.base_type.array_declarator
697 base_type = base_type.base_type
698 return self.declarator.analyse(base_type, env, nonempty = nonempty)
700 return self.name_declarator, self.type
702 def calculate_default_value_code(self, code):
703 if self.default_value is None:
705 if self.default.is_literal:
706 # will not output any code, just assign the result_code
707 self.default.generate_evaluation_code(code)
708 return self.type.cast_code(self.default.result())
709 self.default_value = code.get_argument_default_const(self.type)
710 return self.default_value
712 def annotate(self, code):
714 self.default.annotate(code)
717 class CBaseTypeNode(Node):
718 # Abstract base class for C base type nodes.
720 # Processing during analyse_declarations phase:
727 def analyse_as_type(self, env):
728 return self.analyse(env)
730 class CAnalysedBaseTypeNode(Node):
735 def analyse(self, env, could_be_name = False):
738 class CSimpleBaseTypeNode(CBaseTypeNode):
740 # module_path [string] Qualifying name components
741 # is_basic_c_type boolean
745 # is_self_arg boolean Is self argument of C method
746 # ##is_type_arg boolean Is type argument of class method
749 arg_name = None # in case the argument name was interpreted as a type
751 is_basic_c_type = False
754 def analyse(self, env, could_be_name = False):
755 # Return type descriptor.
756 #print "CSimpleBaseTypeNode.analyse: is_self_arg =", self.is_self_arg ###
758 if self.is_basic_c_type:
759 type = PyrexTypes.simple_c_type(self.signed, self.longness, self.name)
761 error(self.pos, "Unrecognised type modifier combination")
762 elif self.name == "object" and not self.module_path:
763 type = py_object_type
764 elif self.name is None:
765 if self.is_self_arg and env.is_c_class_scope:
766 #print "CSimpleBaseTypeNode.analyse: defaulting to parent type" ###
767 type = env.parent_type
768 ## elif self.is_type_arg and env.is_c_class_scope:
769 ## type = Builtin.type_type
771 type = py_object_type
774 scope = env.find_imported_module(self.module_path, self.pos)
778 if scope.is_c_class_scope:
779 scope = scope.global_scope()
780 entry = scope.lookup(self.name)
781 if entry and entry.is_type:
784 if self.is_self_arg and env.is_c_class_scope:
785 type = env.parent_type
786 ## elif self.is_type_arg and env.is_c_class_scope:
787 ## type = Builtin.type_type
789 type = py_object_type
790 self.arg_name = self.name
793 if not self.name in self.templates:
794 error(self.pos, "'%s' is not a type identifier" % self.name)
795 type = PyrexTypes.TemplatePlaceholderType(self.name)
797 error(self.pos, "'%s' is not a type identifier" % self.name)
799 if not type.is_numeric or type.is_complex:
800 error(self.pos, "can only complexify c numeric types")
801 type = PyrexTypes.CComplexType(type)
802 type.create_declaration_utility_code(env)
803 elif type is Builtin.complex_type:
804 # Special case: optimise builtin complex type into C's
805 # double complex. The parser cannot do this (as for the
806 # normal scalar types) as the user may have redeclared the
807 # 'complex' type. Testing for the exact type here works.
808 type = PyrexTypes.c_double_complex_type
809 type.create_declaration_utility_code(env)
814 return PyrexTypes.error_type
816 class CNestedBaseTypeNode(CBaseTypeNode):
817 # For C++ classes that live inside other C++ classes.
820 # base_type CBaseTypeNode
822 child_attrs = ['base_type']
824 def analyse(self, env, could_be_name = None):
825 base_type = self.base_type.analyse(env)
826 if base_type is PyrexTypes.error_type:
827 return PyrexTypes.error_type
828 if not base_type.is_cpp_class:
829 error(self.pos, "'%s' is not a valid type scope" % base_type)
830 return PyrexTypes.error_type
831 type_entry = base_type.scope.lookup_here(self.name)
832 if not type_entry or not type_entry.is_type:
833 error(self.pos, "'%s.%s' is not a type identifier" % (base_type, self.name))
834 return PyrexTypes.error_type
835 return type_entry.type
837 class TemplatedTypeNode(CBaseTypeNode):
839 # positional_args [ExprNode] List of positional arguments
840 # keyword_args DictNode Keyword arguments
841 # base_type_node CBaseTypeNode
844 # type PyrexTypes.BufferType or PyrexTypes.CppClassType ...containing the right options
847 child_attrs = ["base_type_node", "positional_args",
848 "keyword_args", "dtype_node"]
854 def analyse(self, env, could_be_name = False, base_type = None):
855 if base_type is None:
856 base_type = self.base_type_node.analyse(env)
857 if base_type.is_error: return base_type
859 if base_type.is_cpp_class:
861 if self.keyword_args and self.keyword_args.key_value_pairs:
862 error(self.pos, "c++ templates cannot take keyword arguments");
863 self.type = PyrexTypes.error_type
866 for template_node in self.positional_args:
867 type = template_node.analyse_as_type(env)
869 error(template_node.pos, "unknown type in template argument")
871 template_types.append(type)
872 self.type = base_type.specialize_here(self.pos, template_types)
874 elif base_type.is_pyobject:
878 options = Buffer.analyse_buffer_options(
881 self.positional_args,
883 base_type.buffer_defaults)
885 if sys.version_info[0] < 3:
886 # Py 2.x enforces byte strings as keyword arguments ...
887 options = dict([ (name.encode('ASCII'), value)
888 for name, value in options.items() ])
890 self.type = PyrexTypes.BufferType(base_type, **options)
894 empty_declarator = CNameDeclaratorNode(self.pos, name="", cname=None)
895 if len(self.positional_args) > 1 or self.keyword_args.key_value_pairs:
896 error(self.pos, "invalid array declaration")
897 self.type = PyrexTypes.error_type
899 # It would be nice to merge this class with CArrayDeclaratorNode,
900 # but arrays are part of the declaration, not the type...
901 if not self.positional_args:
904 dimension = self.positional_args[0]
905 self.array_declarator = CArrayDeclaratorNode(self.pos,
906 base = empty_declarator,
907 dimension = dimension)
908 self.type = self.array_declarator.analyse(base_type, env)[1]
912 class CComplexBaseTypeNode(CBaseTypeNode):
913 # base_type CBaseTypeNode
914 # declarator CDeclaratorNode
916 child_attrs = ["base_type", "declarator"]
918 def analyse(self, env, could_be_name = False):
919 base = self.base_type.analyse(env, could_be_name)
920 _, type = self.declarator.analyse(base, env)
924 class CVarDefNode(StatNode):
925 # C variable definition or forward/extern function declaration.
927 # visibility 'private' or 'public' or 'extern'
928 # base_type CBaseTypeNode
929 # declarators [CDeclaratorNode]
933 # decorators [cython.locals(...)] or None
934 # directive_locals { string : NameNode } locals defined by cython.locals(...)
936 child_attrs = ["base_type", "declarators"]
939 directive_locals = None
941 def analyse_declarations(self, env, dest_scope = None):
942 if self.directive_locals is None:
943 self.directive_locals = {}
946 self.dest_scope = dest_scope
947 base_type = self.base_type.analyse(env)
949 # If the field is an external typedef, we cannot be sure about the type,
950 # so do conversion ourself rather than rely on the CPython mechanism (through
951 # a property; made in AnalyseDeclarationsTransform).
952 if (dest_scope.is_c_class_scope
953 and self.visibility in ('public', 'readonly')):
956 need_property = False
957 visibility = self.visibility
959 for declarator in self.declarators:
960 if isinstance(declarator, CFuncDeclaratorNode):
961 name_declarator, type = declarator.analyse(base_type, env, directive_locals=self.directive_locals)
963 name_declarator, type = declarator.analyse(base_type, env)
964 if not type.is_complete():
965 if not (self.visibility == 'extern' and type.is_array):
966 error(declarator.pos,
967 "Variable type '%s' is incomplete" % type)
968 if self.visibility == 'extern' and type.is_pyobject:
969 error(declarator.pos,
970 "Python object cannot be declared extern")
971 name = name_declarator.name
972 cname = name_declarator.cname
974 error(declarator.pos, "Missing name in declaration.")
976 if type.is_cfunction:
977 entry = dest_scope.declare_cfunction(name, type, declarator.pos,
978 cname = cname, visibility = self.visibility, in_pxd = self.in_pxd,
980 if entry is not None:
981 entry.directive_locals = copy.copy(self.directive_locals)
983 if self.directive_locals:
984 error(self.pos, "Decorators can only be followed by functions")
985 if self.in_pxd and self.visibility != 'extern':
987 "Only 'extern' C variable declaration allowed in .pxd file")
988 entry = dest_scope.declare_var(name, type, declarator.pos,
989 cname=cname, visibility=visibility, api=self.api, is_cdef=1)
990 entry.needs_property = need_property
993 class CStructOrUnionDefNode(StatNode):
995 # cname string or None
996 # kind "struct" or "union"
997 # typedef_flag boolean
998 # visibility "public" or "private"
1001 # attributes [CVarDefNode] or None
1005 child_attrs = ["attributes"]
1007 def analyse_declarations(self, env):
1009 if self.visibility == 'extern' and self.packed:
1010 error(self.pos, "Cannot declare extern struct as 'packed'")
1011 if self.attributes is not None:
1012 scope = StructOrUnionScope(self.name)
1013 self.entry = env.declare_struct_or_union(
1014 self.name, self.kind, scope, self.typedef_flag, self.pos,
1015 self.cname, visibility = self.visibility, api = self.api,
1016 packed = self.packed)
1017 if self.attributes is not None:
1018 if self.in_pxd and not env.in_cinclude:
1019 self.entry.defined_in_pxd = 1
1020 for attr in self.attributes:
1021 attr.analyse_declarations(env, scope)
1022 if self.visibility != 'extern':
1023 need_typedef_indirection = False
1024 for attr in scope.var_entries:
1026 while type.is_array:
1027 type = type.base_type
1028 if type == self.entry.type:
1029 error(attr.pos, "Struct cannot contain itself as a member.")
1030 if self.typedef_flag:
1032 type = type.base_type
1033 if type == self.entry.type:
1034 need_typedef_indirection = True
1035 if need_typedef_indirection:
1036 # C can't handle typedef structs that refer to themselves.
1037 struct_entry = self.entry
1038 self.entry = env.declare_typedef(
1039 self.name, struct_entry.type, self.pos,
1040 cname = self.cname, visibility='ignore')
1041 struct_entry.type.typedef_flag = False
1042 # FIXME: this might be considered a hack ;-)
1043 struct_entry.cname = struct_entry.type.cname = \
1044 '_' + self.entry.type.typedef_cname
1046 def analyse_expressions(self, env):
1049 def generate_execution_code(self, code):
1053 class CppClassNode(CStructOrUnionDefNode):
1056 # cname string or None
1057 # visibility "extern"
1059 # attributes [CVarDefNode] or None
1061 # base_classes [string]
1062 # templates [string] or None
1064 def analyse_declarations(self, env):
1066 if self.attributes is not None:
1067 scope = CppClassScope(self.name, env)
1068 base_class_types = []
1069 for base_class_name in self.base_classes:
1070 base_class_entry = env.lookup(base_class_name)
1071 if base_class_entry is None:
1072 error(self.pos, "'%s' not found" % base_class_name)
1073 elif not base_class_entry.is_type or not base_class_entry.type.is_cpp_class:
1074 error(self.pos, "'%s' is not a cpp class type" % base_class_name)
1076 base_class_types.append(base_class_entry.type)
1077 if self.templates is None:
1078 template_types = None
1080 template_types = [PyrexTypes.TemplatePlaceholderType(template_name) for template_name in self.templates]
1081 self.entry = env.declare_cpp_class(
1082 self.name, scope, self.pos,
1083 self.cname, base_class_types, visibility = self.visibility, templates = template_types)
1084 if self.entry is None:
1086 self.entry.is_cpp_class = 1
1087 if self.attributes is not None:
1088 if self.in_pxd and not env.in_cinclude:
1089 self.entry.defined_in_pxd = 1
1090 for attr in self.attributes:
1091 attr.analyse_declarations(scope)
1093 class CEnumDefNode(StatNode):
1094 # name string or None
1095 # cname string or None
1096 # items [CEnumDefItemNode]
1097 # typedef_flag boolean
1098 # visibility "public" or "private"
1103 child_attrs = ["items"]
1105 def analyse_declarations(self, env):
1106 self.entry = env.declare_enum(self.name, self.pos,
1107 cname = self.cname, typedef_flag = self.typedef_flag,
1108 visibility = self.visibility, api = self.api)
1109 if self.items is not None:
1110 if self.in_pxd and not env.in_cinclude:
1111 self.entry.defined_in_pxd = 1
1112 for item in self.items:
1113 item.analyse_declarations(env, self.entry)
1115 def analyse_expressions(self, env):
1118 def generate_execution_code(self, code):
1119 if self.visibility == 'public' or self.api:
1120 temp = code.funcstate.allocate_temp(PyrexTypes.py_object_type, manage_ref=True)
1121 for item in self.entry.enum_values:
1122 code.putln("%s = PyInt_FromLong(%s); %s" % (
1125 code.error_goto_if_null(temp, item.pos)))
1126 code.put_gotref(temp)
1127 code.putln('if (__Pyx_SetAttrString(%s, "%s", %s) < 0) %s' % (
1128 Naming.module_cname,
1131 code.error_goto(item.pos)))
1132 code.put_decref_clear(temp, PyrexTypes.py_object_type)
1133 code.funcstate.release_temp(temp)
1136 class CEnumDefItemNode(StatNode):
1138 # cname string or None
1139 # value ExprNode or None
1141 child_attrs = ["value"]
1143 def analyse_declarations(self, env, enum_entry):
1145 self.value.analyse_const_expression(env)
1146 if not self.value.type.is_int:
1147 self.value = self.value.coerce_to(PyrexTypes.c_int_type, env)
1148 self.value.analyse_const_expression(env)
1149 entry = env.declare_const(self.name, enum_entry.type,
1150 self.value, self.pos, cname = self.cname,
1151 visibility = enum_entry.visibility, api = enum_entry.api)
1152 enum_entry.enum_values.append(entry)
1155 class CTypeDefNode(StatNode):
1156 # base_type CBaseTypeNode
1157 # declarator CDeclaratorNode
1158 # visibility "public" or "private"
1162 child_attrs = ["base_type", "declarator"]
1164 def analyse_declarations(self, env):
1165 base = self.base_type.analyse(env)
1166 name_declarator, type = self.declarator.analyse(base, env)
1167 name = name_declarator.name
1168 cname = name_declarator.cname
1169 entry = env.declare_typedef(name, type, self.pos,
1170 cname = cname, visibility = self.visibility, api = self.api)
1171 if self.in_pxd and not env.in_cinclude:
1172 entry.defined_in_pxd = 1
1174 def analyse_expressions(self, env):
1176 def generate_execution_code(self, code):
1180 class FuncDefNode(StatNode, BlockNode):
1181 # Base class for function definition nodes.
1183 # return_type PyrexType
1184 # #filename string C name of filename string const
1185 # entry Symtab.Entry
1186 # needs_closure boolean Whether or not this function has inner functions/classes/yield
1187 # needs_outer_scope boolean Whether or not this function requires outer scope
1188 # directive_locals { string : NameNode } locals defined by cython.locals(...)
1192 needs_closure = False
1193 needs_outer_scope = False
1194 is_generator = False
1195 is_generator_body = False
1198 def analyse_default_values(self, env):
1199 genv = env.global_scope()
1201 for arg in self.args:
1205 arg.default.analyse_types(env)
1206 arg.default = arg.default.coerce_to(arg.type, genv)
1209 "This argument cannot have a default value")
1214 error(arg.pos, "Non-default argument following default argument")
1216 def align_argument_type(self, env, arg):
1217 directive_locals = self.directive_locals
1219 if arg.name in directive_locals:
1220 type_node = directive_locals[arg.name]
1221 other_type = type_node.analyse_as_type(env)
1222 if other_type is None:
1223 error(type_node.pos, "Not a type")
1224 elif (type is not PyrexTypes.py_object_type
1225 and not type.same_as(other_type)):
1226 error(arg.base_type.pos, "Signature does not agree with previous declaration")
1227 error(type_node.pos, "Previous declaration here")
1229 arg.type = other_type
1232 def need_gil_acquisition(self, lenv):
1235 def create_local_scope(self, env):
1237 while genv.is_py_class_scope or genv.is_c_class_scope:
1238 genv = genv.outer_scope
1239 if self.needs_closure:
1240 lenv = ClosureScope(name=self.entry.name,
1242 scope_name=self.entry.cname)
1244 lenv = LocalScope(name=self.entry.name,
1247 lenv.return_type = self.return_type
1248 type = self.entry.type
1249 if type.is_cfunction:
1250 lenv.nogil = type.nogil and not type.with_gil
1251 self.local_scope = lenv
1252 lenv.directives = env.directives
1255 def generate_function_body(self, env, code):
1256 self.body.generate_execution_code(code)
1258 def generate_function_definitions(self, env, code):
1261 lenv = self.local_scope
1262 if lenv.is_closure_scope and not lenv.is_passthrough:
1263 outer_scope_cname = "%s->%s" % (Naming.cur_scope_cname,
1264 Naming.outer_scope_cname)
1266 outer_scope_cname = Naming.outer_scope_cname
1267 lenv.mangle_closure_cnames(outer_scope_cname)
1268 # Generate closure function definitions
1269 self.body.generate_function_definitions(lenv, code)
1270 # generate lambda function definitions
1271 self.generate_lambda_definitions(lenv, code)
1273 is_getbuffer_slot = (self.entry.name == "__getbuffer__" and
1274 self.entry.scope.is_c_class_scope)
1275 is_releasebuffer_slot = (self.entry.name == "__releasebuffer__" and
1276 self.entry.scope.is_c_class_scope)
1277 is_buffer_slot = is_getbuffer_slot or is_releasebuffer_slot
1279 if 'cython_unused' not in self.modifiers:
1280 self.modifiers = self.modifiers + ['cython_unused']
1282 preprocessor_guard = None
1283 if self.entry.is_special and not is_buffer_slot:
1284 slot = TypeSlots.method_name_to_slot.get(self.entry.name)
1286 preprocessor_guard = slot.preprocessor_guard_code()
1287 if (self.entry.name == '__long__' and
1288 not self.entry.scope.lookup_here('__int__')):
1289 preprocessor_guard = None
1291 profile = code.globalstate.directives['profile']
1292 if profile and lenv.nogil:
1293 warning(self.pos, "Cannot profile nogil function.", 1)
1296 code.globalstate.use_utility_code(profile_utility_code)
1298 # Generate C code for header and body of function
1299 code.enter_cfunc_scope()
1300 code.return_from_error_cleanup_label = code.new_label()
1302 # ----- Top-level constants used by this function
1303 code.mark_pos(self.pos)
1304 self.generate_cached_builtins_decls(lenv, code)
1305 # ----- Function header
1308 if preprocessor_guard:
1309 code.putln(preprocessor_guard)
1311 with_pymethdef = self.needs_assignment_synthesis(env, code)
1313 self.py_func.generate_function_header(code,
1314 with_pymethdef = with_pymethdef,
1316 self.generate_function_header(code,
1317 with_pymethdef = with_pymethdef)
1318 # ----- Local variable declarations
1319 # Find function scope
1321 while cenv.is_py_class_scope or cenv.is_c_class_scope:
1322 cenv = cenv.outer_scope
1323 if self.needs_closure:
1324 code.put(lenv.scope_class.type.declaration_code(Naming.cur_scope_cname))
1326 elif self.needs_outer_scope:
1327 if lenv.is_passthrough:
1328 code.put(lenv.scope_class.type.declaration_code(Naming.cur_scope_cname))
1330 code.put(cenv.scope_class.type.declaration_code(Naming.outer_scope_cname))
1332 self.generate_argument_declarations(lenv, code)
1333 for entry in lenv.var_entries:
1334 if not entry.in_closure:
1335 code.put_var_declaration(entry)
1337 if not self.return_type.is_void:
1338 if self.return_type.is_pyobject:
1342 (self.return_type.declaration_code(Naming.retval_cname),
1344 tempvardecl_code = code.insertion_point()
1346 code.put_declare_refcount_context()
1347 self.generate_keyword_list(code)
1349 code.put_trace_declarations()
1350 # ----- Extern library function declarations
1351 lenv.generate_library_function_declarations(code)
1352 # ----- GIL acquisition
1353 acquire_gil = self.acquire_gil
1355 env.use_utility_code(force_init_threads_utility_code)
1356 code.putln("#ifdef WITH_THREAD")
1357 code.putln("PyGILState_STATE _save = PyGILState_Ensure();")
1358 code.putln("#endif")
1359 # ----- set up refnanny
1361 code.put_setup_refcount_context(self.entry.name)
1362 # ----- Automatic lead-ins for certain special functions
1363 if is_getbuffer_slot:
1364 self.getbuffer_init(code)
1365 # ----- Create closure scope object
1366 if self.needs_closure:
1367 code.putln("%s = (%s)%s->tp_new(%s, %s, NULL);" % (
1368 Naming.cur_scope_cname,
1369 lenv.scope_class.type.declaration_code(''),
1370 lenv.scope_class.type.typeptr_cname,
1371 lenv.scope_class.type.typeptr_cname,
1372 Naming.empty_tuple))
1373 code.putln("if (unlikely(!%s)) {" % Naming.cur_scope_cname)
1374 if is_getbuffer_slot:
1375 self.getbuffer_error_cleanup(code)
1377 code.put_finish_refcount_context()
1378 # FIXME: what if the error return value is a Python value?
1379 code.putln("return %s;" % self.error_value())
1381 code.put_gotref(Naming.cur_scope_cname)
1382 # Note that it is unsafe to decref the scope at this point.
1383 if self.needs_outer_scope:
1384 code.putln("%s = (%s)%s;" % (
1386 cenv.scope_class.type.declaration_code(''),
1388 if lenv.is_passthrough:
1389 code.putln("%s = %s;" % (Naming.cur_scope_cname, outer_scope_cname));
1390 elif self.needs_closure:
1391 # inner closures own a reference to their outer parent
1392 code.put_incref(outer_scope_cname, cenv.scope_class.type)
1393 code.put_giveref(outer_scope_cname)
1394 # ----- Trace function call
1396 # this looks a bit late, but if we don't get here due to a
1397 # fatal error before hand, it's not really worth tracing
1398 code.put_trace_call(self.entry.name, self.pos)
1399 # ----- Fetch arguments
1400 self.generate_argument_parsing_code(env, code)
1401 # If an argument is assigned to in the body, we must
1402 # incref it to properly keep track of refcounts.
1403 for entry in lenv.arg_entries:
1404 if entry.type.is_pyobject:
1405 if (acquire_gil or entry.assignments) and not entry.in_closure:
1406 code.put_var_incref(entry)
1407 # ----- Initialise local variables
1408 for entry in lenv.var_entries:
1409 if entry.type.is_pyobject and entry.init_to_none and entry.used:
1410 code.put_init_var_to_py_none(entry)
1411 # ----- Initialise local buffer auxiliary variables
1412 for entry in lenv.var_entries + lenv.arg_entries:
1413 if entry.type.is_buffer and entry.buffer_aux.buffer_info_var.used:
1414 code.putln("%s.buf = NULL;" %
1415 entry.buffer_aux.buffer_info_var.cname)
1416 # ----- Check and convert arguments
1417 self.generate_argument_type_tests(code)
1418 # ----- Acquire buffer arguments
1419 for entry in lenv.arg_entries:
1420 if entry.type.is_buffer:
1421 Buffer.put_acquire_arg_buffer(entry, code, self.pos)
1423 # -------------------------
1424 # ----- Function body -----
1425 # -------------------------
1426 self.generate_function_body(env, code)
1428 # ----- Default return value
1430 if self.return_type.is_pyobject:
1431 #if self.return_type.is_extension_type:
1432 # lhs = "(PyObject *)%s" % Naming.retval_cname
1434 lhs = Naming.retval_cname
1435 code.put_init_to_py_none(lhs, self.return_type)
1437 val = self.return_type.default_value
1439 code.putln("%s = %s;" % (Naming.retval_cname, val))
1440 # ----- Error cleanup
1441 if code.error_label in code.labels_used:
1442 code.put_goto(code.return_label)
1443 code.put_label(code.error_label)
1444 for cname, type in code.funcstate.all_managed_temps():
1445 code.put_xdecref(cname, type)
1447 # Clean up buffers -- this calls a Python function
1448 # so need to save and restore error state
1449 buffers_present = len(lenv.buffer_entries) > 0
1451 code.globalstate.use_utility_code(restore_exception_utility_code)
1452 code.putln("{ PyObject *__pyx_type, *__pyx_value, *__pyx_tb;")
1453 code.putln("__Pyx_ErrFetch(&__pyx_type, &__pyx_value, &__pyx_tb);")
1454 for entry in lenv.buffer_entries:
1455 Buffer.put_release_buffer_code(code, entry)
1456 #code.putln("%s = 0;" % entry.cname)
1457 code.putln("__Pyx_ErrRestore(__pyx_type, __pyx_value, __pyx_tb);}")
1459 err_val = self.error_value()
1460 exc_check = self.caller_will_check_exceptions()
1461 if err_val is not None or exc_check:
1462 # TODO: Fix exception tracing (though currently unused by cProfile).
1463 # code.globalstate.use_utility_code(get_exception_tuple_utility_code)
1464 # code.put_trace_exception()
1465 code.putln('__Pyx_AddTraceback("%s");' % self.entry.qualified_name)
1467 warning(self.entry.pos, "Unraisable exception in function '%s'." \
1468 % self.entry.qualified_name, 0)
1470 '__Pyx_WriteUnraisable("%s");' %
1471 self.entry.qualified_name)
1472 env.use_utility_code(unraisable_exception_utility_code)
1473 env.use_utility_code(restore_exception_utility_code)
1474 default_retval = self.return_type.default_value
1475 if err_val is None and default_retval:
1476 err_val = default_retval
1477 if err_val is not None:
1478 code.putln("%s = %s;" % (Naming.retval_cname, err_val))
1480 if is_getbuffer_slot:
1481 self.getbuffer_error_cleanup(code)
1483 # If we are using the non-error cleanup section we should
1484 # jump past it if we have an error. The if-test below determine
1485 # whether this section is used.
1486 if buffers_present or is_getbuffer_slot:
1487 code.put_goto(code.return_from_error_cleanup_label)
1490 # ----- Non-error return cleanup
1491 code.put_label(code.return_label)
1492 for entry in lenv.buffer_entries:
1494 Buffer.put_release_buffer_code(code, entry)
1495 if is_getbuffer_slot:
1496 self.getbuffer_normal_cleanup(code)
1497 # ----- Return cleanup for both error and no-error return
1498 code.put_label(code.return_from_error_cleanup_label)
1499 if not Options.init_local_none:
1500 for entry in lenv.var_entries:
1501 if lenv.control_flow.get_state((entry.name, 'initialized')) is not True:
1502 entry.xdecref_cleanup = 1
1504 for entry in lenv.var_entries:
1505 if entry.type.is_pyobject:
1506 if entry.used and not entry.in_closure:
1507 code.put_var_decref(entry)
1508 # Decref any increfed args
1509 for entry in lenv.arg_entries:
1510 if entry.type.is_pyobject:
1511 if (acquire_gil or entry.assignments) and not entry.in_closure:
1512 code.put_var_decref(entry)
1513 if self.needs_closure:
1514 code.put_decref(Naming.cur_scope_cname, lenv.scope_class.type)
1517 # This code is duplicated in ModuleNode.generate_module_init_func
1519 default_retval = self.return_type.default_value
1520 err_val = self.error_value()
1521 if err_val is None and default_retval:
1522 err_val = default_retval
1523 if self.return_type.is_pyobject:
1524 code.put_xgiveref(self.return_type.as_pyobject(Naming.retval_cname))
1526 if self.entry.is_special and self.entry.name == "__hash__":
1527 # Returning -1 for __hash__ is supposed to signal an error
1528 # We do as Python instances and coerce -1 into -2.
1529 code.putln("if (unlikely(%s == -1) && !PyErr_Occurred()) %s = -2;" % (
1530 Naming.retval_cname, Naming.retval_cname))
1533 if self.return_type.is_pyobject:
1534 code.put_trace_return(Naming.retval_cname)
1536 code.put_trace_return("Py_None")
1538 code.put_finish_refcount_context()
1541 code.putln("#ifdef WITH_THREAD")
1542 code.putln("PyGILState_Release(_save);")
1543 code.putln("#endif")
1545 if not self.return_type.is_void:
1546 code.putln("return %s;" % Naming.retval_cname)
1550 if preprocessor_guard:
1551 code.putln("#endif /*!(%s)*/" % preprocessor_guard)
1553 # ----- Go back and insert temp variable declarations
1554 tempvardecl_code.put_temp_declarations(code.funcstate)
1555 # ----- Python version
1556 code.exit_cfunc_scope()
1558 self.py_func.generate_function_definitions(env, code)
1559 self.generate_wrapper_functions(code)
1561 def declare_argument(self, env, arg):
1562 if arg.type.is_void:
1563 error(arg.pos, "Invalid use of 'void'")
1564 elif not arg.type.is_complete() and not arg.type.is_array:
1566 "Argument type '%s' is incomplete" % arg.type)
1567 return env.declare_arg(arg.name, arg.type, arg.pos)
1569 def generate_arg_type_test(self, arg, code):
1570 # Generate type test for one argument.
1571 if arg.type.typeobj_is_available():
1572 code.globalstate.use_utility_code(arg_type_test_utility_code)
1573 typeptr_cname = arg.type.typeptr_cname
1574 arg_code = "((PyObject *)%s)" % arg.entry.cname
1576 'if (unlikely(!__Pyx_ArgTypeTest(%s, %s, %d, "%s", %s))) %s' % (
1581 arg.type.is_builtin_type,
1582 code.error_goto(arg.pos)))
1584 error(arg.pos, "Cannot test type of extern C class "
1585 "without type object name specification")
1587 def generate_arg_none_check(self, arg, code):
1588 # Generate None check for one argument.
1589 code.putln('if (unlikely(((PyObject *)%s) == Py_None)) {' % arg.entry.cname)
1590 code.putln('''PyErr_Format(PyExc_TypeError, "Argument '%s' must not be None"); %s''' % (
1592 code.error_goto(arg.pos)))
1595 def generate_wrapper_functions(self, code):
1598 def generate_execution_code(self, code):
1599 # Evaluate and store argument default values
1600 for arg in self.args:
1601 default = arg.default
1603 if not default.is_literal:
1604 default.generate_evaluation_code(code)
1605 default.make_owned_reference(code)
1606 result = default.result_as(arg.type)
1609 arg.calculate_default_value_code(code),
1611 if arg.type.is_pyobject:
1612 code.put_giveref(default.result())
1613 default.generate_post_assignment_code(code)
1614 default.free_temps(code)
1615 # For Python class methods, create and store function object
1617 self.assmt.generate_execution_code(code)
1620 # Special code for the __getbuffer__ function
1622 def getbuffer_init(self, code):
1623 info = self.local_scope.arg_entries[1].cname
1624 # Python 3.0 betas have a bug in memoryview which makes it call
1625 # getbuffer with a NULL parameter. For now we work around this;
1626 # the following block should be removed when this bug is fixed.
1627 code.putln("if (%s != NULL) {" % info)
1628 code.putln("%s->obj = Py_None; __Pyx_INCREF(Py_None);" % info)
1629 code.put_giveref("%s->obj" % info) # Do not refnanny object within structs
1632 def getbuffer_error_cleanup(self, code):
1633 info = self.local_scope.arg_entries[1].cname
1634 code.putln("if (%s != NULL && %s->obj != NULL) {"
1636 code.put_gotref("%s->obj" % info)
1637 code.putln("__Pyx_DECREF(%s->obj); %s->obj = NULL;"
1641 def getbuffer_normal_cleanup(self, code):
1642 info = self.local_scope.arg_entries[1].cname
1643 code.putln("if (%s != NULL && %s->obj == Py_None) {" % (info, info))
1644 code.put_gotref("Py_None")
1645 code.putln("__Pyx_DECREF(Py_None); %s->obj = NULL;" % info)
1648 class CFuncDefNode(FuncDefNode):
1649 # C function definition.
1651 # modifiers ['inline']
1652 # visibility 'private' or 'public' or 'extern'
1653 # base_type CBaseTypeNode
1654 # declarator CDeclaratorNode
1657 # decorators [DecoratorNode] list of decorators
1659 # with_gil boolean Acquire GIL around body
1661 # py_func wrapper for calling from Python
1662 # overridable whether or not this is a cpdef function
1663 # inline_in_pxd whether this is an inline function in a pxd file
1665 child_attrs = ["base_type", "declarator", "body", "py_func"]
1667 inline_in_pxd = False
1669 directive_locals = None
1671 def unqualified_name(self):
1672 return self.entry.name
1674 def analyse_declarations(self, env):
1675 if self.directive_locals is None:
1676 self.directive_locals = {}
1677 self.directive_locals.update(env.directives['locals'])
1678 base_type = self.base_type.analyse(env)
1679 # The 2 here is because we need both function and argument names.
1680 if isinstance(self.declarator, CFuncDeclaratorNode):
1681 name_declarator, type = self.declarator.analyse(base_type, env,
1682 nonempty = 2 * (self.body is not None),
1683 directive_locals = self.directive_locals)
1685 name_declarator, type = self.declarator.analyse(base_type, env, nonempty = 2 * (self.body is not None))
1686 if not type.is_cfunction:
1688 "Suite attached to non-function declaration")
1689 # Remember the actual type according to the function header
1690 # written here, because the type in the symbol table entry
1691 # may be different if we're overriding a C method inherited
1692 # from the base type of an extension type.
1694 type.is_overridable = self.overridable
1695 declarator = self.declarator
1696 while not hasattr(declarator, 'args'):
1697 declarator = declarator.base
1698 self.args = declarator.args
1699 for formal_arg, type_arg in zip(self.args, type.args):
1700 self.align_argument_type(env, type_arg)
1701 formal_arg.type = type_arg.type
1702 formal_arg.name = type_arg.name
1703 formal_arg.cname = type_arg.cname
1704 if type_arg.type.is_buffer and 'inline' in self.modifiers:
1705 warning(formal_arg.pos, "Buffer unpacking not optimized away.", 1)
1706 name = name_declarator.name
1707 cname = name_declarator.cname
1708 self.entry = env.declare_cfunction(
1709 name, type, self.pos,
1710 cname = cname, visibility = self.visibility,
1711 defining = self.body is not None,
1712 api = self.api, modifiers = self.modifiers)
1713 self.entry.inline_func_in_pxd = self.inline_in_pxd
1714 self.return_type = type.return_type
1715 if self.return_type.is_array and visibility != 'extern':
1717 "Function cannot return an array")
1719 if self.overridable and not env.is_module_scope:
1720 if len(self.args) < 1 or not self.args[0].type.is_pyobject:
1721 # An error will be produced in the cdef function
1722 self.overridable = False
1724 if self.overridable:
1726 py_func_body = self.call_self_node(is_module_scope = env.is_module_scope)
1727 self.py_func = DefNode(pos = self.pos,
1728 name = self.entry.name,
1731 starstar_arg = None,
1733 body = py_func_body,
1735 self.py_func.is_module_scope = env.is_module_scope
1736 self.py_func.analyse_declarations(env)
1737 self.entry.as_variable = self.py_func.entry
1738 # Reset scope entry the above cfunction
1739 env.entries[name] = self.entry
1740 if not env.is_module_scope or Options.lookup_module_cpdef:
1741 self.override = OverrideCheckNode(self.pos, py_func = self.py_func)
1742 self.body = StatListNode(self.pos, stats=[self.override, self.body])
1743 self.create_local_scope(env)
1745 def call_self_node(self, omit_optional_args=0, is_module_scope=0):
1747 args = self.type.args
1748 if omit_optional_args:
1749 args = args[:len(args) - self.type.optional_arg_count]
1750 arg_names = [arg.name for arg in args]
1752 cfunc = ExprNodes.NameNode(self.pos, name=self.entry.name)
1754 self_arg = ExprNodes.NameNode(self.pos, name=arg_names[0])
1755 cfunc = ExprNodes.AttributeNode(self.pos, obj=self_arg, attribute=self.entry.name)
1756 skip_dispatch = not is_module_scope or Options.lookup_module_cpdef
1757 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)
1758 return ReturnStatNode(pos=self.pos, return_type=PyrexTypes.py_object_type, value=c_call)
1760 def declare_arguments(self, env):
1761 for arg in self.type.args:
1763 error(arg.pos, "Missing argument name")
1764 self.declare_argument(env, arg)
1766 def need_gil_acquisition(self, lenv):
1767 return self.type.with_gil
1769 def nogil_check(self, env):
1771 with_gil = type.with_gil
1772 if type.nogil and not with_gil:
1773 if type.return_type.is_pyobject:
1775 "Function with Python return type cannot be declared nogil")
1776 for entry in self.local_scope.var_entries:
1777 if entry.type.is_pyobject:
1778 error(self.pos, "Function declared nogil has Python locals or temporaries")
1780 def analyse_expressions(self, env):
1781 self.local_scope.directives = env.directives
1782 if self.py_func is not None:
1783 # this will also analyse the default values
1784 self.py_func.analyse_expressions(env)
1786 self.analyse_default_values(env)
1787 self.acquire_gil = self.need_gil_acquisition(self.local_scope)
1789 def needs_assignment_synthesis(self, env, code=None):
1792 def generate_function_header(self, code, with_pymethdef, with_opt_args = 1, with_dispatch = 1, cname = None):
1795 for arg in type.args[:len(type.args)-type.optional_arg_count]:
1796 arg_decls.append(arg.declaration_code())
1797 if with_dispatch and self.overridable:
1798 arg_decls.append(PyrexTypes.c_int_type.declaration_code(Naming.skip_dispatch_cname))
1799 if type.optional_arg_count and with_opt_args:
1800 arg_decls.append(type.op_arg_struct.declaration_code(Naming.optional_args_cname))
1801 if type.has_varargs:
1802 arg_decls.append("...")
1804 arg_decls = ["void"]
1806 cname = self.entry.func_cname
1807 entity = type.function_header_code(cname, ', '.join(arg_decls))
1808 if self.entry.visibility == 'private':
1809 storage_class = "static "
1814 if 'inline' in self.modifiers:
1815 self.modifiers[self.modifiers.index('inline')] = 'cython_inline'
1817 modifiers = "%s " % ' '.join(self.modifiers).upper()
1819 header = self.return_type.declaration_code(entity, dll_linkage=dll_linkage)
1820 #print (storage_class, modifiers, header)
1821 code.putln("%s%s%s {" % (storage_class, modifiers, header))
1823 def generate_argument_declarations(self, env, code):
1824 for arg in self.args:
1826 result = arg.calculate_default_value_code(code)
1827 code.putln('%s = %s;' % (
1828 arg.type.declaration_code(arg.cname), result))
1830 def generate_keyword_list(self, code):
1833 def generate_argument_parsing_code(self, env, code):
1835 if self.type.optional_arg_count:
1836 code.putln('if (%s) {' % Naming.optional_args_cname)
1837 for arg in self.args:
1839 code.putln('if (%s->%sn > %s) {' % (Naming.optional_args_cname, Naming.pyrex_prefix, i))
1840 declarator = arg.declarator
1841 while not hasattr(declarator, 'name'):
1842 declarator = declarator.base
1843 code.putln('%s = %s->%s;' % (arg.cname, Naming.optional_args_cname, self.type.opt_arg_cname(declarator.name)))
1845 for _ in range(self.type.optional_arg_count):
1849 def generate_argument_conversion_code(self, code):
1852 def generate_argument_type_tests(self, code):
1853 # Generate type tests for args whose type in a parent
1854 # class is a supertype of the declared type.
1855 for arg in self.type.args:
1856 if arg.needs_type_test:
1857 self.generate_arg_type_test(arg, code)
1858 elif arg.type.is_pyobject and not arg.accept_none:
1859 self.generate_arg_none_check(arg, code)
1861 def error_value(self):
1862 if self.return_type.is_pyobject:
1866 return self.entry.type.exception_value
1868 def caller_will_check_exceptions(self):
1869 return self.entry.type.exception_check
1871 def generate_wrapper_functions(self, code):
1872 # If the C signature of a function has changed, we need to generate
1873 # wrappers to put in the slots here.
1876 func_type = entry.type
1877 while entry.prev_entry is not None:
1879 entry = entry.prev_entry
1880 entry.func_cname = "%s%swrap_%s" % (self.entry.func_cname, Naming.pyrex_prefix, k)
1882 self.generate_function_header(code,
1884 with_dispatch = entry.type.is_overridable,
1885 with_opt_args = entry.type.optional_arg_count,
1886 cname = entry.func_cname)
1887 if not self.return_type.is_void:
1889 args = self.type.args
1890 arglist = [arg.cname for arg in args[:len(args)-self.type.optional_arg_count]]
1891 if entry.type.is_overridable:
1892 arglist.append(Naming.skip_dispatch_cname)
1893 elif func_type.is_overridable:
1895 if entry.type.optional_arg_count:
1896 arglist.append(Naming.optional_args_cname)
1897 elif func_type.optional_arg_count:
1898 arglist.append('NULL')
1899 code.putln('%s(%s);' % (self.entry.func_cname, ', '.join(arglist)))
1903 class PyArgDeclNode(Node):
1904 # Argument which must be a Python object (used
1905 # for * and ** arguments).
1908 # entry Symtab.Entry
1909 # annotation ExprNode or None Py3 argument annotation
1912 def generate_function_definitions(self, env, code):
1913 self.entry.generate_function_definitions(env, code)
1915 class DecoratorNode(Node):
1918 # decorator NameNode or CallNode or AttributeNode
1919 child_attrs = ['decorator']
1922 class DefNode(FuncDefNode):
1923 # A Python function definition.
1925 # name string the Python name of the function
1926 # lambda_name string the internal name of a lambda 'function'
1927 # decorators [DecoratorNode] list of decorators
1928 # args [CArgDeclNode] formal arguments
1929 # star_arg PyArgDeclNode or None * argument
1930 # starstar_arg PyArgDeclNode or None ** argument
1931 # doc EncodedString or None
1933 # return_type_annotation
1934 # ExprNode or None the Py3 return type annotation
1936 # The following subnode is constructed internally
1937 # when the def statement is inside a Python class definition.
1939 # assmt AssignmentNode Function construction/assignment
1941 child_attrs = ["args", "star_arg", "starstar_arg", "body", "decorators"]
1946 num_required_kw_args = 0
1947 reqd_kw_flags_cname = "0"
1949 no_assignment_synthesis = 0
1951 return_type_annotation = None
1959 def __init__(self, pos, **kwds):
1960 FuncDefNode.__init__(self, pos, **kwds)
1962 for arg in self.args:
1969 self.num_kwonly_args = k
1970 self.num_required_kw_args = rk
1971 self.num_required_args = r
1973 def as_cfunction(self, cfunc=None, scope=None):
1975 error(self.star_arg.pos, "cdef function cannot have star argument")
1976 if self.starstar_arg:
1977 error(self.starstar_arg.pos, "cdef function cannot have starstar argument")
1980 for formal_arg in self.args:
1981 name_declarator, type = formal_arg.analyse(scope, nonempty=1)
1982 cfunc_args.append(PyrexTypes.CFuncTypeArg(name = name_declarator.name,
1984 type = py_object_type,
1985 pos = formal_arg.pos))
1986 cfunc_type = PyrexTypes.CFuncType(return_type = py_object_type,
1988 has_varargs = False,
1989 exception_value = None,
1990 exception_check = False,
1993 is_overridable = True)
1994 cfunc = CVarDefNode(self.pos, type=cfunc_type)
1998 cfunc_type = cfunc.type
1999 if len(self.args) != len(cfunc_type.args) or cfunc_type.has_varargs:
2000 error(self.pos, "wrong number of arguments")
2001 error(cfunc.pos, "previous declaration here")
2002 for i, (formal_arg, type_arg) in enumerate(zip(self.args, cfunc_type.args)):
2003 name_declarator, type = formal_arg.analyse(scope, nonempty=1,
2004 is_self_arg = (i == 0 and scope.is_c_class_scope))
2005 if type is None or type is PyrexTypes.py_object_type:
2006 formal_arg.type = type_arg.type
2007 formal_arg.name_declarator = name_declarator
2009 if cfunc_type.exception_value is None:
2010 exception_value = None
2012 exception_value = ExprNodes.ConstNode(self.pos, value=cfunc_type.exception_value, type=cfunc_type.return_type)
2013 declarator = CFuncDeclaratorNode(self.pos,
2014 base = CNameDeclaratorNode(self.pos, name=self.name, cname=None),
2016 has_varargs = False,
2017 exception_check = cfunc_type.exception_check,
2018 exception_value = exception_value,
2019 with_gil = cfunc_type.with_gil,
2020 nogil = cfunc_type.nogil)
2021 return CFuncDefNode(self.pos,
2023 base_type = CAnalysedBaseTypeNode(self.pos, type=cfunc_type.return_type),
2024 declarator = declarator,
2027 overridable = cfunc_type.is_overridable,
2029 with_gil = cfunc_type.with_gil,
2030 nogil = cfunc_type.nogil,
2031 visibility = 'private',
2033 directive_locals = getattr(cfunc, 'directive_locals', {}))
2035 def is_cdef_func_compatible(self):
2036 """Determines if the function's signature is compatible with a
2037 cdef function. This can be used before calling
2038 .as_cfunction() to see if that will be successful.
2040 if self.needs_closure:
2042 if self.star_arg or self.starstar_arg:
2046 def analyse_declarations(self, env):
2047 self.is_classmethod = self.is_staticmethod = False
2049 for decorator in self.decorators:
2050 func = decorator.decorator
2052 self.is_classmethod |= func.name == 'classmethod'
2053 self.is_staticmethod |= func.name == 'staticmethod'
2055 if self.is_classmethod and env.lookup_here('classmethod'):
2056 # classmethod() was overridden - not much we can do here ...
2057 self.is_classmethod = False
2058 if self.is_staticmethod and env.lookup_here('staticmethod'):
2059 # staticmethod() was overridden - not much we can do here ...
2060 self.is_staticmethod = False
2062 if self.name == '__new__' and env.is_py_class_scope:
2063 self.is_staticmethod = 1
2065 self.analyse_argument_types(env)
2066 if self.name == '<lambda>':
2067 self.declare_lambda_function(env)
2069 self.declare_pyfunction(env)
2070 self.analyse_signature(env)
2071 self.return_type = self.entry.signature.return_type()
2072 self.create_local_scope(env)
2074 def analyse_argument_types(self, env):
2075 directive_locals = self.directive_locals = env.directives['locals']
2076 allow_none_for_extension_args = env.directives['allow_none_for_extension_args']
2077 for arg in self.args:
2078 if hasattr(arg, 'name'):
2079 name_declarator = None
2081 base_type = arg.base_type.analyse(env)
2082 name_declarator, type = \
2083 arg.declarator.analyse(base_type, env)
2084 arg.name = name_declarator.name
2086 self.align_argument_type(env, arg)
2087 if name_declarator and name_declarator.cname:
2089 "Python function argument cannot have C name specification")
2090 arg.type = arg.type.as_argument_type()
2092 arg.needs_conversion = 0
2093 arg.needs_type_test = 0
2095 if arg.type.is_pyobject:
2097 arg.accept_none = True
2099 arg.accept_none = False
2100 elif arg.type.is_extension_type or arg.type.is_builtin_type:
2101 if arg.default and arg.default.constant_result is None:
2102 # special case: def func(MyType obj = None)
2103 arg.accept_none = True
2105 # default depends on compiler directive
2106 arg.accept_none = allow_none_for_extension_args
2108 # probably just a plain 'object'
2109 arg.accept_none = True
2111 arg.accept_none = True # won't be used, but must be there
2113 error(arg.pos, "Only Python type arguments can have 'not None'")
2115 error(arg.pos, "Only Python type arguments can have 'or None'")
2117 def analyse_signature(self, env):
2118 if self.entry.is_special:
2120 error(self.pos, "special functions of cdef classes cannot have decorators")
2121 self.entry.trivial_signature = len(self.args) == 1 and not (self.star_arg or self.starstar_arg)
2122 elif not env.directives['always_allow_keywords'] and not (self.star_arg or self.starstar_arg):
2123 # Use the simpler calling signature for zero- and one-argument functions.
2124 if self.entry.signature is TypeSlots.pyfunction_signature:
2125 if len(self.args) == 0:
2126 self.entry.signature = TypeSlots.pyfunction_noargs
2127 elif len(self.args) == 1:
2128 if self.args[0].default is None and not self.args[0].kw_only:
2129 self.entry.signature = TypeSlots.pyfunction_onearg
2130 elif self.entry.signature is TypeSlots.pymethod_signature:
2131 if len(self.args) == 1:
2132 self.entry.signature = TypeSlots.unaryfunc
2133 elif len(self.args) == 2:
2134 if self.args[1].default is None and not self.args[1].kw_only:
2135 self.entry.signature = TypeSlots.ibinaryfunc
2137 sig = self.entry.signature
2138 nfixed = sig.num_fixed_args()
2139 if sig is TypeSlots.pymethod_signature and nfixed == 1 \
2140 and len(self.args) == 0 and self.star_arg:
2141 # this is the only case where a diverging number of
2142 # arguments is not an error - when we have no explicit
2143 # 'self' parameter as in method(*args)
2144 sig = self.entry.signature = TypeSlots.pyfunction_signature # self is not 'really' used
2145 self.self_in_stararg = 1
2148 for i in range(min(nfixed, len(self.args))):
2151 if sig.is_self_arg(i) and not self.is_staticmethod:
2152 if self.is_classmethod:
2154 arg.hdr_type = arg.type = Builtin.type_type
2157 arg.hdr_type = arg.type = env.parent_type
2158 arg.needs_conversion = 0
2160 arg.hdr_type = sig.fixed_arg_type(i)
2161 if not arg.type.same_as(arg.hdr_type):
2162 if arg.hdr_type.is_pyobject and arg.type.is_pyobject:
2163 arg.needs_type_test = 1
2165 arg.needs_conversion = 1
2166 if arg.needs_conversion:
2167 arg.hdr_cname = Naming.arg_prefix + arg.name
2169 arg.hdr_cname = Naming.var_prefix + arg.name
2171 if nfixed > len(self.args):
2172 self.bad_signature()
2174 elif nfixed < len(self.args):
2175 if not sig.has_generic_args:
2176 self.bad_signature()
2177 for arg in self.args:
2178 if arg.is_generic and \
2179 (arg.type.is_extension_type or arg.type.is_builtin_type):
2180 arg.needs_type_test = 1
2182 def bad_signature(self):
2183 sig = self.entry.signature
2184 expected_str = "%d" % sig.num_fixed_args()
2185 if sig.has_generic_args:
2186 expected_str = expected_str + " or more"
2188 if name.startswith("__") and name.endswith("__"):
2189 desc = "Special method"
2193 "%s %s has wrong number of arguments "
2194 "(%d declared, %s expected)" % (
2195 desc, self.name, len(self.args), expected_str))
2197 def signature_has_nongeneric_args(self):
2198 argcount = len(self.args)
2199 if argcount == 0 or (
2200 argcount == 1 and (self.args[0].is_self_arg or
2201 self.args[0].is_type_arg)):
2205 def signature_has_generic_args(self):
2206 return self.entry.signature.has_generic_args
2208 def declare_pyfunction(self, env):
2209 #print "DefNode.declare_pyfunction:", self.name, "in", env ###
2211 entry = env.lookup_here(name)
2212 if entry and entry.type.is_cfunction and not self.is_wrapper:
2213 warning(self.pos, "Overriding cdef method with def method.", 5)
2214 entry = env.declare_pyfunction(name, self.pos, allow_redefine=not self.is_wrapper)
2216 prefix = env.next_id(env.scope_prefix)
2218 entry.func_cname = \
2219 Naming.pyfunc_prefix + prefix + name
2220 entry.pymethdef_cname = \
2221 Naming.pymethdef_prefix + prefix + name
2222 if Options.docstrings:
2223 entry.doc = embed_position(self.pos, self.doc)
2225 Naming.funcdoc_prefix + prefix + name
2226 if entry.is_special:
2227 if entry.name in TypeSlots.invisible or not entry.doc or (entry.name in '__getattr__' and env.directives['fast_getattr']):
2228 entry.wrapperbase_cname = None
2230 entry.wrapperbase_cname = Naming.wrapperbase_prefix + prefix + name
2234 def declare_lambda_function(self, env):
2235 entry = env.declare_lambda_function(self.lambda_name, self.pos)
2239 def declare_arguments(self, env):
2240 for arg in self.args:
2242 error(arg.pos, "Missing argument name")
2244 env.control_flow.set_state((), (arg.name, 'source'), 'arg')
2245 env.control_flow.set_state((), (arg.name, 'initialized'), True)
2246 if arg.needs_conversion:
2247 arg.entry = env.declare_var(arg.name, arg.type, arg.pos)
2248 if arg.type.is_pyobject:
2249 arg.entry.init = "0"
2250 arg.entry.init_to_none = 0
2252 arg.entry = self.declare_argument(env, arg)
2254 arg.entry.is_self_arg = arg.is_self_arg
2256 if arg.is_self_arg or arg.is_type_arg or \
2257 (arg.type.is_extension_type and not arg.hdr_type.is_extension_type):
2258 arg.entry.is_declared_generic = 1
2259 self.declare_python_arg(env, self.star_arg)
2260 self.declare_python_arg(env, self.starstar_arg)
2262 def declare_python_arg(self, env, arg):
2264 if env.directives['infer_types'] != False:
2265 type = PyrexTypes.unspecified_type
2267 type = py_object_type
2268 entry = env.declare_var(arg.name, type, arg.pos)
2271 entry.init_to_none = 0
2272 entry.xdecref_cleanup = 1
2274 env.control_flow.set_state((), (arg.name, 'initialized'), True)
2276 def analyse_expressions(self, env):
2277 self.local_scope.directives = env.directives
2278 self.analyse_default_values(env)
2279 if self.needs_assignment_synthesis(env):
2280 # Shouldn't we be doing this at the module level too?
2281 self.synthesize_assignment_node(env)
2283 def needs_assignment_synthesis(self, env, code=None):
2284 if self.no_assignment_synthesis:
2286 # Should enable for module level as well, that will require more testing...
2287 if self.entry.is_anonymous:
2289 if env.is_module_scope:
2291 return env.directives['binding']
2293 return code.globalstate.directives['binding']
2294 return env.is_py_class_scope or env.is_closure_scope
2296 def synthesize_assignment_node(self, env):
2299 while genv.is_py_class_scope or genv.is_c_class_scope:
2300 genv = genv.outer_scope
2302 if genv.is_closure_scope:
2303 rhs = ExprNodes.InnerFunctionNode(
2304 self.pos, pymethdef_cname = self.entry.pymethdef_cname)
2306 rhs = ExprNodes.PyCFunctionNode(
2307 self.pos, pymethdef_cname = self.entry.pymethdef_cname, binding = env.directives['binding'])
2309 if env.is_py_class_scope:
2310 if not self.is_staticmethod and not self.is_classmethod:
2313 self.assmt = SingleAssignmentNode(self.pos,
2314 lhs = ExprNodes.NameNode(self.pos, name = self.name),
2316 self.assmt.analyse_declarations(env)
2317 self.assmt.analyse_expressions(env)
2319 def generate_function_header(self, code, with_pymethdef, proto_only=0):
2321 sig = self.entry.signature
2322 if sig.has_dummy_arg or self.self_in_stararg:
2323 arg_code_list.append(
2324 "PyObject *%s" % Naming.self_cname)
2325 for arg in self.args:
2326 if not arg.is_generic:
2327 if arg.is_self_arg or arg.is_type_arg:
2328 arg_code_list.append("PyObject *%s" % arg.hdr_cname)
2330 arg_code_list.append(
2331 arg.hdr_type.declaration_code(arg.hdr_cname))
2332 if not self.entry.is_special and sig.method_flags() == [TypeSlots.method_noargs]:
2333 arg_code_list.append("CYTHON_UNUSED PyObject *unused")
2334 if (self.entry.scope.is_c_class_scope and self.entry.name == "__ipow__"):
2335 arg_code_list.append("CYTHON_UNUSED PyObject *unused")
2336 if sig.has_generic_args:
2337 arg_code_list.append(
2338 "PyObject *%s, PyObject *%s"
2339 % (Naming.args_cname, Naming.kwds_cname))
2340 arg_code = ", ".join(arg_code_list)
2341 dc = self.return_type.declaration_code(self.entry.func_cname)
2342 mf = " ".join(self.modifiers).upper()
2344 header = "static %s%s(%s)" % (mf, dc, arg_code)
2345 code.putln("%s; /*proto*/" % header)
2348 if (Options.docstrings and self.entry.doc and
2349 not self.entry.scope.is_property_scope and
2350 (not self.entry.is_special or self.entry.wrapperbase_cname)):
2351 docstr = self.entry.doc
2352 if docstr.is_unicode:
2353 docstr = docstr.utf8encode()
2355 'static char %s[] = "%s";' % (
2356 self.entry.doc_cname,
2357 split_string_literal(escape_byte_string(docstr))))
2358 if self.entry.is_special:
2360 "struct wrapperbase %s;" % self.entry.wrapperbase_cname)
2363 "static PyMethodDef %s = " %
2364 self.entry.pymethdef_cname)
2365 code.put_pymethoddef(self.entry, ";", allow_skip=False)
2366 code.putln("%s {" % header)
2368 def generate_argument_declarations(self, env, code):
2369 for arg in self.args:
2370 if arg.is_generic: # or arg.needs_conversion:
2371 if arg.needs_conversion:
2372 code.putln("PyObject *%s = 0;" % arg.hdr_cname)
2373 elif not arg.entry.in_closure:
2374 code.put_var_declaration(arg.entry)
2376 def generate_keyword_list(self, code):
2377 if self.signature_has_generic_args() and \
2378 self.signature_has_nongeneric_args():
2380 "static PyObject **%s[] = {" %
2381 Naming.pykwdlist_cname)
2382 for arg in self.args:
2384 pystring_cname = code.intern_identifier(arg.name)
2385 code.put('&%s,' % pystring_cname)
2388 def generate_argument_parsing_code(self, env, code):
2389 # Generate fast equivalent of PyArg_ParseTuple call for
2390 # generic arguments, if any, including args/kwargs
2391 if self.entry.signature.has_dummy_arg and not self.self_in_stararg:
2392 # get rid of unused argument warning
2393 code.putln("%s = %s;" % (Naming.self_cname, Naming.self_cname))
2395 old_error_label = code.new_error_label()
2396 our_error_label = code.error_label
2397 end_label = code.new_label("argument_unpacking_done")
2399 has_kwonly_args = self.num_kwonly_args > 0
2400 has_star_or_kw_args = self.star_arg is not None \
2401 or self.starstar_arg is not None or has_kwonly_args
2403 for arg in self.args:
2404 if not arg.type.is_pyobject:
2405 done = arg.type.create_from_py_utility_code(env)
2406 if not done: pass # will fail later
2408 if not self.signature_has_generic_args():
2409 if has_star_or_kw_args:
2410 error(self.pos, "This method cannot have * or keyword arguments")
2411 self.generate_argument_conversion_code(code)
2413 elif not self.signature_has_nongeneric_args():
2414 # func(*args) or func(**kw) or func(*args, **kw)
2415 self.generate_stararg_copy_code(code)
2418 positional_args = []
2420 for arg in self.args:
2421 arg_entry = arg.entry
2424 if not arg.is_self_arg and not arg.is_type_arg:
2426 kw_only_args.append(arg)
2428 positional_args.append(arg)
2430 kw_only_args.append(arg)
2431 elif not arg.is_self_arg and not arg.is_type_arg:
2432 positional_args.append(arg)
2434 self.generate_tuple_and_keyword_parsing_code(
2435 positional_args, kw_only_args, end_label, code)
2437 code.error_label = old_error_label
2438 if code.label_used(our_error_label):
2439 if not code.label_used(end_label):
2440 code.put_goto(end_label)
2441 code.put_label(our_error_label)
2442 if has_star_or_kw_args:
2443 self.generate_arg_decref(self.star_arg, code)
2444 if self.starstar_arg:
2445 if self.starstar_arg.entry.xdecref_cleanup:
2446 code.put_var_xdecref_clear(self.starstar_arg.entry)
2448 code.put_var_decref_clear(self.starstar_arg.entry)
2449 code.putln('__Pyx_AddTraceback("%s");' % self.entry.qualified_name)
2450 # The arguments are put into the closure one after the
2451 # other, so when type errors are found, all references in
2452 # the closure instance must be properly ref-counted to
2453 # facilitate generic closure instance deallocation. In
2454 # the case of an argument type error, it's best to just
2455 # DECREF+clear the already handled references, as this
2456 # frees their references as early as possible.
2457 for arg in self.args:
2458 if arg.type.is_pyobject and arg.entry.in_closure:
2459 code.put_var_xdecref_clear(arg.entry)
2460 if self.needs_closure:
2461 code.put_decref(Naming.cur_scope_cname, self.local_scope.scope_class.type)
2462 code.put_finish_refcount_context()
2463 code.putln("return %s;" % self.error_value())
2464 if code.label_used(end_label):
2465 code.put_label(end_label)
2467 # fix refnanny view on closure variables here, instead of
2468 # doing it separately for each arg parsing special case
2469 if self.star_arg and self.star_arg.entry.in_closure:
2470 code.put_var_giveref(self.star_arg.entry)
2471 if self.starstar_arg and self.starstar_arg.entry.in_closure:
2472 code.put_var_giveref(self.starstar_arg.entry)
2473 for arg in self.args:
2474 if arg.type.is_pyobject and arg.entry.in_closure:
2475 code.put_var_giveref(arg.entry)
2477 def generate_arg_assignment(self, arg, item, code):
2478 if arg.type.is_pyobject:
2480 item = PyrexTypes.typecast(arg.type, PyrexTypes.py_object_type, item)
2482 if entry.in_closure:
2483 code.put_incref(item, PyrexTypes.py_object_type)
2484 code.putln("%s = %s;" % (entry.cname, item))
2486 func = arg.type.from_py_function
2488 code.putln("%s = %s(%s); %s" % (
2492 code.error_goto_if(arg.type.error_condition(arg.entry.cname), arg.pos)))
2494 error(arg.pos, "Cannot convert Python object argument to type '%s'" % arg.type)
2496 def generate_arg_xdecref(self, arg, code):
2498 code.put_var_xdecref_clear(arg.entry)
2500 def generate_arg_decref(self, arg, code):
2502 code.put_var_decref_clear(arg.entry)
2504 def generate_stararg_copy_code(self, code):
2505 if not self.star_arg:
2506 code.globalstate.use_utility_code(raise_argtuple_invalid_utility_code)
2507 code.putln("if (unlikely(PyTuple_GET_SIZE(%s) > 0)) {" %
2509 code.put('__Pyx_RaiseArgtupleInvalid("%s", 1, 0, 0, PyTuple_GET_SIZE(%s)); return %s;' % (
2510 self.name, Naming.args_cname, self.error_value()))
2513 if self.starstar_arg:
2515 kwarg_check = "unlikely(%s)" % Naming.kwds_cname
2517 kwarg_check = "%s" % Naming.kwds_cname
2519 kwarg_check = "unlikely(%s) && unlikely(PyDict_Size(%s) > 0)" % (
2520 Naming.kwds_cname, Naming.kwds_cname)
2521 code.globalstate.use_utility_code(keyword_string_check_utility_code)
2523 "if (%s && unlikely(!__Pyx_CheckKeywordStrings(%s, \"%s\", %d))) return %s;" % (
2524 kwarg_check, Naming.kwds_cname, self.name,
2525 bool(self.starstar_arg), self.error_value()))
2527 if self.starstar_arg:
2528 code.putln("%s = (%s) ? PyDict_Copy(%s) : PyDict_New();" % (
2529 self.starstar_arg.entry.cname,
2532 code.putln("if (unlikely(!%s)) return %s;" % (
2533 self.starstar_arg.entry.cname, self.error_value()))
2534 self.starstar_arg.entry.xdecref_cleanup = 0
2535 code.put_gotref(self.starstar_arg.entry.cname)
2537 if self.self_in_stararg:
2538 # need to create a new tuple with 'self' inserted as first item
2539 code.put("%s = PyTuple_New(PyTuple_GET_SIZE(%s)+1); if (unlikely(!%s)) " % (
2540 self.star_arg.entry.cname,
2542 self.star_arg.entry.cname))
2543 if self.starstar_arg:
2545 code.put_decref_clear(self.starstar_arg.entry.cname, py_object_type)
2546 code.putln("return %s;" % self.error_value())
2549 code.putln("return %s;" % self.error_value())
2550 code.put_gotref(self.star_arg.entry.cname)
2551 code.put_incref(Naming.self_cname, py_object_type)
2552 code.put_giveref(Naming.self_cname)
2553 code.putln("PyTuple_SET_ITEM(%s, 0, %s);" % (
2554 self.star_arg.entry.cname, Naming.self_cname))
2555 temp = code.funcstate.allocate_temp(PyrexTypes.c_py_ssize_t_type, manage_ref=False)
2556 code.putln("for (%s=0; %s < PyTuple_GET_SIZE(%s); %s++) {" % (
2557 temp, temp, Naming.args_cname, temp))
2558 code.putln("PyObject* item = PyTuple_GET_ITEM(%s, %s);" % (
2559 Naming.args_cname, temp))
2560 code.put_incref("item", py_object_type)
2561 code.put_giveref("item")
2562 code.putln("PyTuple_SET_ITEM(%s, %s+1, item);" % (
2563 self.star_arg.entry.cname, temp))
2565 code.funcstate.release_temp(temp)
2566 self.star_arg.entry.xdecref_cleanup = 0
2568 code.put_incref(Naming.args_cname, py_object_type)
2569 code.putln("%s = %s;" % (
2570 self.star_arg.entry.cname,
2572 self.star_arg.entry.xdecref_cleanup = 0
2574 def generate_tuple_and_keyword_parsing_code(self, positional_args,
2575 kw_only_args, success_label, code):
2576 argtuple_error_label = code.new_label("argtuple_error")
2578 min_positional_args = self.num_required_args - self.num_required_kw_args
2579 if len(self.args) > 0 and (self.args[0].is_self_arg or self.args[0].is_type_arg):
2580 min_positional_args -= 1
2581 max_positional_args = len(positional_args)
2582 has_fixed_positional_count = not self.star_arg and \
2583 min_positional_args == max_positional_args
2585 if self.num_required_kw_args:
2586 code.globalstate.use_utility_code(raise_keyword_required_utility_code)
2588 if self.starstar_arg or self.star_arg:
2589 self.generate_stararg_init_code(max_positional_args, code)
2591 # --- optimised code when we receive keyword arguments
2592 if self.num_required_kw_args:
2593 likely_hint = "likely"
2595 likely_hint = "unlikely"
2596 code.putln("if (%s(%s)) {" % (likely_hint, Naming.kwds_cname))
2597 self.generate_keyword_unpacking_code(
2598 min_positional_args, max_positional_args,
2599 has_fixed_positional_count,
2600 positional_args, kw_only_args, argtuple_error_label, code)
2602 # --- optimised code when we do not receive any keyword arguments
2603 if (self.num_required_kw_args and min_positional_args > 0) or min_positional_args == max_positional_args:
2604 # Python raises arg tuple related errors first, so we must
2605 # check the length here
2606 if min_positional_args == max_positional_args and not self.star_arg:
2610 code.putln('} else if (PyTuple_GET_SIZE(%s) %s %d) {' % (
2611 Naming.args_cname, compare, min_positional_args))
2612 code.put_goto(argtuple_error_label)
2614 if self.num_required_kw_args:
2615 # pure error case: keywords required but not passed
2616 if max_positional_args > min_positional_args and not self.star_arg:
2617 code.putln('} else if (PyTuple_GET_SIZE(%s) > %d) {' % (
2618 Naming.args_cname, max_positional_args))
2619 code.put_goto(argtuple_error_label)
2620 code.putln('} else {')
2621 for i, arg in enumerate(kw_only_args):
2623 pystring_cname = code.intern_identifier(arg.name)
2624 # required keyword-only argument missing
2625 code.put('__Pyx_RaiseKeywordRequired("%s", %s); ' % (
2628 code.putln(code.error_goto(self.pos))
2631 elif min_positional_args == max_positional_args:
2632 # parse the exact number of positional arguments from the
2634 code.putln('} else {')
2635 for i, arg in enumerate(positional_args):
2636 item = "PyTuple_GET_ITEM(%s, %d)" % (Naming.args_cname, i)
2637 self.generate_arg_assignment(arg, item, code)
2638 self.generate_arg_default_assignments(code)
2641 # parse the positional arguments from the variable length
2643 code.putln('} else {')
2644 self.generate_arg_default_assignments(code)
2645 code.putln('switch (PyTuple_GET_SIZE(%s)) {' % Naming.args_cname)
2647 code.putln('default:')
2648 reversed_args = list(enumerate(positional_args))[::-1]
2649 for i, arg in reversed_args:
2650 if i >= min_positional_args-1:
2651 if min_positional_args > 1:
2652 code.putln('case %2d:' % (i+1)) # pure code beautification
2654 code.put('case %2d: ' % (i+1))
2655 item = "PyTuple_GET_ITEM(%s, %d)" % (Naming.args_cname, i)
2656 self.generate_arg_assignment(arg, item, code)
2657 if min_positional_args == 0:
2658 code.put('case 0: ')
2659 code.putln('break;')
2661 if min_positional_args:
2662 for i in range(min_positional_args-1, -1, -1):
2663 code.putln('case %2d:' % i)
2664 code.put_goto(argtuple_error_label)
2666 code.put('default: ')
2667 code.put_goto(argtuple_error_label)
2672 if code.label_used(argtuple_error_label):
2673 code.put_goto(success_label)
2674 code.put_label(argtuple_error_label)
2675 code.globalstate.use_utility_code(raise_argtuple_invalid_utility_code)
2676 code.put('__Pyx_RaiseArgtupleInvalid("%s", %d, %d, %d, PyTuple_GET_SIZE(%s)); ' % (
2677 self.name, has_fixed_positional_count,
2678 min_positional_args, max_positional_args,
2680 code.putln(code.error_goto(self.pos))
2682 def generate_arg_default_assignments(self, code):
2683 for arg in self.args:
2684 if arg.is_generic and arg.default:
2688 arg.calculate_default_value_code(code)))
2690 def generate_stararg_init_code(self, max_positional_args, code):
2691 if self.starstar_arg:
2692 self.starstar_arg.entry.xdecref_cleanup = 0
2693 code.putln('%s = PyDict_New(); if (unlikely(!%s)) return %s;' % (
2694 self.starstar_arg.entry.cname,
2695 self.starstar_arg.entry.cname,
2696 self.error_value()))
2697 code.put_gotref(self.starstar_arg.entry.cname)
2699 self.star_arg.entry.xdecref_cleanup = 0
2700 code.putln('if (PyTuple_GET_SIZE(%s) > %d) {' % (
2702 max_positional_args))
2703 code.putln('%s = PyTuple_GetSlice(%s, %d, PyTuple_GET_SIZE(%s));' % (
2704 self.star_arg.entry.cname, Naming.args_cname,
2705 max_positional_args, Naming.args_cname))
2706 code.putln("if (unlikely(!%s)) {" % self.star_arg.entry.cname)
2707 if self.starstar_arg:
2708 code.put_decref_clear(self.starstar_arg.entry.cname, py_object_type)
2709 if self.needs_closure:
2710 code.put_decref(Naming.cur_scope_cname, self.local_scope.scope_class.type)
2711 code.put_finish_refcount_context()
2712 code.putln('return %s;' % self.error_value())
2714 code.put_gotref(self.star_arg.entry.cname)
2715 code.putln('} else {')
2716 code.put("%s = %s; " % (self.star_arg.entry.cname, Naming.empty_tuple))
2717 code.put_incref(Naming.empty_tuple, py_object_type)
2720 def generate_keyword_unpacking_code(self, min_positional_args, max_positional_args,
2721 has_fixed_positional_count, positional_args,
2722 kw_only_args, argtuple_error_label, code):
2723 all_args = tuple(positional_args) + tuple(kw_only_args)
2724 max_args = len(all_args)
2726 code.putln("Py_ssize_t kw_args = PyDict_Size(%s);" %
2728 # the 'values' array collects borrowed references to arguments
2729 # before doing any type coercion etc.
2730 code.putln("PyObject* values[%d] = {%s};" % (
2731 max_args, ','.join('0'*max_args)))
2733 # assign borrowed Python default values to the values array,
2734 # so that they can be overwritten by received arguments below
2735 for i, arg in enumerate(all_args):
2736 if arg.default and arg.type.is_pyobject:
2737 default_value = arg.calculate_default_value_code(code)
2738 code.putln('values[%d] = %s;' % (i, arg.type.as_pyobject(default_value)))
2740 # parse the args tuple and check that it's not too long
2741 code.putln('switch (PyTuple_GET_SIZE(%s)) {' % Naming.args_cname)
2743 code.putln('default:')
2744 for i in range(max_positional_args-1, -1, -1):
2745 code.put('case %2d: ' % (i+1))
2746 code.putln("values[%d] = PyTuple_GET_ITEM(%s, %d);" % (
2747 i, Naming.args_cname, i))
2748 code.putln('case 0: break;')
2749 if not self.star_arg:
2750 code.put('default: ') # more arguments than allowed
2751 code.put_goto(argtuple_error_label)
2754 # now fill up the positional/required arguments with values
2756 if self.num_required_args or max_positional_args > 0:
2757 last_required_arg = -1
2758 for i, arg in enumerate(all_args):
2760 last_required_arg = i
2761 if last_required_arg < max_positional_args:
2762 last_required_arg = max_positional_args-1
2763 num_required_args = self.num_required_args
2764 if max_positional_args > 0:
2765 code.putln('switch (PyTuple_GET_SIZE(%s)) {' % Naming.args_cname)
2766 for i, arg in enumerate(all_args[:last_required_arg+1]):
2767 if max_positional_args > 0 and i <= max_positional_args:
2768 if self.star_arg and i == max_positional_args:
2769 code.putln('default:')
2771 code.putln('case %2d:' % i)
2772 pystring_cname = code.intern_identifier(arg.name)
2775 # handled separately below
2777 code.putln('if (kw_args > 0) {')
2778 code.putln('PyObject* value = PyDict_GetItem(%s, %s);' % (
2779 Naming.kwds_cname, pystring_cname))
2780 code.putln('if (value) { values[%d] = value; kw_args--; }' % i)
2783 num_required_args -= 1
2784 code.putln('values[%d] = PyDict_GetItem(%s, %s);' % (
2785 i, Naming.kwds_cname, pystring_cname))
2786 code.putln('if (likely(values[%d])) kw_args--;' % i);
2787 if i < min_positional_args:
2789 # special case: we know arg 0 is missing
2791 code.put_goto(argtuple_error_label)
2793 # print the correct number of values (args or
2794 # kwargs) that were passed into positional
2795 # arguments up to this point
2796 code.putln('else {')
2797 code.globalstate.use_utility_code(raise_argtuple_invalid_utility_code)
2798 code.put('__Pyx_RaiseArgtupleInvalid("%s", %d, %d, %d, %d); ' % (
2799 self.name, has_fixed_positional_count,
2800 min_positional_args, max_positional_args, i))
2801 code.putln(code.error_goto(self.pos))
2804 code.putln('else {')
2805 code.put('__Pyx_RaiseKeywordRequired("%s", %s); ' %(
2806 self.name, pystring_cname))
2807 code.putln(code.error_goto(self.pos))
2809 if max_positional_args > 0:
2812 if kw_only_args and not self.starstar_arg:
2813 # unpack optional keyword-only arguments
2814 # checking for interned strings in a dict is faster than iterating
2815 # but it's too likely that we must iterate if we expect **kwargs
2817 for i, arg in enumerate(all_args[max_positional_args:]):
2818 if not arg.kw_only or not arg.default:
2820 optional_args.append((i+max_positional_args, arg))
2822 # this mimics an unrolled loop so that we can "break" out of it
2823 code.putln('while (kw_args > 0) {')
2824 code.putln('PyObject* value;')
2825 for i, arg in optional_args:
2826 pystring_cname = code.intern_identifier(arg.name)
2828 'value = PyDict_GetItem(%s, %s);' % (
2829 Naming.kwds_cname, pystring_cname))
2831 'if (value) { values[%d] = value; if (!(--kw_args)) break; }' % i)
2832 code.putln('break;')
2835 code.putln('if (unlikely(kw_args > 0)) {')
2836 # non-positional/-required kw args left in dict: default args,
2837 # kw-only args, **kwargs or error
2839 # This is sort of a catch-all: except for checking required
2840 # arguments, this will always do the right thing for unpacking
2841 # keyword arguments, so that we can concentrate on optimising
2842 # common cases above.
2843 if max_positional_args == 0:
2846 code.putln("const Py_ssize_t used_pos_args = (PyTuple_GET_SIZE(%s) < %d) ? PyTuple_GET_SIZE(%s) : %d;" % (
2847 Naming.args_cname, max_positional_args,
2848 Naming.args_cname, max_positional_args))
2849 pos_arg_count = "used_pos_args"
2851 pos_arg_count = "PyTuple_GET_SIZE(%s)" % Naming.args_cname
2852 code.globalstate.use_utility_code(parse_keywords_utility_code)
2854 'if (unlikely(__Pyx_ParseOptionalKeywords(%s, %s, %s, values, %s, "%s") < 0)) ' % (
2856 Naming.pykwdlist_cname,
2857 self.starstar_arg and self.starstar_arg.entry.cname or '0',
2860 code.putln(code.error_goto(self.pos))
2863 # convert arg values to their final type and assign them
2864 for i, arg in enumerate(all_args):
2865 if arg.default and not arg.type.is_pyobject:
2866 code.putln("if (values[%d]) {" % i)
2867 self.generate_arg_assignment(arg, "values[%d]" % i, code)
2868 if arg.default and not arg.type.is_pyobject:
2869 code.putln('} else {')
2873 arg.calculate_default_value_code(code)))
2876 def generate_argument_conversion_code(self, code):
2877 # Generate code to convert arguments from signature type to
2878 # declared type, if needed. Also copies signature arguments
2879 # into closure fields.
2880 for arg in self.args:
2881 if arg.needs_conversion:
2882 self.generate_arg_conversion(arg, code)
2883 elif arg.entry.in_closure:
2884 if arg.type.is_pyobject:
2885 code.put_incref(arg.hdr_cname, py_object_type)
2886 code.putln('%s = %s;' % (arg.entry.cname, arg.hdr_cname))
2888 def generate_arg_conversion(self, arg, code):
2889 # Generate conversion code for one argument.
2890 old_type = arg.hdr_type
2892 if old_type.is_pyobject:
2894 code.putln("if (%s) {" % arg.hdr_cname)
2896 code.putln("assert(%s); {" % arg.hdr_cname)
2897 self.generate_arg_conversion_from_pyobject(arg, code)
2899 elif new_type.is_pyobject:
2900 self.generate_arg_conversion_to_pyobject(arg, code)
2902 if new_type.assignable_from(old_type):
2904 "%s = %s;" % (arg.entry.cname, arg.hdr_cname))
2907 "Cannot convert 1 argument from '%s' to '%s'" %
2908 (old_type, new_type))
2910 def generate_arg_conversion_from_pyobject(self, arg, code):
2912 func = new_type.from_py_function
2913 # copied from CoerceFromPyTypeNode
2915 lhs = arg.entry.cname
2916 rhs = "%s(%s)" % (func, arg.hdr_cname)
2917 if new_type.is_enum:
2918 rhs = PyrexTypes.typecast(new_type, PyrexTypes.c_long_type, rhs)
2919 code.putln("%s = %s; %s" % (
2922 code.error_goto_if(new_type.error_condition(arg.entry.cname), arg.pos)))
2925 "Cannot convert Python object argument to type '%s'"
2928 def generate_arg_conversion_to_pyobject(self, arg, code):
2929 old_type = arg.hdr_type
2930 func = old_type.to_py_function
2932 code.putln("%s = %s(%s); %s" % (
2936 code.error_goto_if_null(arg.entry.cname, arg.pos)))
2937 code.put_var_gotref(arg.entry)
2940 "Cannot convert argument of type '%s' to Python object"
2943 def generate_argument_type_tests(self, code):
2944 # Generate type tests for args whose signature
2945 # type is PyObject * and whose declared type is
2946 # a subtype thereof.
2947 for arg in self.args:
2948 if arg.needs_type_test:
2949 self.generate_arg_type_test(arg, code)
2950 elif not arg.accept_none and arg.type.is_pyobject:
2951 self.generate_arg_none_check(arg, code)
2953 def error_value(self):
2954 return self.entry.signature.error_value
2956 def caller_will_check_exceptions(self):
2960 class GeneratorDefNode(DefNode):
2961 # Generator DefNode.
2963 # gbody GeneratorBodyDefNode
2967 needs_closure = True
2969 child_attrs = DefNode.child_attrs + ["gbody"]
2971 def __init__(self, **kwargs):
2972 # XXX: don't actually needs a body
2973 kwargs['body'] = StatListNode(kwargs['pos'], stats=[])
2974 super(GeneratorDefNode, self).__init__(**kwargs)
2976 def analyse_declarations(self, env):
2977 super(GeneratorDefNode, self).analyse_declarations(env)
2978 self.gbody.local_scope = self.local_scope
2979 self.gbody.analyse_declarations(env)
2981 def generate_function_body(self, env, code):
2982 body_cname = self.gbody.entry.func_cname
2983 generator_cname = '%s->%s' % (Naming.cur_scope_cname, Naming.obj_base_cname)
2985 code.putln('%s.resume_label = 0;' % generator_cname)
2986 code.putln('%s.body = (__pyx_generator_body_t) %s;' % (generator_cname, body_cname))
2987 code.put_giveref(Naming.cur_scope_cname)
2988 code.put_finish_refcount_context()
2989 code.putln("return (PyObject *) %s;" % Naming.cur_scope_cname);
2991 def generate_function_definitions(self, env, code):
2992 self.gbody.generate_function_header(code, proto=True)
2993 super(GeneratorDefNode, self).generate_function_definitions(env, code)
2994 self.gbody.generate_function_definitions(env, code)
2997 class GeneratorBodyDefNode(DefNode):
2998 # Generator body DefNode.
3001 is_generator_body = True
3003 def __init__(self, pos=None, name=None, body=None):
3004 super(GeneratorBodyDefNode, self).__init__(pos=pos, body=body, name=name, doc=None,
3006 star_arg=None, starstar_arg=None)
3008 def declare_generator_body(self, env):
3009 prefix = env.next_id(env.scope_prefix)
3010 name = env.next_id('generator')
3011 entry = env.declare_var(prefix + name, py_object_type, self.pos, visibility='private')
3012 entry.func_cname = Naming.genbody_prefix + prefix + name
3013 entry.qualified_name = EncodedString(self.name)
3016 def analyse_declarations(self, env):
3017 self.analyse_argument_types(env)
3018 self.declare_generator_body(env)
3020 def generate_function_header(self, code, proto=False):
3021 header = "static PyObject *%s(%s, PyObject *%s)" % (
3022 self.entry.func_cname,
3023 self.local_scope.scope_class.type.declaration_code(Naming.cur_scope_cname),
3024 Naming.sent_value_cname)
3026 code.putln('%s; /* proto */' % header)
3028 code.putln('%s /* generator body */\n{' % header);
3030 def generate_function_definitions(self, env, code):
3031 lenv = self.local_scope
3033 # Generate closure function definitions
3034 self.body.generate_function_definitions(lenv, code)
3036 # Generate C code for header and body of function
3037 code.enter_cfunc_scope()
3038 code.return_from_error_cleanup_label = code.new_label()
3040 # ----- Top-level constants used by this function
3041 code.mark_pos(self.pos)
3042 self.generate_cached_builtins_decls(lenv, code)
3043 # ----- Function header
3045 self.generate_function_header(code)
3046 # ----- Local variables
3047 code.putln("PyObject *%s = NULL;" % Naming.retval_cname)
3048 tempvardecl_code = code.insertion_point()
3049 code.put_declare_refcount_context()
3050 code.put_setup_refcount_context(self.entry.name)
3052 # ----- Resume switch point.
3053 code.funcstate.init_closure_temps(lenv.scope_class.type.scope)
3054 resume_code = code.insertion_point()
3055 first_run_label = code.new_label('first_run')
3056 code.use_label(first_run_label)
3057 code.put_label(first_run_label)
3059 (code.error_goto_if_null(Naming.sent_value_cname, self.pos)))
3061 # ----- Function body
3062 self.generate_function_body(env, code)
3063 code.putln('PyErr_SetNone(PyExc_StopIteration); %s' % code.error_goto(self.pos))
3064 # ----- Error cleanup
3065 if code.error_label in code.labels_used:
3066 code.put_goto(code.return_label)
3067 code.put_label(code.error_label)
3068 for cname, type in code.funcstate.all_managed_temps():
3069 code.put_xdecref(cname, type)
3070 code.putln('__Pyx_AddTraceback("%s");' % self.entry.qualified_name)
3072 # ----- Non-error return cleanup
3073 code.put_label(code.return_label)
3074 code.put_xdecref(Naming.retval_cname, py_object_type)
3075 code.putln('%s->%s.resume_label = -1;' % (Naming.cur_scope_cname, Naming.obj_base_cname))
3076 code.put_finish_refcount_context()
3077 code.putln('return NULL;');
3080 # ----- Go back and insert temp variable declarations
3081 tempvardecl_code.put_temp_declarations(code.funcstate)
3082 # ----- Generator resume code
3083 resume_code.putln("switch (%s->%s.resume_label) {" % (Naming.cur_scope_cname, Naming.obj_base_cname));
3084 resume_code.putln("case 0: goto %s;" % first_run_label)
3086 from ParseTreeTransforms import YieldNodeCollector
3087 collector = YieldNodeCollector()
3088 collector.visitchildren(self)
3089 for yield_expr in collector.yields:
3090 resume_code.putln("case %d: goto %s;" % (yield_expr.label_num, yield_expr.label_name));
3091 resume_code.putln("default: /* CPython raises the right error here */");
3092 resume_code.put_finish_refcount_context()
3093 resume_code.putln("return NULL;");
3094 resume_code.putln("}");
3096 code.exit_cfunc_scope()
3099 class OverrideCheckNode(StatNode):
3100 # A Node for dispatching to the def method if it
3109 child_attrs = ['body']
3113 def analyse_expressions(self, env):
3114 self.args = env.arg_entries
3115 if self.py_func.is_module_scope:
3120 self.func_node = ExprNodes.RawCNameExprNode(self.pos, py_object_type)
3121 call_tuple = ExprNodes.TupleNode(self.pos, args=[ExprNodes.NameNode(self.pos, name=arg.name) for arg in self.args[first_arg:]])
3122 call_node = ExprNodes.SimpleCallNode(self.pos,
3123 function=self.func_node,
3124 args=[ExprNodes.NameNode(self.pos, name=arg.name) for arg in self.args[first_arg:]])
3125 self.body = ReturnStatNode(self.pos, value=call_node)
3126 self.body.analyse_expressions(env)
3128 def generate_execution_code(self, code):
3129 interned_attr_cname = code.intern_identifier(self.py_func.entry.name)
3130 # Check to see if we are an extension type
3131 if self.py_func.is_module_scope:
3132 self_arg = "((PyObject *)%s)" % Naming.module_cname
3134 self_arg = "((PyObject *)%s)" % self.args[0].cname
3135 code.putln("/* Check if called by wrapper */")
3136 code.putln("if (unlikely(%s)) ;" % Naming.skip_dispatch_cname)
3137 code.putln("/* Check if overriden in Python */")
3138 if self.py_func.is_module_scope:
3139 code.putln("else {")
3141 code.putln("else if (unlikely(Py_TYPE(%s)->tp_dictoffset != 0)) {" % self_arg)
3142 func_node_temp = code.funcstate.allocate_temp(py_object_type, manage_ref=True)
3143 self.func_node.set_cname(func_node_temp)
3144 # need to get attribute manually--scope would return cdef method
3145 err = code.error_goto_if_null(func_node_temp, self.pos)
3146 code.putln("%s = PyObject_GetAttr(%s, %s); %s" % (
3147 func_node_temp, self_arg, interned_attr_cname, err))
3148 code.put_gotref(func_node_temp)
3149 is_builtin_function_or_method = "PyCFunction_Check(%s)" % func_node_temp
3150 is_overridden = "(PyCFunction_GET_FUNCTION(%s) != (void *)&%s)" % (
3151 func_node_temp, self.py_func.entry.func_cname)
3152 code.putln("if (!%s || %s) {" % (is_builtin_function_or_method, is_overridden))
3153 self.body.generate_execution_code(code)
3155 code.put_decref_clear(func_node_temp, PyrexTypes.py_object_type)
3156 code.funcstate.release_temp(func_node_temp)
3159 class ClassDefNode(StatNode, BlockNode):
3162 class PyClassDefNode(ClassDefNode):
3163 # A Python class definition.
3165 # name EncodedString Name of the class
3166 # doc string or None
3167 # body StatNode Attribute definition code
3168 # entry Symtab.Entry
3169 # scope PyClassScope
3170 # decorators [DecoratorNode] list of decorators or None
3172 # The following subnodes are constructed internally:
3174 # dict DictNode Class dictionary or Py3 namespace
3175 # classobj ClassNode Class object
3176 # target NameNode Variable to assign class object to
3178 child_attrs = ["body", "dict", "metaclass", "mkw", "bases", "classobj", "target"]
3180 py3_style_class = False # Python3 style class (bases+kwargs)
3182 def __init__(self, pos, name, bases, doc, body, decorators = None,
3183 keyword_args = None, starstar_arg = None):
3184 StatNode.__init__(self, pos)
3188 self.decorators = decorators
3190 if self.doc and Options.docstrings:
3191 doc = embed_position(self.pos, self.doc)
3192 doc_node = ExprNodes.StringNode(pos, value = doc)
3195 if keyword_args or starstar_arg:
3196 self.py3_style_class = True
3198 self.metaclass = None
3199 if keyword_args and not starstar_arg:
3200 for i, item in list(enumerate(keyword_args.key_value_pairs))[::-1]:
3201 if item.key.value == 'metaclass':
3202 if self.metaclass is not None:
3203 error(item.pos, "keyword argument 'metaclass' passed multiple times")
3204 # special case: we already know the metaclass,
3205 # so we don't need to do the "build kwargs,
3206 # find metaclass" dance at runtime
3207 self.metaclass = item.value
3208 del keyword_args.key_value_pairs[i]
3209 if starstar_arg or (keyword_args and keyword_args.key_value_pairs):
3210 self.mkw = ExprNodes.KeywordArgsNode(
3211 pos, keyword_args = keyword_args, starstar_arg = starstar_arg)
3213 self.mkw = ExprNodes.NullNode(pos)
3214 if self.metaclass is None:
3215 self.metaclass = ExprNodes.PyClassMetaclassNode(
3216 pos, mkw = self.mkw, bases = self.bases)
3217 self.dict = ExprNodes.PyClassNamespaceNode(pos, name = name,
3218 doc = doc_node, metaclass = self.metaclass, bases = self.bases,
3220 self.classobj = ExprNodes.Py3ClassNode(pos, name = name,
3221 bases = self.bases, dict = self.dict, doc = doc_node,
3222 metaclass = self.metaclass, mkw = self.mkw)
3224 self.dict = ExprNodes.DictNode(pos, key_value_pairs = [])
3225 self.metaclass = None
3228 self.classobj = ExprNodes.ClassNode(pos, name = name,
3229 bases = bases, dict = self.dict, doc = doc_node)
3230 self.target = ExprNodes.NameNode(pos, name = name)
3232 def as_cclass(self):
3234 Return this node as if it were declared as an extension class
3236 if self.py3_style_class:
3237 error(self.classobj.pos, "Python3 style class could not be represented as C class")
3239 bases = self.classobj.bases.args
3241 base_class_name = None
3242 base_class_module = None
3243 elif len(bases) == 1:
3246 from ExprNodes import AttributeNode, NameNode
3247 while isinstance(base, AttributeNode):
3248 path.insert(0, base.attribute)
3250 if isinstance(base, NameNode):
3251 path.insert(0, base.name)
3252 base_class_name = path[-1]
3254 base_class_module = u'.'.join(path[:-1])
3256 base_class_module = None
3258 error(self.classobj.bases.args.pos, "Invalid base class")
3260 error(self.classobj.bases.args.pos, "C class may only have one base class")
3263 return CClassDefNode(self.pos,
3264 visibility = 'private',
3266 class_name = self.name,
3267 base_class_module = base_class_module,
3268 base_class_name = base_class_name,
3269 decorators = self.decorators,
3274 def create_scope(self, env):
3276 while genv.is_py_class_scope or genv.is_c_class_scope:
3277 genv = genv.outer_scope
3278 cenv = self.scope = PyClassScope(name = self.name, outer_scope = genv)
3281 def analyse_declarations(self, env):
3282 self.target.analyse_target_declaration(env)
3283 cenv = self.create_scope(env)
3284 cenv.directives = env.directives
3285 cenv.class_obj_cname = self.target.entry.cname
3286 self.body.analyse_declarations(cenv)
3288 def analyse_expressions(self, env):
3289 if self.py3_style_class:
3290 self.bases.analyse_expressions(env)
3291 self.metaclass.analyse_expressions(env)
3292 self.mkw.analyse_expressions(env)
3293 self.dict.analyse_expressions(env)
3294 self.classobj.analyse_expressions(env)
3295 genv = env.global_scope()
3297 self.body.analyse_expressions(cenv)
3298 self.target.analyse_target_expression(env, self.classobj)
3300 def generate_function_definitions(self, env, code):
3301 self.generate_lambda_definitions(self.scope, code)
3302 self.body.generate_function_definitions(self.scope, code)
3304 def generate_execution_code(self, code):
3305 code.pyclass_stack.append(self)
3307 if self.py3_style_class:
3308 self.bases.generate_evaluation_code(code)
3309 self.mkw.generate_evaluation_code(code)
3310 self.metaclass.generate_evaluation_code(code)
3311 self.dict.generate_evaluation_code(code)
3312 cenv.namespace_cname = cenv.class_obj_cname = self.dict.result()
3313 self.body.generate_execution_code(code)
3314 self.classobj.generate_evaluation_code(code)
3315 cenv.namespace_cname = cenv.class_obj_cname = self.classobj.result()
3316 self.target.generate_assignment_code(self.classobj, code)
3317 self.dict.generate_disposal_code(code)
3318 self.dict.free_temps(code)
3319 if self.py3_style_class:
3320 self.mkw.generate_disposal_code(code)
3321 self.mkw.free_temps(code)
3322 self.metaclass.generate_disposal_code(code)
3323 self.metaclass.free_temps(code)
3324 self.bases.generate_disposal_code(code)
3325 self.bases.free_temps(code)
3326 code.pyclass_stack.pop()
3328 class CClassDefNode(ClassDefNode):
3329 # An extension type definition.
3331 # visibility 'private' or 'public' or 'extern'
3332 # typedef_flag boolean
3334 # module_name string or None For import of extern type objects
3335 # class_name string Unqualified name of class
3336 # as_name string or None Name to declare as in this scope
3337 # base_class_module string or None Module containing the base class
3338 # base_class_name string or None Name of the base class
3339 # objstruct_name string or None Specified C name of object struct
3340 # typeobj_name string or None Specified C name of type object
3341 # in_pxd boolean Is in a .pxd file
3342 # decorators [DecoratorNode] list of decorators or None
3343 # doc string or None
3344 # body StatNode or None
3345 # entry Symtab.Entry
3346 # base_type PyExtensionType or None
3347 # buffer_defaults_node DictNode or None Declares defaults for a buffer
3348 # buffer_defaults_pos
3350 child_attrs = ["body"]
3351 buffer_defaults_node = None
3352 buffer_defaults_pos = None
3353 typedef_flag = False
3355 objstruct_name = None
3360 def analyse_declarations(self, env):
3361 #print "CClassDefNode.analyse_declarations:", self.class_name
3362 #print "...visibility =", self.visibility
3363 #print "...module_name =", self.module_name
3366 if self.buffer_defaults_node:
3367 buffer_defaults = Buffer.analyse_buffer_options(self.buffer_defaults_pos,
3368 env, [], self.buffer_defaults_node,
3369 need_complete=False)
3371 buffer_defaults = None
3373 if env.in_cinclude and not self.objstruct_name:
3374 error(self.pos, "Object struct name specification required for "
3375 "C class defined in 'extern from' block")
3376 self.base_type = None
3377 # Now that module imports are cached, we need to
3378 # import the modules for extern classes.
3379 if self.module_name:
3381 for module in env.cimported_modules:
3382 if module.name == self.module_name:
3383 self.module = module
3384 if self.module is None:
3385 self.module = ModuleScope(self.module_name, None, env.context)
3386 self.module.has_extern_class = 1
3387 env.add_imported_module(self.module)
3389 if self.base_class_name:
3390 if self.base_class_module:
3391 base_class_scope = env.find_module(self.base_class_module, self.pos)
3393 base_class_scope = env
3394 if self.base_class_name == 'object':
3395 # extension classes are special and don't need to inherit from object
3396 if base_class_scope is None or base_class_scope.lookup('object') is None:
3397 self.base_class_name = None
3398 self.base_class_module = None
3399 base_class_scope = None
3400 if base_class_scope:
3401 base_class_entry = base_class_scope.find(self.base_class_name, self.pos)
3402 if base_class_entry:
3403 if not base_class_entry.is_type:
3404 error(self.pos, "'%s' is not a type name" % self.base_class_name)
3405 elif not base_class_entry.type.is_extension_type and \
3406 not (base_class_entry.type.is_builtin_type and \
3407 base_class_entry.type.objstruct_cname):
3408 error(self.pos, "'%s' is not an extension type" % self.base_class_name)
3409 elif not base_class_entry.type.is_complete():
3410 error(self.pos, "Base class '%s' of type '%s' is incomplete" % (
3411 self.base_class_name, self.class_name))
3412 elif base_class_entry.type.scope and base_class_entry.type.scope.directives and \
3413 base_class_entry.type.scope.directives['final']:
3414 error(self.pos, "Base class '%s' of type '%s' is final" % (
3415 self.base_class_name, self.class_name))
3416 elif base_class_entry.type.is_builtin_type and \
3417 base_class_entry.type.name in ('tuple', 'str', 'bytes'):
3418 error(self.pos, "inheritance from PyVarObject types like '%s' is not currently supported"
3419 % base_class_entry.type.name)
3421 self.base_type = base_class_entry.type
3422 has_body = self.body is not None
3423 if self.module_name and self.visibility != 'extern':
3424 module_path = self.module_name.split(".")
3425 home_scope = env.find_imported_module(module_path, self.pos)
3431 if self.visibility == 'extern':
3432 if (self.module_name == '__builtin__' and
3433 self.class_name in Builtin.builtin_types and
3434 env.qualified_name[:8] != 'cpython.'): # allow overloaded names for cimporting from cpython
3435 warning(self.pos, "%s already a builtin Cython type" % self.class_name, 1)
3437 self.entry = home_scope.declare_c_class(
3438 name = self.class_name,
3440 defining = has_body and self.in_pxd,
3441 implementing = has_body and not self.in_pxd,
3442 module_name = self.module_name,
3443 base_type = self.base_type,
3444 objstruct_cname = self.objstruct_name,
3445 typeobj_cname = self.typeobj_name,
3446 visibility = self.visibility,
3447 typedef_flag = self.typedef_flag,
3449 buffer_defaults = buffer_defaults,
3450 shadow = self.shadow)
3452 home_scope.lookup(self.class_name).as_variable = self.entry
3453 if home_scope is not env and self.visibility == 'extern':
3454 env.add_imported_entry(self.class_name, self.entry, self.pos)
3455 self.scope = scope = self.entry.type.scope
3456 if scope is not None:
3457 scope.directives = env.directives
3459 if self.doc and Options.docstrings:
3460 scope.doc = embed_position(self.pos, self.doc)
3463 self.body.analyse_declarations(scope)
3467 scope.implemented = 1
3468 env.allocate_vtable_names(self.entry)
3470 def analyse_expressions(self, env):
3472 scope = self.entry.type.scope
3473 self.body.analyse_expressions(scope)
3475 def generate_function_definitions(self, env, code):
3477 self.generate_lambda_definitions(self.scope, code)
3478 self.body.generate_function_definitions(self.scope, code)
3480 def generate_execution_code(self, code):
3481 # This is needed to generate evaluation code for
3482 # default values of method arguments.
3484 self.body.generate_execution_code(code)
3486 def annotate(self, code):
3488 self.body.annotate(code)
3491 class PropertyNode(StatNode):
3492 # Definition of a property in an extension type.
3495 # doc EncodedString or None Doc string
3498 child_attrs = ["body"]
3500 def analyse_declarations(self, env):
3501 entry = env.declare_property(self.name, self.doc, self.pos)
3503 entry.scope.directives = env.directives
3504 self.body.analyse_declarations(entry.scope)
3506 def analyse_expressions(self, env):
3507 self.body.analyse_expressions(env)
3509 def generate_function_definitions(self, env, code):
3510 self.body.generate_function_definitions(env, code)
3512 def generate_execution_code(self, code):
3515 def annotate(self, code):
3516 self.body.annotate(code)
3519 class GlobalNode(StatNode):
3520 # Global variable declaration.
3526 def analyse_declarations(self, env):
3527 for name in self.names:
3528 env.declare_global(name, self.pos)
3530 def analyse_expressions(self, env):
3533 def generate_execution_code(self, code):
3537 class NonlocalNode(StatNode):
3538 # Nonlocal variable declaration via the 'nonlocal' keyword.
3544 def analyse_declarations(self, env):
3545 for name in self.names:
3546 env.declare_nonlocal(name, self.pos)
3548 def analyse_expressions(self, env):
3551 def generate_execution_code(self, code):
3555 class ExprStatNode(StatNode):
3556 # Expression used as a statement.
3560 child_attrs = ["expr"]
3562 def analyse_declarations(self, env):
3564 if isinstance(self.expr, ExprNodes.GeneralCallNode):
3565 func = self.expr.function.as_cython_attribute()
3566 if func == u'declare':
3567 args, kwds = self.expr.explicit_args_kwds()
3569 error(self.expr.pos, "Variable names must be specified.")
3570 for var, type_node in kwds.key_value_pairs:
3571 type = type_node.analyse_as_type(env)
3573 error(type_node.pos, "Unknown type")
3575 env.declare_var(var.value, type, var.pos, is_cdef = True)
3576 self.__class__ = PassStatNode
3578 def analyse_expressions(self, env):
3579 self.expr.result_is_used = False # hint that .result() may safely be left empty
3580 self.expr.analyse_expressions(env)
3582 def nogil_check(self, env):
3583 if self.expr.type.is_pyobject and self.expr.is_temp:
3586 gil_message = "Discarding owned Python object"
3588 def generate_execution_code(self, code):
3589 self.expr.generate_evaluation_code(code)
3590 if not self.expr.is_temp and self.expr.result():
3591 code.putln("%s;" % self.expr.result())
3592 self.expr.generate_disposal_code(code)
3593 self.expr.free_temps(code)
3595 def generate_function_definitions(self, env, code):
3596 self.expr.generate_function_definitions(env, code)
3598 def annotate(self, code):
3599 self.expr.annotate(code)
3602 class AssignmentNode(StatNode):
3603 # Abstract base class for assignment nodes.
3605 # The analyse_expressions and generate_execution_code
3606 # phases of assignments are split into two sub-phases
3607 # each, to enable all the right hand sides of a
3608 # parallel assignment to be evaluated before assigning
3609 # to any of the left hand sides.
3611 def analyse_expressions(self, env):
3612 self.analyse_types(env)
3614 # def analyse_expressions(self, env):
3615 # self.analyse_expressions_1(env)
3616 # self.analyse_expressions_2(env)
3618 def generate_execution_code(self, code):
3619 self.generate_rhs_evaluation_code(code)
3620 self.generate_assignment_code(code)
3623 class SingleAssignmentNode(AssignmentNode):
3624 # The simplest case:
3628 # lhs ExprNode Left hand side
3629 # rhs ExprNode Right hand side
3630 # first bool Is this guaranteed the first assignment to lhs?
3632 child_attrs = ["lhs", "rhs"]
3634 declaration_only = False
3636 def analyse_declarations(self, env):
3639 # handle declarations of the form x = cython.foo()
3640 if isinstance(self.rhs, ExprNodes.CallNode):
3641 func_name = self.rhs.function.as_cython_attribute()
3643 args, kwds = self.rhs.explicit_args_kwds()
3645 if func_name in ['declare', 'typedef']:
3646 if len(args) > 2 or kwds is not None:
3647 error(self.rhs.pos, "Can only declare one type at a time.")
3649 type = args[0].analyse_as_type(env)
3651 error(args[0].pos, "Unknown type")
3654 if func_name == 'declare':
3655 if isinstance(lhs, ExprNodes.NameNode):
3656 vars = [(lhs.name, lhs.pos)]
3657 elif isinstance(lhs, ExprNodes.TupleNode):
3658 vars = [(var.name, var.pos) for var in lhs.args]
3660 error(lhs.pos, "Invalid declaration")
3662 for var, pos in vars:
3663 env.declare_var(var, type, pos, is_cdef = True)
3668 self.declaration_only = True
3670 self.declaration_only = True
3671 if not isinstance(lhs, ExprNodes.NameNode):
3672 error(lhs.pos, "Invalid declaration.")
3673 env.declare_typedef(lhs.name, type, self.pos, visibility='private')
3675 elif func_name in ['struct', 'union']:
3676 self.declaration_only = True
3677 if len(args) > 0 or kwds is None:
3678 error(self.rhs.pos, "Struct or union members must be given by name.")
3681 for member, type_node in kwds.key_value_pairs:
3682 type = type_node.analyse_as_type(env)
3684 error(type_node.pos, "Unknown type")
3686 members.append((member.value, type, member.pos))
3687 if len(members) < len(kwds.key_value_pairs):
3689 if not isinstance(self.lhs, ExprNodes.NameNode):
3690 error(self.lhs.pos, "Invalid declaration.")
3691 name = self.lhs.name
3692 scope = StructOrUnionScope(name)
3693 env.declare_struct_or_union(name, func_name, scope, False, self.rhs.pos)
3694 for member, type, pos in members:
3695 scope.declare_var(member, type, pos)
3697 if self.declaration_only:
3700 self.lhs.analyse_target_declaration(env)
3702 def analyse_types(self, env, use_temp = 0):
3703 self.rhs.analyse_types(env)
3704 self.lhs.analyse_target_types(env)
3705 self.lhs.gil_assignment_check(env)
3706 self.rhs = self.rhs.coerce_to(self.lhs.type, env)
3708 self.rhs = self.rhs.coerce_to_temp(env)
3710 def generate_rhs_evaluation_code(self, code):
3711 self.rhs.generate_evaluation_code(code)
3713 def generate_assignment_code(self, code):
3714 self.lhs.generate_assignment_code(self.rhs, code)
3716 def generate_function_definitions(self, env, code):
3717 self.rhs.generate_function_definitions(env, code)
3719 def annotate(self, code):
3720 self.lhs.annotate(code)
3721 self.rhs.annotate(code)
3724 class CascadedAssignmentNode(AssignmentNode):
3725 # An assignment with multiple left hand sides:
3729 # lhs_list [ExprNode] Left hand sides
3730 # rhs ExprNode Right hand sides
3734 # coerced_rhs_list [ExprNode] RHS coerced to type of each LHS
3736 child_attrs = ["lhs_list", "rhs", "coerced_rhs_list"]
3737 coerced_rhs_list = None
3739 def analyse_declarations(self, env):
3740 for lhs in self.lhs_list:
3741 lhs.analyse_target_declaration(env)
3743 def analyse_types(self, env, use_temp = 0):
3744 self.rhs.analyse_types(env)
3745 if not self.rhs.is_simple():
3747 self.rhs = self.rhs.coerce_to_temp(env)
3749 self.rhs = self.rhs.coerce_to_simple(env)
3750 from ExprNodes import CloneNode
3751 self.coerced_rhs_list = []
3752 for lhs in self.lhs_list:
3753 lhs.analyse_target_types(env)
3754 lhs.gil_assignment_check(env)
3755 rhs = CloneNode(self.rhs)
3756 rhs = rhs.coerce_to(lhs.type, env)
3757 self.coerced_rhs_list.append(rhs)
3759 def generate_rhs_evaluation_code(self, code):
3760 self.rhs.generate_evaluation_code(code)
3762 def generate_assignment_code(self, code):
3763 for i in range(len(self.lhs_list)):
3764 lhs = self.lhs_list[i]
3765 rhs = self.coerced_rhs_list[i]
3766 rhs.generate_evaluation_code(code)
3767 lhs.generate_assignment_code(rhs, code)
3768 # Assignment has disposed of the cloned RHS
3769 self.rhs.generate_disposal_code(code)
3770 self.rhs.free_temps(code)
3772 def generate_function_definitions(self, env, code):
3773 self.rhs.generate_function_definitions(env, code)
3775 def annotate(self, code):
3776 for i in range(len(self.lhs_list)):
3777 lhs = self.lhs_list[i].annotate(code)
3778 rhs = self.coerced_rhs_list[i].annotate(code)
3779 self.rhs.annotate(code)
3782 class ParallelAssignmentNode(AssignmentNode):
3783 # A combined packing/unpacking assignment:
3787 # This has been rearranged by the parser into
3789 # a = d ; b = e ; c = f
3791 # but we must evaluate all the right hand sides
3792 # before assigning to any of the left hand sides.
3794 # stats [AssignmentNode] The constituent assignments
3796 child_attrs = ["stats"]
3798 def analyse_declarations(self, env):
3799 for stat in self.stats:
3800 stat.analyse_declarations(env)
3802 def analyse_expressions(self, env):
3803 for stat in self.stats:
3804 stat.analyse_types(env, use_temp = 1)
3806 # def analyse_expressions(self, env):
3807 # for stat in self.stats:
3808 # stat.analyse_expressions_1(env, use_temp = 1)
3809 # for stat in self.stats:
3810 # stat.analyse_expressions_2(env)
3812 def generate_execution_code(self, code):
3813 for stat in self.stats:
3814 stat.generate_rhs_evaluation_code(code)
3815 for stat in self.stats:
3816 stat.generate_assignment_code(code)
3818 def generate_function_definitions(self, env, code):
3819 for stat in self.stats:
3820 stat.generate_function_definitions(env, code)
3822 def annotate(self, code):
3823 for stat in self.stats:
3827 class InPlaceAssignmentNode(AssignmentNode):
3828 # An in place arithmetic operand:
3834 # lhs ExprNode Left hand side
3835 # rhs ExprNode Right hand side
3836 # op char one of "+-*/%^&|"
3837 # dup (ExprNode) copy of lhs used for operation (auto-generated)
3839 # This code is a bit tricky because in order to obey Python
3840 # semantics the sub-expressions (e.g. indices) of the lhs must
3841 # not be evaluated twice. So we must re-use the values calculated
3842 # in evaluation phase for the assignment phase as well.
3843 # Fortunately, the type of the lhs node is fairly constrained
3844 # (it must be a NameNode, AttributeNode, or IndexNode).
3846 child_attrs = ["lhs", "rhs"]
3848 def analyse_declarations(self, env):
3849 self.lhs.analyse_target_declaration(env)
3851 def analyse_types(self, env):
3852 self.rhs.analyse_types(env)
3853 self.lhs.analyse_target_types(env)
3855 def generate_execution_code(self, code):
3857 self.rhs.generate_evaluation_code(code)
3858 self.lhs.generate_subexpr_evaluation_code(code)
3859 c_op = self.operator
3863 error(self.pos, "No C inplace power operator")
3864 if isinstance(self.lhs, ExprNodes.IndexNode) and self.lhs.is_buffer_access:
3865 if self.lhs.type.is_pyobject:
3866 error(self.pos, "In-place operators not allowed on object buffers in this release.")
3867 if c_op in ('/', '%') and self.lhs.type.is_int and not code.directives['cdivision']:
3868 error(self.pos, "In-place non-c divide operators not allowed on int buffers.")
3869 self.lhs.generate_buffer_setitem_code(self.rhs, code, c_op)
3872 # TODO: make sure overload is declared
3873 code.putln("%s %s= %s;" % (self.lhs.result(), c_op, self.rhs.result()))
3874 self.lhs.generate_subexpr_disposal_code(code)
3875 self.lhs.free_subexpr_temps(code)
3876 self.rhs.generate_disposal_code(code)
3877 self.rhs.free_temps(code)
3879 def annotate(self, code):
3880 self.lhs.annotate(code)
3881 self.rhs.annotate(code)
3883 def create_binop_node(self):
3885 return ExprNodes.binop_node(self.pos, self.operator, self.lhs, self.rhs)
3888 class PrintStatNode(StatNode):
3891 # arg_tuple TupleNode
3892 # stream ExprNode or None (stdout)
3893 # append_newline boolean
3895 child_attrs = ["arg_tuple", "stream"]
3897 def analyse_expressions(self, env):
3899 self.stream.analyse_expressions(env)
3900 self.stream = self.stream.coerce_to_pyobject(env)
3901 self.arg_tuple.analyse_expressions(env)
3902 self.arg_tuple = self.arg_tuple.coerce_to_pyobject(env)
3903 env.use_utility_code(printing_utility_code)
3904 if len(self.arg_tuple.args) == 1 and self.append_newline:
3905 env.use_utility_code(printing_one_utility_code)
3907 nogil_check = Node.gil_error
3908 gil_message = "Python print statement"
3910 def generate_execution_code(self, code):
3912 self.stream.generate_evaluation_code(code)
3913 stream_result = self.stream.py_result()
3916 if len(self.arg_tuple.args) == 1 and self.append_newline:
3917 arg = self.arg_tuple.args[0]
3918 arg.generate_evaluation_code(code)
3921 "if (__Pyx_PrintOne(%s, %s) < 0) %s" % (
3924 code.error_goto(self.pos)))
3925 arg.generate_disposal_code(code)
3926 arg.free_temps(code)
3928 self.arg_tuple.generate_evaluation_code(code)
3930 "if (__Pyx_Print(%s, %s, %d) < 0) %s" % (
3932 self.arg_tuple.py_result(),
3933 self.append_newline,
3934 code.error_goto(self.pos)))
3935 self.arg_tuple.generate_disposal_code(code)
3936 self.arg_tuple.free_temps(code)
3939 self.stream.generate_disposal_code(code)
3940 self.stream.free_temps(code)
3942 def generate_function_definitions(self, env, code):
3944 self.stream.generate_function_definitions(env, code)
3945 self.arg_tuple.generate_function_definitions(env, code)
3947 def annotate(self, code):
3949 self.stream.annotate(code)
3950 self.arg_tuple.annotate(code)
3953 class ExecStatNode(StatNode):
3958 child_attrs = ["args"]
3960 def analyse_expressions(self, env):
3961 for i, arg in enumerate(self.args):
3962 arg.analyse_expressions(env)
3963 arg = arg.coerce_to_pyobject(env)
3965 env.use_utility_code(Builtin.pyexec_utility_code)
3967 nogil_check = Node.gil_error
3968 gil_message = "Python exec statement"
3970 def generate_execution_code(self, code):
3972 for arg in self.args:
3973 arg.generate_evaluation_code(code)
3974 args.append( arg.py_result() )
3975 args = tuple(args + ['0', '0'][:3-len(args)])
3976 temp_result = code.funcstate.allocate_temp(PyrexTypes.py_object_type, manage_ref=True)
3977 code.putln("%s = __Pyx_PyRun(%s, %s, %s);" % (
3978 (temp_result,) + args))
3979 for arg in self.args:
3980 arg.generate_disposal_code(code)
3981 arg.free_temps(code)
3983 code.error_goto_if_null(temp_result, self.pos))
3984 code.put_gotref(temp_result)
3985 code.put_decref_clear(temp_result, py_object_type)
3986 code.funcstate.release_temp(temp_result)
3988 def annotate(self, code):
3989 for arg in self.args:
3993 class DelStatNode(StatNode):
3998 child_attrs = ["args"]
4000 def analyse_declarations(self, env):
4001 for arg in self.args:
4002 arg.analyse_target_declaration(env)
4004 def analyse_expressions(self, env):
4005 for arg in self.args:
4006 arg.analyse_target_expression(env, None)
4007 if arg.type.is_pyobject:
4009 elif arg.type.is_ptr and arg.type.base_type.is_cpp_class:
4011 elif arg.type.is_cpp_class:
4012 error(arg.pos, "Deletion of non-heap C++ object")
4014 error(arg.pos, "Deletion of non-Python, non-C++ object")
4015 #arg.release_target_temp(env)
4017 def nogil_check(self, env):
4018 for arg in self.args:
4019 if arg.type.is_pyobject:
4022 gil_message = "Deleting Python object"
4024 def generate_execution_code(self, code):
4025 for arg in self.args:
4026 if arg.type.is_pyobject:
4027 arg.generate_deletion_code(code)
4028 elif arg.type.is_ptr and arg.type.base_type.is_cpp_class:
4029 arg.generate_result_code(code)
4030 code.putln("delete %s;" % arg.result())
4031 # else error reported earlier
4033 def annotate(self, code):
4034 for arg in self.args:
4038 class PassStatNode(StatNode):
4043 def analyse_expressions(self, env):
4046 def generate_execution_code(self, code):
4050 class BreakStatNode(StatNode):
4054 def analyse_expressions(self, env):
4057 def generate_execution_code(self, code):
4058 if not code.break_label:
4059 error(self.pos, "break statement not inside loop")
4061 code.put_goto(code.break_label)
4064 class ContinueStatNode(StatNode):
4068 def analyse_expressions(self, env):
4071 def generate_execution_code(self, code):
4072 if code.funcstate.in_try_finally:
4073 error(self.pos, "continue statement inside try of try...finally")
4074 elif not code.continue_label:
4075 error(self.pos, "continue statement not inside loop")
4077 code.put_goto(code.continue_label)
4080 class ReturnStatNode(StatNode):
4083 # value ExprNode or None
4084 # return_type PyrexType
4086 child_attrs = ["value"]
4088 def analyse_expressions(self, env):
4089 return_type = env.return_type
4090 self.return_type = return_type
4092 error(self.pos, "Return not inside a function body")
4095 self.value.analyse_types(env)
4096 if return_type.is_void or return_type.is_returncode:
4097 error(self.value.pos,
4098 "Return with value in void function")
4100 self.value = self.value.coerce_to(env.return_type, env)
4102 if (not return_type.is_void
4103 and not return_type.is_pyobject
4104 and not return_type.is_returncode):
4105 error(self.pos, "Return value required")
4107 def nogil_check(self, env):
4108 if self.return_type.is_pyobject:
4111 gil_message = "Returning Python object"
4113 def generate_execution_code(self, code):
4114 code.mark_pos(self.pos)
4115 if not self.return_type:
4116 # error reported earlier
4118 if self.return_type.is_pyobject:
4119 code.put_xdecref(Naming.retval_cname,
4122 self.value.generate_evaluation_code(code)
4123 self.value.make_owned_reference(code)
4126 Naming.retval_cname,
4127 self.value.result_as(self.return_type)))
4128 self.value.generate_post_assignment_code(code)
4129 self.value.free_temps(code)
4131 if self.return_type.is_pyobject:
4132 code.put_init_to_py_none(Naming.retval_cname, self.return_type)
4133 elif self.return_type.is_returncode:
4136 Naming.retval_cname,
4137 self.return_type.default_value))
4138 for cname, type in code.funcstate.temps_holding_reference():
4139 code.put_decref_clear(cname, type)
4140 code.put_goto(code.return_label)
4142 def generate_function_definitions(self, env, code):
4143 if self.value is not None:
4144 self.value.generate_function_definitions(env, code)
4146 def annotate(self, code):
4148 self.value.annotate(code)
4151 class RaiseStatNode(StatNode):
4154 # exc_type ExprNode or None
4155 # exc_value ExprNode or None
4156 # exc_tb ExprNode or None
4158 child_attrs = ["exc_type", "exc_value", "exc_tb"]
4160 def analyse_expressions(self, env):
4162 self.exc_type.analyse_types(env)
4163 self.exc_type = self.exc_type.coerce_to_pyobject(env)
4165 self.exc_value.analyse_types(env)
4166 self.exc_value = self.exc_value.coerce_to_pyobject(env)
4168 self.exc_tb.analyse_types(env)
4169 self.exc_tb = self.exc_tb.coerce_to_pyobject(env)
4170 # special cases for builtin exceptions
4171 self.builtin_exc_name = None
4172 if self.exc_type and not self.exc_value and not self.exc_tb:
4175 if (isinstance(exc, ExprNodes.SimpleCallNode) and
4176 not (exc.args or (exc.arg_tuple is not None and
4177 exc.arg_tuple.args))):
4178 exc = exc.function # extract the exception type
4179 if exc.is_name and exc.entry.is_builtin:
4180 self.builtin_exc_name = exc.name
4181 if self.builtin_exc_name == 'MemoryError':
4182 self.exc_type = None # has a separate implementation
4184 nogil_check = Node.gil_error
4185 gil_message = "Raising exception"
4187 def generate_execution_code(self, code):
4188 if self.builtin_exc_name == 'MemoryError':
4189 code.putln('PyErr_NoMemory(); %s' % code.error_goto(self.pos))
4193 self.exc_type.generate_evaluation_code(code)
4194 type_code = self.exc_type.py_result()
4198 self.exc_value.generate_evaluation_code(code)
4199 value_code = self.exc_value.py_result()
4203 self.exc_tb.generate_evaluation_code(code)
4204 tb_code = self.exc_tb.py_result()
4207 code.globalstate.use_utility_code(raise_utility_code)
4209 "__Pyx_Raise(%s, %s, %s);" % (
4213 for obj in (self.exc_type, self.exc_value, self.exc_tb):
4215 obj.generate_disposal_code(code)
4216 obj.free_temps(code)
4218 code.error_goto(self.pos))
4220 def generate_function_definitions(self, env, code):
4221 if self.exc_type is not None:
4222 self.exc_type.generate_function_definitions(env, code)
4223 if self.exc_value is not None:
4224 self.exc_value.generate_function_definitions(env, code)
4225 if self.exc_tb is not None:
4226 self.exc_tb.generate_function_definitions(env, code)
4228 def annotate(self, code):
4230 self.exc_type.annotate(code)
4232 self.exc_value.annotate(code)
4234 self.exc_tb.annotate(code)
4237 class ReraiseStatNode(StatNode):
4241 def analyse_expressions(self, env):
4242 env.use_utility_code(restore_exception_utility_code)
4244 nogil_check = Node.gil_error
4245 gil_message = "Raising exception"
4247 def generate_execution_code(self, code):
4248 vars = code.funcstate.exc_vars
4250 for varname in vars:
4251 code.put_giveref(varname)
4252 code.putln("__Pyx_ErrRestore(%s, %s, %s);" % tuple(vars))
4253 for varname in vars:
4254 code.put("%s = 0; " % varname)
4256 code.putln(code.error_goto(self.pos))
4258 error(self.pos, "Reraise not inside except clause")
4261 class AssertStatNode(StatNode):
4265 # value ExprNode or None
4267 child_attrs = ["cond", "value"]
4269 def analyse_expressions(self, env):
4270 self.cond = self.cond.analyse_boolean_expression(env)
4272 self.value.analyse_types(env)
4273 self.value = self.value.coerce_to_pyobject(env)
4275 nogil_check = Node.gil_error
4276 gil_message = "Raising exception"
4278 def generate_execution_code(self, code):
4279 code.putln("#ifndef CYTHON_WITHOUT_ASSERTIONS")
4280 self.cond.generate_evaluation_code(code)
4282 "if (unlikely(!%s)) {" %
4285 self.value.generate_evaluation_code(code)
4287 "PyErr_SetObject(PyExc_AssertionError, %s);" %
4288 self.value.py_result())
4289 self.value.generate_disposal_code(code)
4290 self.value.free_temps(code)
4293 "PyErr_SetNone(PyExc_AssertionError);")
4295 code.error_goto(self.pos))
4298 self.cond.generate_disposal_code(code)
4299 self.cond.free_temps(code)
4300 code.putln("#endif")
4302 def generate_function_definitions(self, env, code):
4303 self.cond.generate_function_definitions(env, code)
4304 if self.value is not None:
4305 self.value.generate_function_definitions(env, code)
4307 def annotate(self, code):
4308 self.cond.annotate(code)
4310 self.value.annotate(code)
4313 class IfStatNode(StatNode):
4316 # if_clauses [IfClauseNode]
4317 # else_clause StatNode or None
4319 child_attrs = ["if_clauses", "else_clause"]
4321 def analyse_control_flow(self, env):
4322 env.start_branching(self.pos)
4323 for if_clause in self.if_clauses:
4324 if_clause.analyse_control_flow(env)
4325 env.next_branch(if_clause.end_pos())
4326 if self.else_clause:
4327 self.else_clause.analyse_control_flow(env)
4328 env.finish_branching(self.end_pos())
4330 def analyse_declarations(self, env):
4331 for if_clause in self.if_clauses:
4332 if_clause.analyse_declarations(env)
4333 if self.else_clause:
4334 self.else_clause.analyse_declarations(env)
4336 def analyse_expressions(self, env):
4337 for if_clause in self.if_clauses:
4338 if_clause.analyse_expressions(env)
4339 if self.else_clause:
4340 self.else_clause.analyse_expressions(env)
4342 def generate_execution_code(self, code):
4343 code.mark_pos(self.pos)
4344 end_label = code.new_label()
4345 for if_clause in self.if_clauses:
4346 if_clause.generate_execution_code(code, end_label)
4347 if self.else_clause:
4348 code.putln("/*else*/ {")
4349 self.else_clause.generate_execution_code(code)
4351 code.put_label(end_label)
4353 def generate_function_definitions(self, env, code):
4354 for clause in self.if_clauses:
4355 clause.generate_function_definitions(env, code)
4356 if self.else_clause is not None:
4357 self.else_clause.generate_function_definitions(env, code)
4359 def annotate(self, code):
4360 for if_clause in self.if_clauses:
4361 if_clause.annotate(code)
4362 if self.else_clause:
4363 self.else_clause.annotate(code)
4366 class IfClauseNode(Node):
4367 # if or elif clause in an if statement
4369 # condition ExprNode
4372 child_attrs = ["condition", "body"]
4374 def analyse_control_flow(self, env):
4375 self.body.analyse_control_flow(env)
4377 def analyse_declarations(self, env):
4378 self.body.analyse_declarations(env)
4380 def analyse_expressions(self, env):
4382 self.condition.analyse_temp_boolean_expression(env)
4383 self.body.analyse_expressions(env)
4385 def get_constant_condition_result(self):
4386 if self.condition.has_constant_result():
4387 return bool(self.condition.constant_result)
4391 def generate_execution_code(self, code, end_label):
4392 self.condition.generate_evaluation_code(code)
4395 self.condition.result())
4396 self.condition.generate_disposal_code(code)
4397 self.condition.free_temps(code)
4398 self.body.generate_execution_code(code)
4399 code.put_goto(end_label)
4402 def generate_function_definitions(self, env, code):
4403 self.condition.generate_function_definitions(env, code)
4404 self.body.generate_function_definitions(env, code)
4406 def annotate(self, code):
4407 self.condition.annotate(code)
4408 self.body.annotate(code)
4411 class SwitchCaseNode(StatNode):
4412 # Generated in the optimization of an if-elif-else node
4414 # conditions [ExprNode]
4417 child_attrs = ['conditions', 'body']
4419 def generate_execution_code(self, code):
4420 for cond in self.conditions:
4421 code.mark_pos(cond.pos)
4422 cond.generate_evaluation_code(code)
4423 code.putln("case %s:" % cond.result())
4424 self.body.generate_execution_code(code)
4425 code.putln("break;")
4427 def generate_function_definitions(self, env, code):
4428 for cond in self.conditions:
4429 cond.generate_function_definitions(env, code)
4430 self.body.generate_function_definitions(env, code)
4432 def annotate(self, code):
4433 for cond in self.conditions:
4435 self.body.annotate(code)
4437 class SwitchStatNode(StatNode):
4438 # Generated in the optimization of an if-elif-else node
4441 # cases [SwitchCaseNode]
4442 # else_clause StatNode or None
4444 child_attrs = ['test', 'cases', 'else_clause']
4446 def generate_execution_code(self, code):
4447 self.test.generate_evaluation_code(code)
4448 code.putln("switch (%s) {" % self.test.result())
4449 for case in self.cases:
4450 case.generate_execution_code(code)
4451 if self.else_clause is not None:
4452 code.putln("default:")
4453 self.else_clause.generate_execution_code(code)
4454 code.putln("break;")
4457 def generate_function_definitions(self, env, code):
4458 self.test.generate_function_definitions(env, code)
4459 for case in self.cases:
4460 case.generate_function_definitions(env, code)
4461 if self.else_clause is not None:
4462 self.else_clause.generate_function_definitions(env, code)
4464 def annotate(self, code):
4465 self.test.annotate(code)
4466 for case in self.cases:
4468 if self.else_clause is not None:
4469 self.else_clause.annotate(code)
4471 class LoopNode(object):
4473 def analyse_control_flow(self, env):
4474 env.start_branching(self.pos)
4475 self.body.analyse_control_flow(env)
4476 env.next_branch(self.body.end_pos())
4477 if self.else_clause:
4478 self.else_clause.analyse_control_flow(env)
4479 env.finish_branching(self.end_pos())
4482 class WhileStatNode(LoopNode, StatNode):
4485 # condition ExprNode
4487 # else_clause StatNode
4489 child_attrs = ["condition", "body", "else_clause"]
4491 def analyse_declarations(self, env):
4492 self.body.analyse_declarations(env)
4493 if self.else_clause:
4494 self.else_clause.analyse_declarations(env)
4496 def analyse_expressions(self, env):
4498 self.condition.analyse_temp_boolean_expression(env)
4499 self.body.analyse_expressions(env)
4500 if self.else_clause:
4501 self.else_clause.analyse_expressions(env)
4503 def generate_execution_code(self, code):
4504 old_loop_labels = code.new_loop_labels()
4507 self.condition.generate_evaluation_code(code)
4508 self.condition.generate_disposal_code(code)
4511 self.condition.result())
4512 self.condition.free_temps(code)
4513 self.body.generate_execution_code(code)
4514 code.put_label(code.continue_label)
4516 break_label = code.break_label
4517 code.set_loop_labels(old_loop_labels)
4518 if self.else_clause:
4519 code.putln("/*else*/ {")
4520 self.else_clause.generate_execution_code(code)
4522 code.put_label(break_label)
4524 def generate_function_definitions(self, env, code):
4525 self.condition.generate_function_definitions(env, code)
4526 self.body.generate_function_definitions(env, code)
4527 if self.else_clause is not None:
4528 self.else_clause.generate_function_definitions(env, code)
4530 def annotate(self, code):
4531 self.condition.annotate(code)
4532 self.body.annotate(code)
4533 if self.else_clause:
4534 self.else_clause.annotate(code)
4537 def ForStatNode(pos, **kw):
4538 if 'iterator' in kw:
4539 return ForInStatNode(pos, **kw)
4541 return ForFromStatNode(pos, **kw)
4543 class ForInStatNode(LoopNode, StatNode):
4547 # iterator IteratorNode
4549 # else_clause StatNode
4550 # item NextNode used internally
4552 child_attrs = ["target", "iterator", "body", "else_clause"]
4555 def analyse_declarations(self, env):
4556 self.target.analyse_target_declaration(env)
4557 self.body.analyse_declarations(env)
4558 if self.else_clause:
4559 self.else_clause.analyse_declarations(env)
4561 def analyse_expressions(self, env):
4563 self.target.analyse_target_types(env)
4564 self.iterator.analyse_expressions(env)
4565 self.item = ExprNodes.NextNode(self.iterator, env)
4566 if (self.iterator.type.is_ptr or self.iterator.type.is_array) and \
4567 self.target.type.assignable_from(self.iterator.type):
4568 # C array slice optimization.
4571 self.item = self.item.coerce_to(self.target.type, env)
4572 self.body.analyse_expressions(env)
4573 if self.else_clause:
4574 self.else_clause.analyse_expressions(env)
4576 def generate_execution_code(self, code):
4577 old_loop_labels = code.new_loop_labels()
4578 self.iterator.allocate_counter_temp(code)
4579 self.iterator.generate_evaluation_code(code)
4582 self.item.generate_evaluation_code(code)
4583 self.target.generate_assignment_code(self.item, code)
4584 self.body.generate_execution_code(code)
4585 code.put_label(code.continue_label)
4588 break_label = code.break_label
4589 code.set_loop_labels(old_loop_labels)
4591 if self.else_clause:
4592 # in nested loops, the 'else' block can contain a
4593 # 'continue' statement for the outer loop, but we may need
4594 # to generate cleanup code before taking that path, so we
4596 orig_continue_label = code.continue_label
4597 code.continue_label = code.new_label('outer_continue')
4599 code.putln("/*else*/ {")
4600 self.else_clause.generate_execution_code(code)
4603 if code.label_used(code.continue_label):
4604 code.put_goto(break_label)
4605 code.put_label(code.continue_label)
4606 self.iterator.generate_disposal_code(code)
4607 code.put_goto(orig_continue_label)
4608 code.set_loop_labels(old_loop_labels)
4610 if code.label_used(break_label):
4611 code.put_label(break_label)
4612 self.iterator.release_counter_temp(code)
4613 self.iterator.generate_disposal_code(code)
4614 self.iterator.free_temps(code)
4616 def generate_function_definitions(self, env, code):
4617 self.target.generate_function_definitions(env, code)
4618 self.iterator.generate_function_definitions(env, code)
4619 self.body.generate_function_definitions(env, code)
4620 if self.else_clause is not None:
4621 self.else_clause.generate_function_definitions(env, code)
4623 def annotate(self, code):
4624 self.target.annotate(code)
4625 self.iterator.annotate(code)
4626 self.body.annotate(code)
4627 if self.else_clause:
4628 self.else_clause.annotate(code)
4629 self.item.annotate(code)
4632 class ForFromStatNode(LoopNode, StatNode):
4633 # for name from expr rel name rel expr
4640 # step ExprNode or None
4642 # else_clause StatNode or None
4648 # loopvar_node ExprNode (usually a NameNode or temp node)
4649 # py_loopvar_node PyTempNode or None
4650 child_attrs = ["target", "bound1", "bound2", "step", "body", "else_clause"]
4652 is_py_target = False
4654 py_loopvar_node = None
4657 gil_message = "For-loop using object bounds or target"
4659 def nogil_check(self, env):
4660 for x in (self.target, self.bound1, self.bound2):
4661 if x.type.is_pyobject:
4664 def analyse_declarations(self, env):
4665 self.target.analyse_target_declaration(env)
4666 self.body.analyse_declarations(env)
4667 if self.else_clause:
4668 self.else_clause.analyse_declarations(env)
4670 def analyse_expressions(self, env):
4672 self.target.analyse_target_types(env)
4673 self.bound1.analyse_types(env)
4674 self.bound2.analyse_types(env)
4675 if self.step is not None:
4676 if isinstance(self.step, ExprNodes.UnaryMinusNode):
4677 warning(self.step.pos, "Probable infinite loop in for-from-by statment. Consider switching the directions of the relations.", 2)
4678 self.step.analyse_types(env)
4680 target_type = self.target.type
4681 if self.target.type.is_numeric:
4682 loop_type = self.target.type
4684 loop_type = PyrexTypes.c_int_type
4685 if not self.bound1.type.is_pyobject:
4686 loop_type = PyrexTypes.widest_numeric_type(loop_type, self.bound1.type)
4687 if not self.bound2.type.is_pyobject:
4688 loop_type = PyrexTypes.widest_numeric_type(loop_type, self.bound2.type)
4689 if self.step is not None and not self.step.type.is_pyobject:
4690 loop_type = PyrexTypes.widest_numeric_type(loop_type, self.step.type)
4691 self.bound1 = self.bound1.coerce_to(loop_type, env)
4692 self.bound2 = self.bound2.coerce_to(loop_type, env)
4693 if not self.bound2.is_literal:
4694 self.bound2 = self.bound2.coerce_to_temp(env)
4695 if self.step is not None:
4696 self.step = self.step.coerce_to(loop_type, env)
4697 if not self.step.is_literal:
4698 self.step = self.step.coerce_to_temp(env)
4700 target_type = self.target.type
4701 if not (target_type.is_pyobject or target_type.is_numeric):
4702 error(self.target.pos,
4703 "for-from loop variable must be c numeric type or Python object")
4704 if target_type.is_numeric:
4705 self.is_py_target = False
4706 if isinstance(self.target, ExprNodes.IndexNode) and self.target.is_buffer_access:
4707 raise error(self.pos, "Buffer indexing not allowed as for loop target.")
4708 self.loopvar_node = self.target
4709 self.py_loopvar_node = None
4711 self.is_py_target = True
4712 c_loopvar_node = ExprNodes.TempNode(self.pos, loop_type, env)
4713 self.loopvar_node = c_loopvar_node
4714 self.py_loopvar_node = \
4715 ExprNodes.CloneNode(c_loopvar_node).coerce_to_pyobject(env)
4716 self.body.analyse_expressions(env)
4717 if self.else_clause:
4718 self.else_clause.analyse_expressions(env)
4720 def generate_execution_code(self, code):
4721 old_loop_labels = code.new_loop_labels()
4722 from_range = self.from_range
4723 self.bound1.generate_evaluation_code(code)
4724 self.bound2.generate_evaluation_code(code)
4725 offset, incop = self.relation_table[self.relation1]
4726 if self.step is not None:
4727 self.step.generate_evaluation_code(code)
4728 step = self.step.result()
4729 incop = "%s=%s" % (incop[0], step)
4731 if isinstance(self.loopvar_node, ExprNodes.TempNode):
4732 self.loopvar_node.allocate(code)
4733 if isinstance(self.py_loopvar_node, ExprNodes.TempNode):
4734 self.py_loopvar_node.allocate(code)
4736 loopvar_name = code.funcstate.allocate_temp(self.target.type, False)
4738 loopvar_name = self.loopvar_node.result()
4740 "for (%s = %s%s; %s %s %s; %s%s) {" % (
4742 self.bound1.result(), offset,
4743 loopvar_name, self.relation2, self.bound2.result(),
4744 loopvar_name, incop))
4745 if self.py_loopvar_node:
4746 self.py_loopvar_node.generate_evaluation_code(code)
4747 self.target.generate_assignment_code(self.py_loopvar_node, code)
4749 code.putln("%s = %s;" % (
4750 self.target.result(), loopvar_name))
4751 self.body.generate_execution_code(code)
4752 code.put_label(code.continue_label)
4753 if self.py_loopvar_node:
4754 # This mess is to make for..from loops with python targets behave
4755 # exactly like those with C targets with regards to re-assignment
4756 # of the loop variable.
4758 if self.target.entry.is_pyglobal:
4759 # We know target is a NameNode, this is the only ugly case.
4760 target_node = ExprNodes.PyTempNode(self.target.pos, None)
4761 target_node.allocate(code)
4762 interned_cname = code.intern_identifier(self.target.entry.name)
4763 code.globalstate.use_utility_code(ExprNodes.get_name_interned_utility_code)
4764 code.putln("%s = __Pyx_GetName(%s, %s); %s" % (
4765 target_node.result(),
4766 Naming.module_cname,
4768 code.error_goto_if_null(target_node.result(), self.target.pos)))
4769 code.put_gotref(target_node.result())
4771 target_node = self.target
4772 from_py_node = ExprNodes.CoerceFromPyTypeNode(self.loopvar_node.type, target_node, None)
4773 from_py_node.temp_code = loopvar_name
4774 from_py_node.generate_result_code(code)
4775 if self.target.entry.is_pyglobal:
4776 code.put_decref(target_node.result(), target_node.type)
4777 target_node.release(code)
4779 if self.py_loopvar_node:
4780 # This is potentially wasteful, but we don't want the semantics to
4781 # depend on whether or not the loop is a python type.
4782 self.py_loopvar_node.generate_evaluation_code(code)
4783 self.target.generate_assignment_code(self.py_loopvar_node, code)
4785 code.funcstate.release_temp(loopvar_name)
4786 break_label = code.break_label
4787 code.set_loop_labels(old_loop_labels)
4788 if self.else_clause:
4789 code.putln("/*else*/ {")
4790 self.else_clause.generate_execution_code(code)
4792 code.put_label(break_label)
4793 self.bound1.generate_disposal_code(code)
4794 self.bound1.free_temps(code)
4795 self.bound2.generate_disposal_code(code)
4796 self.bound2.free_temps(code)
4797 if isinstance(self.loopvar_node, ExprNodes.TempNode):
4798 self.loopvar_node.release(code)
4799 if isinstance(self.py_loopvar_node, ExprNodes.TempNode):
4800 self.py_loopvar_node.release(code)
4801 if self.step is not None:
4802 self.step.generate_disposal_code(code)
4803 self.step.free_temps(code)
4806 # {relop : (initial offset, increment op)}
4813 def generate_function_definitions(self, env, code):
4814 self.target.generate_function_definitions(env, code)
4815 self.bound1.generate_function_definitions(env, code)
4816 self.bound2.generate_function_definitions(env, code)
4817 if self.step is not None:
4818 self.step.generate_function_definitions(env, code)
4819 self.body.generate_function_definitions(env, code)
4820 if self.else_clause is not None:
4821 self.else_clause.generate_function_definitions(env, code)
4823 def annotate(self, code):
4824 self.target.annotate(code)
4825 self.bound1.annotate(code)
4826 self.bound2.annotate(code)
4828 self.step.annotate(code)
4829 self.body.annotate(code)
4830 if self.else_clause:
4831 self.else_clause.annotate(code)
4834 class WithStatNode(StatNode):
4836 Represents a Python with statement.
4838 Implemented as follows:
4842 VALUE = MGR.__enter__()
4846 TARGET = VALUE # optional
4850 if not EXIT(*EXCINFO):
4854 EXIT(None, None, None)
4855 MGR = EXIT = VALUE = None
4857 # manager The with statement manager object
4860 child_attrs = ["manager", "body"]
4864 def __init__(self, pos, manager, target, body):
4865 StatNode.__init__(self, pos, manager = manager)
4868 self.target_temp = ExprNodes.TempNode(pos, type=py_object_type)
4869 if target is not None:
4870 self.has_target = True
4871 body = StatListNode(
4873 WithTargetAssignmentStatNode(
4874 pos, lhs = target, rhs = self.target_temp),
4879 excinfo_target = UtilNodes.ResultRefNode(
4880 pos=pos, type=Builtin.tuple_type, may_hold_none=False)
4881 except_clause = ExceptClauseNode(
4882 pos, body = IfStatNode(
4885 pos, condition = ExprNodes.NotNode(
4886 pos, operand = ExprNodes.WithExitCallNode(
4887 pos, with_stat = self,
4888 args = excinfo_target)),
4889 body = ReraiseStatNode(pos),
4892 else_clause = None),
4895 excinfo_target = excinfo_target,
4898 self.body = TryFinallyStatNode(
4899 pos, body = TryExceptStatNode(
4901 except_clauses = [except_clause],
4904 finally_clause = ExprStatNode(
4905 pos, expr = ExprNodes.WithExitCallNode(
4906 pos, with_stat = self,
4907 args = ExprNodes.TupleNode(
4908 pos, args = [ExprNodes.NoneNode(pos) for _ in range(3)]
4910 handle_error_case = False,
4913 def analyse_declarations(self, env):
4914 self.manager.analyse_declarations(env)
4915 self.body.analyse_declarations(env)
4917 def analyse_expressions(self, env):
4918 self.manager.analyse_types(env)
4919 self.body.analyse_expressions(env)
4921 def generate_execution_code(self, code):
4922 code.putln("/*with:*/ {")
4923 self.manager.generate_evaluation_code(code)
4924 self.exit_var = code.funcstate.allocate_temp(py_object_type, manage_ref=False)
4925 code.putln("%s = PyObject_GetAttr(%s, %s); %s" % (
4927 self.manager.py_result(),
4928 code.get_py_string_const(EncodedString('__exit__'), identifier=True),
4929 code.error_goto_if_null(self.exit_var, self.pos),
4931 code.put_gotref(self.exit_var)
4933 # need to free exit_var in the face of exceptions during setup
4934 old_error_label = code.new_error_label()
4935 intermediate_error_label = code.error_label
4937 enter_func = code.funcstate.allocate_temp(py_object_type, manage_ref=True)
4938 code.putln("%s = PyObject_GetAttr(%s, %s); %s" % (
4940 self.manager.py_result(),
4941 code.get_py_string_const(EncodedString('__enter__'), identifier=True),
4942 code.error_goto_if_null(enter_func, self.pos),
4944 code.put_gotref(enter_func)
4945 self.manager.generate_disposal_code(code)
4946 self.manager.free_temps(code)
4947 self.target_temp.allocate(code)
4948 code.putln('%s = PyObject_Call(%s, ((PyObject *)%s), NULL); %s' % (
4949 self.target_temp.result(),
4952 code.error_goto_if_null(self.target_temp.result(), self.pos),
4954 code.put_gotref(self.target_temp.result())
4955 code.put_decref_clear(enter_func, py_object_type)
4956 code.funcstate.release_temp(enter_func)
4957 if not self.has_target:
4958 code.put_decref_clear(self.target_temp.result(), type=py_object_type)
4959 self.target_temp.release(code)
4960 # otherwise, WithTargetAssignmentStatNode will do it for us
4962 code.error_label = old_error_label
4963 self.body.generate_execution_code(code)
4965 step_over_label = code.new_label()
4966 code.put_goto(step_over_label)
4967 code.put_label(intermediate_error_label)
4968 code.put_decref_clear(self.exit_var, py_object_type)
4969 code.put_goto(old_error_label)
4970 code.put_label(step_over_label)
4972 code.funcstate.release_temp(self.exit_var)
4975 class WithTargetAssignmentStatNode(AssignmentNode):
4976 # The target assignment of the 'with' statement value (return
4977 # value of the __enter__() call).
4979 # This is a special cased assignment that steals the RHS reference
4980 # and frees its temp.
4982 # lhs ExprNode the assignment target
4983 # rhs TempNode the return value of the __enter__() call
4985 child_attrs = ["lhs", "rhs"]
4987 def analyse_declarations(self, env):
4988 self.lhs.analyse_target_declaration(env)
4990 def analyse_types(self, env):
4991 self.rhs.analyse_types(env)
4992 self.lhs.analyse_target_types(env)
4993 self.lhs.gil_assignment_check(env)
4994 self.orig_rhs = self.rhs
4995 self.rhs = self.rhs.coerce_to(self.lhs.type, env)
4997 def generate_execution_code(self, code):
4998 self.rhs.generate_evaluation_code(code)
4999 self.lhs.generate_assignment_code(self.rhs, code)
5000 self.orig_rhs.release(code)
5002 def generate_function_definitions(self, env, code):
5003 self.rhs.generate_function_definitions(env, code)
5005 def annotate(self, code):
5006 self.lhs.annotate(code)
5007 self.rhs.annotate(code)
5010 class TryExceptStatNode(StatNode):
5011 # try .. except statement
5014 # except_clauses [ExceptClauseNode]
5015 # else_clause StatNode or None
5017 child_attrs = ["body", "except_clauses", "else_clause"]
5019 def analyse_control_flow(self, env):
5020 env.start_branching(self.pos)
5021 self.body.analyse_control_flow(env)
5022 successful_try = env.control_flow # grab this for later
5023 env.next_branch(self.body.end_pos())
5024 env.finish_branching(self.body.end_pos())
5026 env.start_branching(self.except_clauses[0].pos)
5027 for except_clause in self.except_clauses:
5028 except_clause.analyse_control_flow(env)
5029 env.next_branch(except_clause.end_pos())
5031 # the else cause it executed only when the try clause finishes
5032 env.control_flow.incoming = successful_try
5033 if self.else_clause:
5034 self.else_clause.analyse_control_flow(env)
5035 env.finish_branching(self.end_pos())
5037 def analyse_declarations(self, env):
5038 self.body.analyse_declarations(env)
5039 for except_clause in self.except_clauses:
5040 except_clause.analyse_declarations(env)
5041 if self.else_clause:
5042 self.else_clause.analyse_declarations(env)
5043 env.use_utility_code(reset_exception_utility_code)
5045 def analyse_expressions(self, env):
5046 self.body.analyse_expressions(env)
5047 default_clause_seen = 0
5048 for except_clause in self.except_clauses:
5049 except_clause.analyse_expressions(env)
5050 if default_clause_seen:
5051 error(except_clause.pos, "default 'except:' must be last")
5052 if not except_clause.pattern:
5053 default_clause_seen = 1
5054 self.has_default_clause = default_clause_seen
5055 if self.else_clause:
5056 self.else_clause.analyse_expressions(env)
5058 nogil_check = Node.gil_error
5059 gil_message = "Try-except statement"
5061 def generate_execution_code(self, code):
5062 old_return_label = code.return_label
5063 old_break_label = code.break_label
5064 old_continue_label = code.continue_label
5065 old_error_label = code.new_error_label()
5066 our_error_label = code.error_label
5067 except_end_label = code.new_label('exception_handled')
5068 except_error_label = code.new_label('except_error')
5069 except_return_label = code.new_label('except_return')
5070 try_return_label = code.new_label('try_return')
5071 try_break_label = code.new_label('try_break')
5072 try_continue_label = code.new_label('try_continue')
5073 try_end_label = code.new_label('try_end')
5075 exc_save_vars = [code.funcstate.allocate_temp(py_object_type, False)
5078 code.putln("__Pyx_ExceptionSave(%s);" %
5079 ', '.join(['&%s' % var for var in exc_save_vars]))
5080 for var in exc_save_vars:
5081 code.put_xgotref(var)
5084 code.return_label = try_return_label
5085 code.break_label = try_break_label
5086 code.continue_label = try_continue_label
5087 self.body.generate_execution_code(code)
5090 temps_to_clean_up = code.funcstate.all_free_managed_temps()
5091 code.error_label = except_error_label
5092 code.return_label = except_return_label
5093 if self.else_clause:
5096 self.else_clause.generate_execution_code(code)
5099 for var in exc_save_vars:
5100 code.put_xdecref_clear(var, py_object_type)
5101 code.put_goto(try_end_label)
5102 if code.label_used(try_return_label):
5103 code.put_label(try_return_label)
5104 for var in exc_save_vars:
5105 code.put_xgiveref(var)
5106 code.putln("__Pyx_ExceptionReset(%s);" %
5107 ', '.join(exc_save_vars))
5108 code.put_goto(old_return_label)
5109 code.put_label(our_error_label)
5110 for temp_name, type in temps_to_clean_up:
5111 code.put_xdecref_clear(temp_name, type)
5112 for except_clause in self.except_clauses:
5113 except_clause.generate_handling_code(code, except_end_label)
5115 error_label_used = code.label_used(except_error_label)
5116 if error_label_used or not self.has_default_clause:
5117 if error_label_used:
5118 code.put_label(except_error_label)
5119 for var in exc_save_vars:
5120 code.put_xgiveref(var)
5121 code.putln("__Pyx_ExceptionReset(%s);" %
5122 ', '.join(exc_save_vars))
5123 code.put_goto(old_error_label)
5125 for exit_label, old_label in zip(
5126 [try_break_label, try_continue_label, except_return_label],
5127 [old_break_label, old_continue_label, old_return_label]):
5129 if code.label_used(exit_label):
5130 code.put_label(exit_label)
5131 for var in exc_save_vars:
5132 code.put_xgiveref(var)
5133 code.putln("__Pyx_ExceptionReset(%s);" %
5134 ', '.join(exc_save_vars))
5135 code.put_goto(old_label)
5137 if code.label_used(except_end_label):
5138 code.put_label(except_end_label)
5139 for var in exc_save_vars:
5140 code.put_xgiveref(var)
5141 code.putln("__Pyx_ExceptionReset(%s);" %
5142 ', '.join(exc_save_vars))
5143 code.put_label(try_end_label)
5146 for cname in exc_save_vars:
5147 code.funcstate.release_temp(cname)
5149 code.return_label = old_return_label
5150 code.break_label = old_break_label
5151 code.continue_label = old_continue_label
5152 code.error_label = old_error_label
5154 def generate_function_definitions(self, env, code):
5155 self.body.generate_function_definitions(env, code)
5156 for except_clause in self.except_clauses:
5157 except_clause.generate_function_definitions(env, code)
5158 if self.else_clause is not None:
5159 self.else_clause.generate_function_definitions(env, code)
5161 def annotate(self, code):
5162 self.body.annotate(code)
5163 for except_node in self.except_clauses:
5164 except_node.annotate(code)
5165 if self.else_clause:
5166 self.else_clause.annotate(code)
5169 class ExceptClauseNode(Node):
5170 # Part of try ... except statement.
5172 # pattern [ExprNode]
5173 # target ExprNode or None
5175 # excinfo_target ResultRefNode or None optional target for exception info
5176 # match_flag string result of exception match
5177 # exc_value ExcValueNode used internally
5178 # function_name string qualified name of enclosing function
5179 # exc_vars (string * 3) local exception variables
5181 # excinfo_target is never set by the parser, but can be set by a transform
5182 # in order to extract more extensive information about the exception as a
5183 # sys.exc_info()-style tuple into a target variable
5185 child_attrs = ["pattern", "target", "body", "exc_value", "excinfo_target"]
5188 excinfo_target = None
5190 def analyse_declarations(self, env):
5192 self.target.analyse_target_declaration(env)
5193 self.body.analyse_declarations(env)
5195 def analyse_expressions(self, env):
5197 genv = env.global_scope()
5198 self.function_name = env.qualified_name
5200 # normalise/unpack self.pattern into a list
5201 for i, pattern in enumerate(self.pattern):
5202 pattern.analyse_expressions(env)
5203 self.pattern[i] = pattern.coerce_to_pyobject(env)
5206 self.exc_value = ExprNodes.ExcValueNode(self.pos, env)
5207 self.target.analyse_target_expression(env, self.exc_value)
5208 if self.excinfo_target is not None:
5210 self.excinfo_tuple = ExprNodes.TupleNode(pos=self.pos, args=[
5211 ExprNodes.ExcValueNode(pos=self.pos, env=env) for x in range(3)])
5212 self.excinfo_tuple.analyse_expressions(env)
5214 self.body.analyse_expressions(env)
5216 def generate_handling_code(self, code, end_label):
5217 code.mark_pos(self.pos)
5220 for pattern in self.pattern:
5221 pattern.generate_evaluation_code(code)
5222 exc_tests.append("PyErr_ExceptionMatches(%s)" % pattern.py_result())
5224 match_flag = code.funcstate.allocate_temp(PyrexTypes.c_int_type, False)
5226 "%s = %s;" % (match_flag, ' || '.join(exc_tests)))
5227 for pattern in self.pattern:
5228 pattern.generate_disposal_code(code)
5229 pattern.free_temps(code)
5233 code.funcstate.release_temp(match_flag)
5235 code.putln("/*except:*/ {")
5237 if not getattr(self.body, 'stats', True) and \
5238 self.excinfo_target is None and self.target is None:
5239 # most simple case: no exception variable, empty body (pass)
5240 # => reset the exception state, done
5241 code.putln("PyErr_Restore(0,0,0);")
5242 code.put_goto(end_label)
5246 exc_vars = [code.funcstate.allocate_temp(py_object_type,
5249 code.putln('__Pyx_AddTraceback("%s");' % self.function_name)
5250 # We always have to fetch the exception value even if
5251 # there is no target, because this also normalises the
5252 # exception and stores it in the thread state.
5253 code.globalstate.use_utility_code(get_exception_utility_code)
5254 exc_args = "&%s, &%s, &%s" % tuple(exc_vars)
5255 code.putln("if (__Pyx_GetException(%s) < 0) %s" % (exc_args,
5256 code.error_goto(self.pos)))
5260 self.exc_value.set_var(exc_vars[1])
5261 self.exc_value.generate_evaluation_code(code)
5262 self.target.generate_assignment_code(self.exc_value, code)
5263 if self.excinfo_target is not None:
5264 for tempvar, node in zip(exc_vars, self.excinfo_tuple.args):
5265 node.set_var(tempvar)
5266 self.excinfo_tuple.generate_evaluation_code(code)
5267 self.excinfo_target.result_code = self.excinfo_tuple.result()
5269 old_break_label, old_continue_label = code.break_label, code.continue_label
5270 code.break_label = code.new_label('except_break')
5271 code.continue_label = code.new_label('except_continue')
5273 old_exc_vars = code.funcstate.exc_vars
5274 code.funcstate.exc_vars = exc_vars
5275 self.body.generate_execution_code(code)
5276 code.funcstate.exc_vars = old_exc_vars
5277 if self.excinfo_target is not None:
5278 self.excinfo_tuple.generate_disposal_code(code)
5279 for var in exc_vars:
5280 code.put_decref_clear(var, py_object_type)
5281 code.put_goto(end_label)
5283 if code.label_used(code.break_label):
5284 code.put_label(code.break_label)
5285 if self.excinfo_target is not None:
5286 self.excinfo_tuple.generate_disposal_code(code)
5287 for var in exc_vars:
5288 code.put_decref_clear(var, py_object_type)
5289 code.put_goto(old_break_label)
5290 code.break_label = old_break_label
5292 if code.label_used(code.continue_label):
5293 code.put_label(code.continue_label)
5294 if self.excinfo_target is not None:
5295 self.excinfo_tuple.generate_disposal_code(code)
5296 for var in exc_vars:
5297 code.put_decref_clear(var, py_object_type)
5298 code.put_goto(old_continue_label)
5299 code.continue_label = old_continue_label
5301 if self.excinfo_target is not None:
5302 self.excinfo_tuple.free_temps(code)
5303 for temp in exc_vars:
5304 code.funcstate.release_temp(temp)
5309 def generate_function_definitions(self, env, code):
5310 if self.target is not None:
5311 self.target.generate_function_definitions(env, code)
5312 self.body.generate_function_definitions(env, code)
5314 def annotate(self, code):
5316 for pattern in self.pattern:
5317 pattern.annotate(code)
5319 self.target.annotate(code)
5320 self.body.annotate(code)
5323 class TryFinallyStatNode(StatNode):
5324 # try ... finally statement
5327 # finally_clause StatNode
5329 # The plan is that we funnel all continue, break
5330 # return and error gotos into the beginning of the
5331 # finally block, setting a variable to remember which
5332 # one we're doing. At the end of the finally block, we
5333 # switch on the variable to figure out where to go.
5334 # In addition, if we're doing an error, we save the
5335 # exception on entry to the finally block and restore
5338 child_attrs = ["body", "finally_clause"]
5340 preserve_exception = 1
5342 # handle exception case, in addition to return/break/continue
5343 handle_error_case = True
5345 disallow_continue_in_try_finally = 0
5346 # There doesn't seem to be any point in disallowing
5347 # continue in the try block, since we have no problem
5350 def create_analysed(pos, env, body, finally_clause):
5351 node = TryFinallyStatNode(pos, body=body, finally_clause=finally_clause)
5353 create_analysed = staticmethod(create_analysed)
5355 def analyse_control_flow(self, env):
5356 env.start_branching(self.pos)
5357 self.body.analyse_control_flow(env)
5358 env.next_branch(self.body.end_pos())
5359 env.finish_branching(self.body.end_pos())
5360 self.finally_clause.analyse_control_flow(env)
5362 def analyse_declarations(self, env):
5363 self.body.analyse_declarations(env)
5364 self.finally_clause.analyse_declarations(env)
5366 def analyse_expressions(self, env):
5367 self.body.analyse_expressions(env)
5368 self.finally_clause.analyse_expressions(env)
5370 nogil_check = Node.gil_error
5371 gil_message = "Try-finally statement"
5373 def generate_execution_code(self, code):
5374 old_error_label = code.error_label
5375 old_labels = code.all_new_labels()
5376 new_labels = code.get_all_labels()
5377 new_error_label = code.error_label
5378 if not self.handle_error_case:
5379 code.error_label = old_error_label
5380 catch_label = code.new_label()
5383 if self.disallow_continue_in_try_finally:
5384 was_in_try_finally = code.funcstate.in_try_finally
5385 code.funcstate.in_try_finally = 1
5386 self.body.generate_execution_code(code)
5387 if self.disallow_continue_in_try_finally:
5388 code.funcstate.in_try_finally = was_in_try_finally
5391 temps_to_clean_up = code.funcstate.all_free_managed_temps()
5392 code.mark_pos(self.finally_clause.pos)
5396 error_label_used = 0
5397 for i, new_label in enumerate(new_labels):
5398 if new_label in code.labels_used:
5399 cases_used.append(i)
5400 if new_label == new_error_label:
5401 error_label_used = 1
5402 error_label_case = i
5406 if error_label_used and self.preserve_exception:
5408 "PyObject *%s, *%s, *%s;" % Naming.exc_vars)
5410 "int %s;" % Naming.exc_lineno_name)
5411 exc_var_init_zero = ''.join(["%s = 0; " % var for var in Naming.exc_vars])
5412 exc_var_init_zero += '%s = 0;' % Naming.exc_lineno_name
5413 code.putln(exc_var_init_zero)
5415 exc_var_init_zero = None
5416 code.use_label(catch_label)
5418 "__pyx_why = 0; goto %s;" % catch_label)
5419 for i in cases_used:
5420 new_label = new_labels[i]
5421 #if new_label and new_label != "<try>":
5422 if new_label == new_error_label and self.preserve_exception:
5423 self.put_error_catcher(code,
5424 new_error_label, i+1, catch_label, temps_to_clean_up)
5426 code.put('%s: ' % new_label)
5427 if exc_var_init_zero:
5428 code.putln(exc_var_init_zero)
5429 code.putln("__pyx_why = %s; goto %s;" % (
5432 code.put_label(catch_label)
5433 code.set_all_labels(old_labels)
5434 if error_label_used:
5435 code.new_error_label()
5436 finally_error_label = code.error_label
5437 self.finally_clause.generate_execution_code(code)
5438 if error_label_used:
5439 if finally_error_label in code.labels_used and self.preserve_exception:
5440 over_label = code.new_label()
5441 code.put_goto(over_label);
5442 code.put_label(finally_error_label)
5443 code.putln("if (__pyx_why == %d) {" % (error_label_case + 1))
5444 for var in Naming.exc_vars:
5445 code.putln("Py_XDECREF(%s);" % var)
5447 code.put_goto(old_error_label)
5448 code.put_label(over_label)
5449 code.error_label = old_error_label
5452 "switch (__pyx_why) {")
5453 for i in cases_used:
5454 old_label = old_labels[i]
5455 if old_label == old_error_label and self.preserve_exception:
5456 self.put_error_uncatcher(code, i+1, old_error_label)
5458 code.use_label(old_label)
5460 "case %s: goto %s;" % (
5468 def generate_function_definitions(self, env, code):
5469 self.body.generate_function_definitions(env, code)
5470 self.finally_clause.generate_function_definitions(env, code)
5472 def put_error_catcher(self, code, error_label, i, catch_label, temps_to_clean_up):
5473 code.globalstate.use_utility_code(restore_exception_utility_code)
5480 for temp_name, type in temps_to_clean_up:
5481 code.put_xdecref_clear(temp_name, type)
5483 "__Pyx_ErrFetch(&%s, &%s, &%s);" %
5487 Naming.exc_lineno_name, Naming.lineno_cname))
5488 code.put_goto(catch_label)
5491 def put_error_uncatcher(self, code, i, error_label):
5492 code.globalstate.use_utility_code(restore_exception_utility_code)
5497 "__Pyx_ErrRestore(%s, %s, %s);" %
5501 Naming.lineno_cname, Naming.exc_lineno_name))
5502 for var in Naming.exc_vars:
5506 code.put_goto(error_label)
5510 def annotate(self, code):
5511 self.body.annotate(code)
5512 self.finally_clause.annotate(code)
5515 class GILStatNode(TryFinallyStatNode):
5516 # 'with gil' or 'with nogil' statement
5518 # state string 'gil' or 'nogil'
5522 preserve_exception = 0
5524 def __init__(self, pos, state, body):
5526 TryFinallyStatNode.__init__(self, pos,
5528 finally_clause = GILExitNode(pos, state = state))
5530 def analyse_expressions(self, env):
5531 env.use_utility_code(force_init_threads_utility_code)
5532 was_nogil = env.nogil
5534 TryFinallyStatNode.analyse_expressions(self, env)
5535 env.nogil = was_nogil
5539 def generate_execution_code(self, code):
5540 code.mark_pos(self.pos)
5542 if self.state == 'gil':
5543 code.putln("#ifdef WITH_THREAD")
5544 code.putln("PyGILState_STATE _save = PyGILState_Ensure();")
5545 code.putln("#endif")
5547 code.putln("#ifdef WITH_THREAD")
5548 code.putln("PyThreadState *_save = NULL;")
5549 code.putln("#endif")
5550 code.putln("Py_UNBLOCK_THREADS")
5551 TryFinallyStatNode.generate_execution_code(self, code)
5555 class GILExitNode(StatNode):
5556 # Used as the 'finally' block in a GILStatNode
5558 # state string 'gil' or 'nogil'
5562 def analyse_expressions(self, env):
5565 def generate_execution_code(self, code):
5566 if self.state == 'gil':
5567 code.putln("#ifdef WITH_THREAD")
5568 code.putln("PyGILState_Release(_save);")
5569 code.putln("#endif")
5571 code.putln("Py_BLOCK_THREADS")
5574 class CImportStatNode(StatNode):
5577 # module_name string Qualified name of module being imported
5578 # as_name string or None Name specified in "as" clause, if any
5582 def analyse_declarations(self, env):
5583 if not env.is_module_scope:
5584 error(self.pos, "cimport only allowed at module level")
5586 module_scope = env.find_module(self.module_name, self.pos)
5587 if "." in self.module_name:
5588 names = [EncodedString(name) for name in self.module_name.split(".")]
5590 top_module_scope = env.context.find_submodule(top_name)
5591 module_scope = top_module_scope
5592 for name in names[1:]:
5593 submodule_scope = module_scope.find_submodule(name)
5594 module_scope.declare_module(name, submodule_scope, self.pos)
5595 module_scope = submodule_scope
5597 env.declare_module(self.as_name, module_scope, self.pos)
5599 env.declare_module(top_name, top_module_scope, self.pos)
5601 name = self.as_name or self.module_name
5602 env.declare_module(name, module_scope, self.pos)
5604 def analyse_expressions(self, env):
5607 def generate_execution_code(self, code):
5611 class FromCImportStatNode(StatNode):
5612 # from ... cimport statement
5614 # module_name string Qualified name of module
5615 # imported_names [(pos, name, as_name, kind)] Names to be imported
5619 def analyse_declarations(self, env):
5620 if not env.is_module_scope:
5621 error(self.pos, "cimport only allowed at module level")
5623 module_scope = env.find_module(self.module_name, self.pos)
5624 env.add_imported_module(module_scope)
5625 for pos, name, as_name, kind in self.imported_names:
5627 for local_name, entry in module_scope.entries.items():
5628 env.add_imported_entry(local_name, entry, pos)
5630 entry = module_scope.lookup(name)
5632 if kind and not self.declaration_matches(entry, kind):
5633 entry.redeclared(pos)
5635 if kind == 'struct' or kind == 'union':
5636 entry = module_scope.declare_struct_or_union(name,
5637 kind = kind, scope = None, typedef_flag = 0, pos = pos)
5638 elif kind == 'class':
5639 entry = module_scope.declare_c_class(name, pos = pos,
5640 module_name = self.module_name)
5642 submodule_scope = env.context.find_module(name, relative_to = module_scope, pos = self.pos)
5643 if submodule_scope.parent_module is module_scope:
5644 env.declare_module(as_name or name, submodule_scope, self.pos)
5646 error(pos, "Name '%s' not declared in module '%s'"
5647 % (name, self.module_name))
5650 local_name = as_name or name
5651 env.add_imported_entry(local_name, entry, pos)
5653 def declaration_matches(self, entry, kind):
5654 if not entry.is_type:
5658 if not type.is_extension_type:
5661 if not type.is_struct_or_union:
5663 if kind != type.kind:
5667 def analyse_expressions(self, env):
5670 def generate_execution_code(self, code):
5674 class FromImportStatNode(StatNode):
5675 # from ... import statement
5678 # items [(string, NameNode)]
5679 # interned_items [(string, NameNode, ExprNode)]
5680 # item PyTempNode used internally
5681 # import_star boolean used internally
5683 child_attrs = ["module"]
5686 def analyse_declarations(self, env):
5687 for name, target in self.items:
5689 if not env.is_module_scope:
5690 error(self.pos, "import * only allowed at module level")
5692 env.has_import_star = 1
5693 self.import_star = 1
5695 target.analyse_target_declaration(env)
5697 def analyse_expressions(self, env):
5699 self.module.analyse_expressions(env)
5700 self.item = ExprNodes.RawCNameExprNode(self.pos, py_object_type)
5701 self.interned_items = []
5702 for name, target in self.items:
5704 for _, entry in env.entries.items():
5705 if not entry.is_type and entry.type.is_extension_type:
5706 env.use_utility_code(ExprNodes.type_test_utility_code)
5709 entry = env.lookup(target.name)
5710 # check whether or not entry is already cimported
5711 if (entry.is_type and entry.type.name == name
5712 and hasattr(entry.type, 'module_name')):
5713 if entry.type.module_name == self.module.module_name.value:
5714 # cimported with absolute name
5717 # cimported with relative name
5718 module = env.find_module(self.module.module_name.value,
5720 if entry.type.module_name == module.qualified_name:
5722 except AttributeError:
5724 target.analyse_target_expression(env, None)
5725 if target.type is py_object_type:
5728 coerced_item = self.item.coerce_to(target.type, env)
5729 self.interned_items.append((name, target, coerced_item))
5731 def generate_execution_code(self, code):
5732 self.module.generate_evaluation_code(code)
5733 if self.import_star:
5735 'if (%s(%s) < 0) %s;' % (
5737 self.module.py_result(),
5738 code.error_goto(self.pos)))
5739 item_temp = code.funcstate.allocate_temp(py_object_type, manage_ref=True)
5740 self.item.set_cname(item_temp)
5741 for name, target, coerced_item in self.interned_items:
5742 cname = code.intern_identifier(name)
5744 '%s = PyObject_GetAttr(%s, %s); %s' % (
5746 self.module.py_result(),
5748 code.error_goto_if_null(item_temp, self.pos)))
5749 code.put_gotref(item_temp)
5750 if coerced_item is None:
5751 target.generate_assignment_code(self.item, code)
5753 coerced_item.allocate_temp_result(code)
5754 coerced_item.generate_result_code(code)
5755 target.generate_assignment_code(coerced_item, code)
5756 code.put_decref_clear(item_temp, py_object_type)
5757 code.funcstate.release_temp(item_temp)
5758 self.module.generate_disposal_code(code)
5759 self.module.free_temps(code)
5763 #------------------------------------------------------------------------------------
5765 # Runtime support code
5767 #------------------------------------------------------------------------------------
5769 utility_function_predeclarations = \
5771 /* inline attribute */
5772 #ifndef CYTHON_INLINE
5773 #if defined(__GNUC__)
5774 #define CYTHON_INLINE __inline__
5775 #elif defined(_MSC_VER)
5776 #define CYTHON_INLINE __inline
5777 #elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
5778 #define CYTHON_INLINE inline
5780 #define CYTHON_INLINE
5784 /* unused attribute */
5785 #ifndef CYTHON_UNUSED
5786 # if defined(__GNUC__)
5787 # if !(defined(__cplusplus)) || (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4))
5788 # define CYTHON_UNUSED __attribute__ ((__unused__))
5790 # define CYTHON_UNUSED
5792 # elif defined(__ICC) || defined(__INTEL_COMPILER)
5793 # define CYTHON_UNUSED __attribute__ ((__unused__))
5795 # define CYTHON_UNUSED
5799 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*/
5803 if Options.gcc_branch_hints:
5804 branch_prediction_macros = \
5807 /* Test for GCC > 2.95 */
5808 #if __GNUC__ > 2 || (__GNUC__ == 2 && (__GNUC_MINOR__ > 95))
5809 #define likely(x) __builtin_expect(!!(x), 1)
5810 #define unlikely(x) __builtin_expect(!!(x), 0)
5811 #else /* __GNUC__ > 2 ... */
5812 #define likely(x) (x)
5813 #define unlikely(x) (x)
5814 #endif /* __GNUC__ > 2 ... */
5815 #else /* __GNUC__ */
5816 #define likely(x) (x)
5817 #define unlikely(x) (x)
5818 #endif /* __GNUC__ */
5821 branch_prediction_macros = \
5823 #define likely(x) (x)
5824 #define unlikely(x) (x)
5827 #get_name_predeclaration = \
5828 #"static PyObject *__Pyx_GetName(PyObject *dict, char *name); /*proto*/"
5830 #get_name_interned_predeclaration = \
5831 #"static PyObject *__Pyx_GetName(PyObject *dict, PyObject *name); /*proto*/"
5833 #------------------------------------------------------------------------------------
5835 printing_utility_code = UtilityCode(
5837 static int __Pyx_Print(PyObject*, PyObject *, int); /*proto*/
5838 #if PY_MAJOR_VERSION >= 3
5839 static PyObject* %s = 0;
5840 static PyObject* %s = 0;
5842 """ % (Naming.print_function, Naming.print_function_kwargs),
5844 #if PY_MAJOR_VERSION >= 3
5848 """ % (Naming.print_function, Naming.print_function_kwargs),
5850 #if PY_MAJOR_VERSION < 3
5851 static PyObject *__Pyx_GetStdout(void) {
5852 PyObject *f = PySys_GetObject((char *)"stdout");
5854 PyErr_SetString(PyExc_RuntimeError, "lost sys.stdout");
5859 static int __Pyx_Print(PyObject* f, PyObject *arg_tuple, int newline) {
5864 if (!(f = __Pyx_GetStdout()))
5867 for (i=0; i < PyTuple_GET_SIZE(arg_tuple); i++) {
5868 if (PyFile_SoftSpace(f, 1)) {
5869 if (PyFile_WriteString(" ", f) < 0)
5872 v = PyTuple_GET_ITEM(arg_tuple, i);
5873 if (PyFile_WriteObject(v, f, Py_PRINT_RAW) < 0)
5875 if (PyString_Check(v)) {
5876 char *s = PyString_AsString(v);
5877 Py_ssize_t len = PyString_Size(v);
5879 isspace(Py_CHARMASK(s[len-1])) &&
5881 PyFile_SoftSpace(f, 0);
5885 if (PyFile_WriteString("\n", f) < 0)
5887 PyFile_SoftSpace(f, 0);
5892 #else /* Python 3 has a print function */
5894 static int __Pyx_Print(PyObject* stream, PyObject *arg_tuple, int newline) {
5895 PyObject* kwargs = 0;
5896 PyObject* result = 0;
5897 PyObject* end_string;
5898 if (unlikely(!%(PRINT_FUNCTION)s)) {
5899 %(PRINT_FUNCTION)s = __Pyx_GetAttrString(%(BUILTINS)s, "print");
5900 if (!%(PRINT_FUNCTION)s)
5904 kwargs = PyDict_New();
5905 if (unlikely(!kwargs))
5907 if (unlikely(PyDict_SetItemString(kwargs, "file", stream) < 0))
5910 end_string = PyUnicode_FromStringAndSize(" ", 1);
5911 if (unlikely(!end_string))
5913 if (PyDict_SetItemString(kwargs, "end", end_string) < 0) {
5914 Py_DECREF(end_string);
5917 Py_DECREF(end_string);
5919 } else if (!newline) {
5920 if (unlikely(!%(PRINT_KWARGS)s)) {
5921 %(PRINT_KWARGS)s = PyDict_New();
5922 if (unlikely(!%(PRINT_KWARGS)s))
5924 end_string = PyUnicode_FromStringAndSize(" ", 1);
5925 if (unlikely(!end_string))
5927 if (PyDict_SetItemString(%(PRINT_KWARGS)s, "end", end_string) < 0) {
5928 Py_DECREF(end_string);
5931 Py_DECREF(end_string);
5933 kwargs = %(PRINT_KWARGS)s;
5935 result = PyObject_Call(%(PRINT_FUNCTION)s, arg_tuple, kwargs);
5936 if (unlikely(kwargs) && (kwargs != %(PRINT_KWARGS)s))
5943 if (kwargs != %(PRINT_KWARGS)s)
5949 """ % {'BUILTINS' : Naming.builtins_cname,
5950 'PRINT_FUNCTION' : Naming.print_function,
5951 'PRINT_KWARGS' : Naming.print_function_kwargs}
5955 printing_one_utility_code = UtilityCode(
5957 static int __Pyx_PrintOne(PyObject* stream, PyObject *o); /*proto*/
5960 #if PY_MAJOR_VERSION < 3
5962 static int __Pyx_PrintOne(PyObject* f, PyObject *o) {
5964 if (!(f = __Pyx_GetStdout()))
5967 if (PyFile_SoftSpace(f, 0)) {
5968 if (PyFile_WriteString(" ", f) < 0)
5971 if (PyFile_WriteObject(o, f, Py_PRINT_RAW) < 0)
5973 if (PyFile_WriteString("\n", f) < 0)
5976 /* the line below is just to avoid compiler
5977 * compiler warnings about unused functions */
5978 return __Pyx_Print(f, NULL, 0);
5981 #else /* Python 3 has a print function */
5983 static int __Pyx_PrintOne(PyObject* stream, PyObject *o) {
5985 PyObject* arg_tuple = PyTuple_New(1);
5986 if (unlikely(!arg_tuple))
5989 PyTuple_SET_ITEM(arg_tuple, 0, o);
5990 res = __Pyx_Print(stream, arg_tuple, 1);
5991 Py_DECREF(arg_tuple);
5997 requires=[printing_utility_code])
6001 #------------------------------------------------------------------------------------
6003 # Exception raising code
6005 # Exceptions are raised by __Pyx_Raise() and stored as plain
6006 # type/value/tb in PyThreadState->curexc_*. When being caught by an
6007 # 'except' statement, curexc_* is moved over to exc_* by
6008 # __Pyx_GetException()
6010 restore_exception_utility_code = UtilityCode(
6012 static CYTHON_INLINE void __Pyx_ErrRestore(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
6013 static CYTHON_INLINE void __Pyx_ErrFetch(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
6016 static CYTHON_INLINE void __Pyx_ErrRestore(PyObject *type, PyObject *value, PyObject *tb) {
6017 PyObject *tmp_type, *tmp_value, *tmp_tb;
6018 PyThreadState *tstate = PyThreadState_GET();
6020 tmp_type = tstate->curexc_type;
6021 tmp_value = tstate->curexc_value;
6022 tmp_tb = tstate->curexc_traceback;
6023 tstate->curexc_type = type;
6024 tstate->curexc_value = value;
6025 tstate->curexc_traceback = tb;
6026 Py_XDECREF(tmp_type);
6027 Py_XDECREF(tmp_value);
6031 static CYTHON_INLINE void __Pyx_ErrFetch(PyObject **type, PyObject **value, PyObject **tb) {
6032 PyThreadState *tstate = PyThreadState_GET();
6033 *type = tstate->curexc_type;
6034 *value = tstate->curexc_value;
6035 *tb = tstate->curexc_traceback;
6037 tstate->curexc_type = 0;
6038 tstate->curexc_value = 0;
6039 tstate->curexc_traceback = 0;
6044 # The following function is based on do_raise() from ceval.c. There
6045 # are separate versions for Python2 and Python3 as exception handling
6046 # has changed quite a lot between the two versions.
6048 raise_utility_code = UtilityCode(
6050 static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
6053 #if PY_MAJOR_VERSION < 3
6054 static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb) {
6058 /* First, check the traceback argument, replacing None with NULL. */
6059 if (tb == Py_None) {
6063 else if (tb != NULL && !PyTraceBack_Check(tb)) {
6064 PyErr_SetString(PyExc_TypeError,
6065 "raise: arg 3 must be a traceback or None");
6068 /* Next, replace a missing value with None */
6069 if (value == NULL) {
6073 #if PY_VERSION_HEX < 0x02050000
6074 if (!PyClass_Check(type))
6076 if (!PyType_Check(type))
6079 /* Raising an instance. The value should be a dummy. */
6080 if (value != Py_None) {
6081 PyErr_SetString(PyExc_TypeError,
6082 "instance exception may not have a separate value");
6085 /* Normalize to raise <class>, <instance> */
6088 #if PY_VERSION_HEX < 0x02050000
6089 if (PyInstance_Check(type)) {
6090 type = (PyObject*) ((PyInstanceObject*)type)->in_class;
6095 PyErr_SetString(PyExc_TypeError,
6096 "raise: exception must be an old-style class or instance");
6100 type = (PyObject*) Py_TYPE(type);
6102 if (!PyType_IsSubtype((PyTypeObject *)type, (PyTypeObject *)PyExc_BaseException)) {
6103 PyErr_SetString(PyExc_TypeError,
6104 "raise: exception class must be a subclass of BaseException");
6110 __Pyx_ErrRestore(type, value, tb);
6119 #else /* Python 3+ */
6121 static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb) {
6122 if (tb == Py_None) {
6124 } else if (tb && !PyTraceBack_Check(tb)) {
6125 PyErr_SetString(PyExc_TypeError,
6126 "raise: arg 3 must be a traceback or None");
6129 if (value == Py_None)
6132 if (PyExceptionInstance_Check(type)) {
6134 PyErr_SetString(PyExc_TypeError,
6135 "instance exception may not have a separate value");
6139 type = (PyObject*) Py_TYPE(value);
6140 } else if (!PyExceptionClass_Check(type)) {
6141 PyErr_SetString(PyExc_TypeError,
6142 "raise: exception class must be a subclass of BaseException");
6146 PyErr_SetObject(type, value);
6149 PyThreadState *tstate = PyThreadState_GET();
6150 PyObject* tmp_tb = tstate->curexc_traceback;
6153 tstate->curexc_traceback = tb;
6163 requires=[restore_exception_utility_code])
6165 #------------------------------------------------------------------------------------
6167 get_exception_utility_code = UtilityCode(
6169 static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
6172 static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb) {
6173 PyObject *local_type, *local_value, *local_tb;
6174 PyObject *tmp_type, *tmp_value, *tmp_tb;
6175 PyThreadState *tstate = PyThreadState_GET();
6176 local_type = tstate->curexc_type;
6177 local_value = tstate->curexc_value;
6178 local_tb = tstate->curexc_traceback;
6179 tstate->curexc_type = 0;
6180 tstate->curexc_value = 0;
6181 tstate->curexc_traceback = 0;
6182 PyErr_NormalizeException(&local_type, &local_value, &local_tb);
6183 if (unlikely(tstate->curexc_type))
6185 #if PY_MAJOR_VERSION >= 3
6186 if (unlikely(PyException_SetTraceback(local_value, local_tb) < 0))
6190 *value = local_value;
6192 Py_INCREF(local_type);
6193 Py_INCREF(local_value);
6194 Py_INCREF(local_tb);
6195 tmp_type = tstate->exc_type;
6196 tmp_value = tstate->exc_value;
6197 tmp_tb = tstate->exc_traceback;
6198 tstate->exc_type = local_type;
6199 tstate->exc_value = local_value;
6200 tstate->exc_traceback = local_tb;
6201 /* Make sure tstate is in a consistent state when we XDECREF
6202 these objects (XDECREF may run arbitrary code). */
6203 Py_XDECREF(tmp_type);
6204 Py_XDECREF(tmp_value);
6211 Py_XDECREF(local_type);
6212 Py_XDECREF(local_value);
6213 Py_XDECREF(local_tb);
6219 #------------------------------------------------------------------------------------
6221 get_exception_tuple_utility_code = UtilityCode(proto="""
6222 static PyObject *__Pyx_GetExceptionTuple(void); /*proto*/
6224 # I doubt that calling __Pyx_GetException() here is correct as it moves
6225 # the exception from tstate->curexc_* to tstate->exc_*, which prevents
6226 # exception handlers later on from receiving it.
6228 static PyObject *__Pyx_GetExceptionTuple(void) {
6229 PyObject *type = NULL, *value = NULL, *tb = NULL;
6230 if (__Pyx_GetException(&type, &value, &tb) == 0) {
6231 PyObject* exc_info = PyTuple_New(3);
6236 PyTuple_SET_ITEM(exc_info, 0, type);
6237 PyTuple_SET_ITEM(exc_info, 1, value);
6238 PyTuple_SET_ITEM(exc_info, 2, tb);
6245 requires=[get_exception_utility_code])
6247 #------------------------------------------------------------------------------------
6249 reset_exception_utility_code = UtilityCode(
6251 static CYTHON_INLINE void __Pyx_ExceptionSave(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
6252 static void __Pyx_ExceptionReset(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
6255 static CYTHON_INLINE void __Pyx_ExceptionSave(PyObject **type, PyObject **value, PyObject **tb) {
6256 PyThreadState *tstate = PyThreadState_GET();
6257 *type = tstate->exc_type;
6258 *value = tstate->exc_value;
6259 *tb = tstate->exc_traceback;
6265 static void __Pyx_ExceptionReset(PyObject *type, PyObject *value, PyObject *tb) {
6266 PyObject *tmp_type, *tmp_value, *tmp_tb;
6267 PyThreadState *tstate = PyThreadState_GET();
6268 tmp_type = tstate->exc_type;
6269 tmp_value = tstate->exc_value;
6270 tmp_tb = tstate->exc_traceback;
6271 tstate->exc_type = type;
6272 tstate->exc_value = value;
6273 tstate->exc_traceback = tb;
6274 Py_XDECREF(tmp_type);
6275 Py_XDECREF(tmp_value);
6280 #------------------------------------------------------------------------------------
6282 swap_exception_utility_code = UtilityCode(
6284 static CYTHON_INLINE void __Pyx_ExceptionSwap(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
6287 static CYTHON_INLINE void __Pyx_ExceptionSwap(PyObject **type, PyObject **value, PyObject **tb) {
6288 PyObject *tmp_type, *tmp_value, *tmp_tb;
6289 PyThreadState *tstate = PyThreadState_GET();
6291 tmp_type = tstate->exc_type;
6292 tmp_value = tstate->exc_value;
6293 tmp_tb = tstate->exc_traceback;
6295 tstate->exc_type = *type;
6296 tstate->exc_value = *value;
6297 tstate->exc_traceback = *tb;
6305 #------------------------------------------------------------------------------------
6307 arg_type_test_utility_code = UtilityCode(
6309 static int __Pyx_ArgTypeTest(PyObject *obj, PyTypeObject *type, int none_allowed,
6310 const char *name, int exact); /*proto*/
6313 static int __Pyx_ArgTypeTest(PyObject *obj, PyTypeObject *type, int none_allowed,
6314 const char *name, int exact)
6317 PyErr_Format(PyExc_SystemError, "Missing type object");
6320 if (none_allowed && obj == Py_None) return 1;
6322 if (Py_TYPE(obj) == type) return 1;
6325 if (PyObject_TypeCheck(obj, type)) return 1;
6327 PyErr_Format(PyExc_TypeError,
6328 "Argument '%s' has incorrect type (expected %s, got %s)",
6329 name, type->tp_name, Py_TYPE(obj)->tp_name);
6334 #------------------------------------------------------------------------------------
6336 # __Pyx_RaiseArgtupleInvalid raises the correct exception when too
6337 # many or too few positional arguments were found. This handles
6338 # Py_ssize_t formatting correctly.
6340 raise_argtuple_invalid_utility_code = UtilityCode(
6342 static void __Pyx_RaiseArgtupleInvalid(const char* func_name, int exact,
6343 Py_ssize_t num_min, Py_ssize_t num_max, Py_ssize_t num_found); /*proto*/
6346 static void __Pyx_RaiseArgtupleInvalid(
6347 const char* func_name,
6351 Py_ssize_t num_found)
6353 Py_ssize_t num_expected;
6354 const char *number, *more_or_less;
6356 if (num_found < num_min) {
6357 num_expected = num_min;
6358 more_or_less = "at least";
6360 num_expected = num_max;
6361 more_or_less = "at most";
6364 more_or_less = "exactly";
6366 number = (num_expected == 1) ? "" : "s";
6367 PyErr_Format(PyExc_TypeError,
6368 #if PY_VERSION_HEX < 0x02050000
6369 "%s() takes %s %d positional argument%s (%d given)",
6371 "%s() takes %s %zd positional argument%s (%zd given)",
6373 func_name, more_or_less, num_expected, number, num_found);
6377 raise_keyword_required_utility_code = UtilityCode(
6379 static CYTHON_INLINE void __Pyx_RaiseKeywordRequired(const char* func_name, PyObject* kw_name); /*proto*/
6382 static CYTHON_INLINE void __Pyx_RaiseKeywordRequired(
6383 const char* func_name,
6386 PyErr_Format(PyExc_TypeError,
6387 #if PY_MAJOR_VERSION >= 3
6388 "%s() needs keyword-only argument %U", func_name, kw_name);
6390 "%s() needs keyword-only argument %s", func_name,
6391 PyString_AS_STRING(kw_name));
6396 raise_double_keywords_utility_code = UtilityCode(
6398 static void __Pyx_RaiseDoubleKeywordsError(
6399 const char* func_name, PyObject* kw_name); /*proto*/
6402 static void __Pyx_RaiseDoubleKeywordsError(
6403 const char* func_name,
6406 PyErr_Format(PyExc_TypeError,
6407 #if PY_MAJOR_VERSION >= 3
6408 "%s() got multiple values for keyword argument '%U'", func_name, kw_name);
6410 "%s() got multiple values for keyword argument '%s'", func_name,
6411 PyString_AS_STRING(kw_name));
6416 #------------------------------------------------------------------------------------
6418 # __Pyx_CheckKeywordStrings raises an error if non-string keywords
6419 # were passed to a function, or if any keywords were passed to a
6420 # function that does not accept them.
6422 keyword_string_check_utility_code = UtilityCode(
6424 static CYTHON_INLINE int __Pyx_CheckKeywordStrings(PyObject *kwdict,
6425 const char* function_name, int kw_allowed); /*proto*/
6428 static CYTHON_INLINE int __Pyx_CheckKeywordStrings(
6430 const char* function_name,
6435 while (PyDict_Next(kwdict, &pos, &key, 0)) {
6436 #if PY_MAJOR_VERSION < 3
6437 if (unlikely(!PyString_CheckExact(key)) && unlikely(!PyString_Check(key)))
6439 if (unlikely(!PyUnicode_CheckExact(key)) && unlikely(!PyUnicode_Check(key)))
6441 goto invalid_keyword_type;
6443 if ((!kw_allowed) && unlikely(key))
6444 goto invalid_keyword;
6446 invalid_keyword_type:
6447 PyErr_Format(PyExc_TypeError,
6448 "%s() keywords must be strings", function_name);
6451 PyErr_Format(PyExc_TypeError,
6452 #if PY_MAJOR_VERSION < 3
6453 "%s() got an unexpected keyword argument '%s'",
6454 function_name, PyString_AsString(key));
6456 "%s() got an unexpected keyword argument '%U'",
6457 function_name, key);
6463 #------------------------------------------------------------------------------------
6465 # __Pyx_ParseOptionalKeywords copies the optional/unknown keyword
6466 # arguments from the kwds dict into kwds2. If kwds2 is NULL, unknown
6467 # keywords will raise an invalid keyword error.
6469 # Three kinds of errors are checked: 1) non-string keywords, 2)
6470 # unexpected keywords and 3) overlap with positional arguments.
6472 # If num_posargs is greater 0, it denotes the number of positional
6473 # arguments that were passed and that must therefore not appear
6474 # amongst the keywords as well.
6476 # This method does not check for required keyword arguments.
6479 parse_keywords_utility_code = UtilityCode(
6481 static int __Pyx_ParseOptionalKeywords(PyObject *kwds, PyObject **argnames[], \
6482 PyObject *kwds2, PyObject *values[], Py_ssize_t num_pos_args, \
6483 const char* function_name); /*proto*/
6486 static int __Pyx_ParseOptionalKeywords(
6488 PyObject **argnames[],
6491 Py_ssize_t num_pos_args,
6492 const char* function_name)
6494 PyObject *key = 0, *value = 0;
6497 PyObject*** first_kw_arg = argnames + num_pos_args;
6499 while (PyDict_Next(kwds, &pos, &key, &value)) {
6500 name = first_kw_arg;
6501 while (*name && (**name != key)) name++;
6503 values[name-argnames] = value;
6505 #if PY_MAJOR_VERSION < 3
6506 if (unlikely(!PyString_CheckExact(key)) && unlikely(!PyString_Check(key))) {
6508 if (unlikely(!PyUnicode_CheckExact(key)) && unlikely(!PyUnicode_Check(key))) {
6510 goto invalid_keyword_type;
6512 for (name = first_kw_arg; *name; name++) {
6513 #if PY_MAJOR_VERSION >= 3
6514 if (PyUnicode_GET_SIZE(**name) == PyUnicode_GET_SIZE(key) &&
6515 PyUnicode_Compare(**name, key) == 0) break;
6517 if (PyString_GET_SIZE(**name) == PyString_GET_SIZE(key) &&
6518 _PyString_Eq(**name, key)) break;
6522 values[name-argnames] = value;
6524 /* unexpected keyword found */
6525 for (name=argnames; name != first_kw_arg; name++) {
6526 if (**name == key) goto arg_passed_twice;
6527 #if PY_MAJOR_VERSION >= 3
6528 if (PyUnicode_GET_SIZE(**name) == PyUnicode_GET_SIZE(key) &&
6529 PyUnicode_Compare(**name, key) == 0) goto arg_passed_twice;
6531 if (PyString_GET_SIZE(**name) == PyString_GET_SIZE(key) &&
6532 _PyString_Eq(**name, key)) goto arg_passed_twice;
6536 if (unlikely(PyDict_SetItem(kwds2, key, value))) goto bad;
6538 goto invalid_keyword;
6546 __Pyx_RaiseDoubleKeywordsError(function_name, **name);
6548 invalid_keyword_type:
6549 PyErr_Format(PyExc_TypeError,
6550 "%s() keywords must be strings", function_name);
6553 PyErr_Format(PyExc_TypeError,
6554 #if PY_MAJOR_VERSION < 3
6555 "%s() got an unexpected keyword argument '%s'",
6556 function_name, PyString_AsString(key));
6558 "%s() got an unexpected keyword argument '%U'",
6559 function_name, key);
6565 requires=[raise_double_keywords_utility_code])
6567 #------------------------------------------------------------------------------------
6569 traceback_utility_code = UtilityCode(
6571 static void __Pyx_AddTraceback(const char *funcname); /*proto*/
6574 #include "compile.h"
6575 #include "frameobject.h"
6576 #include "traceback.h"
6578 static void __Pyx_AddTraceback(const char *funcname) {
6579 PyObject *py_srcfile = 0;
6580 PyObject *py_funcname = 0;
6581 PyObject *py_globals = 0;
6582 PyCodeObject *py_code = 0;
6583 PyFrameObject *py_frame = 0;
6585 #if PY_MAJOR_VERSION < 3
6586 py_srcfile = PyString_FromString(%(FILENAME)s);
6588 py_srcfile = PyUnicode_FromString(%(FILENAME)s);
6590 if (!py_srcfile) goto bad;
6592 #if PY_MAJOR_VERSION < 3
6593 py_funcname = PyString_FromFormat( "%%s (%%s:%%d)", funcname, %(CFILENAME)s, %(CLINENO)s);
6595 py_funcname = PyUnicode_FromFormat( "%%s (%%s:%%d)", funcname, %(CFILENAME)s, %(CLINENO)s);
6599 #if PY_MAJOR_VERSION < 3
6600 py_funcname = PyString_FromString(funcname);
6602 py_funcname = PyUnicode_FromString(funcname);
6605 if (!py_funcname) goto bad;
6606 py_globals = PyModule_GetDict(%(GLOBALS)s);
6607 if (!py_globals) goto bad;
6608 py_code = PyCode_New(
6609 0, /*int argcount,*/
6610 #if PY_MAJOR_VERSION >= 3
6611 0, /*int kwonlyargcount,*/
6614 0, /*int stacksize,*/
6616 %(EMPTY_BYTES)s, /*PyObject *code,*/
6617 %(EMPTY_TUPLE)s, /*PyObject *consts,*/
6618 %(EMPTY_TUPLE)s, /*PyObject *names,*/
6619 %(EMPTY_TUPLE)s, /*PyObject *varnames,*/
6620 %(EMPTY_TUPLE)s, /*PyObject *freevars,*/
6621 %(EMPTY_TUPLE)s, /*PyObject *cellvars,*/
6622 py_srcfile, /*PyObject *filename,*/
6623 py_funcname, /*PyObject *name,*/
6624 %(LINENO)s, /*int firstlineno,*/
6625 %(EMPTY_BYTES)s /*PyObject *lnotab*/
6627 if (!py_code) goto bad;
6628 py_frame = PyFrame_New(
6629 PyThreadState_GET(), /*PyThreadState *tstate,*/
6630 py_code, /*PyCodeObject *code,*/
6631 py_globals, /*PyObject *globals,*/
6632 0 /*PyObject *locals*/
6634 if (!py_frame) goto bad;
6635 py_frame->f_lineno = %(LINENO)s;
6636 PyTraceBack_Here(py_frame);
6638 Py_XDECREF(py_srcfile);
6639 Py_XDECREF(py_funcname);
6640 Py_XDECREF(py_code);
6641 Py_XDECREF(py_frame);
6644 'FILENAME': Naming.filename_cname,
6645 'LINENO': Naming.lineno_cname,
6646 'CFILENAME': Naming.cfilenm_cname,
6647 'CLINENO': Naming.clineno_cname,
6648 'GLOBALS': Naming.module_cname,
6649 'EMPTY_TUPLE' : Naming.empty_tuple,
6650 'EMPTY_BYTES' : Naming.empty_bytes,
6653 #------------------------------------------------------------------------------------
6655 unraisable_exception_utility_code = UtilityCode(
6657 static void __Pyx_WriteUnraisable(const char *name); /*proto*/
6660 static void __Pyx_WriteUnraisable(const char *name) {
6661 PyObject *old_exc, *old_val, *old_tb;
6663 __Pyx_ErrFetch(&old_exc, &old_val, &old_tb);
6664 #if PY_MAJOR_VERSION < 3
6665 ctx = PyString_FromString(name);
6667 ctx = PyUnicode_FromString(name);
6669 __Pyx_ErrRestore(old_exc, old_val, old_tb);
6671 PyErr_WriteUnraisable(Py_None);
6673 PyErr_WriteUnraisable(ctx);
6678 requires=[restore_exception_utility_code])
6680 #------------------------------------------------------------------------------------
6682 set_vtable_utility_code = UtilityCode(
6684 static int __Pyx_SetVtable(PyObject *dict, void *vtable); /*proto*/
6687 static int __Pyx_SetVtable(PyObject *dict, void *vtable) {
6688 #if PY_VERSION_HEX >= 0x02070000 && !(PY_MAJOR_VERSION==3&&PY_MINOR_VERSION==0)
6689 PyObject *ob = PyCapsule_New(vtable, 0, 0);
6691 PyObject *ob = PyCObject_FromVoidPtr(vtable, 0);
6695 if (PyDict_SetItemString(dict, "__pyx_vtable__", ob) < 0)
6705 #------------------------------------------------------------------------------------
6707 get_vtable_utility_code = UtilityCode(
6709 static void* __Pyx_GetVtable(PyObject *dict); /*proto*/
6712 static void* __Pyx_GetVtable(PyObject *dict) {
6714 PyObject *ob = PyMapping_GetItemString(dict, (char *)"__pyx_vtable__");
6717 #if PY_VERSION_HEX >= 0x02070000 && !(PY_MAJOR_VERSION==3&&PY_MINOR_VERSION==0)
6718 ptr = PyCapsule_GetPointer(ob, 0);
6720 ptr = PyCObject_AsVoidPtr(ob);
6722 if (!ptr && !PyErr_Occurred())
6723 PyErr_SetString(PyExc_RuntimeError, "invalid vtable found for imported type");
6732 #------------------------------------------------------------------------------------
6734 init_string_tab_utility_code = UtilityCode(
6736 static int __Pyx_InitStrings(__Pyx_StringTabEntry *t); /*proto*/
6739 static int __Pyx_InitStrings(__Pyx_StringTabEntry *t) {
6741 #if PY_MAJOR_VERSION < 3
6742 if (t->is_unicode) {
6743 *t->p = PyUnicode_DecodeUTF8(t->s, t->n - 1, NULL);
6744 } else if (t->intern) {
6745 *t->p = PyString_InternFromString(t->s);
6747 *t->p = PyString_FromStringAndSize(t->s, t->n - 1);
6749 #else /* Python 3+ has unicode identifiers */
6750 if (t->is_unicode | t->is_str) {
6752 *t->p = PyUnicode_InternFromString(t->s);
6753 } else if (t->encoding) {
6754 *t->p = PyUnicode_Decode(t->s, t->n - 1, t->encoding, NULL);
6756 *t->p = PyUnicode_FromStringAndSize(t->s, t->n - 1);
6759 *t->p = PyBytes_FromStringAndSize(t->s, t->n - 1);
6770 #------------------------------------------------------------------------------------
6772 force_init_threads_utility_code = UtilityCode(
6774 #ifndef __PYX_FORCE_INIT_THREADS
6775 #if PY_VERSION_HEX < 0x02040200
6776 #define __PYX_FORCE_INIT_THREADS 1
6778 #define __PYX_FORCE_INIT_THREADS 0
6783 #------------------------------------------------------------------------------------
6785 # Note that cPython ignores PyTrace_EXCEPTION,
6786 # but maybe some other profilers don't.
6788 profile_utility_code = UtilityCode(proto="""
6789 #ifndef CYTHON_PROFILE
6790 #define CYTHON_PROFILE 1
6793 #ifndef CYTHON_PROFILE_REUSE_FRAME
6794 #define CYTHON_PROFILE_REUSE_FRAME 0
6799 #include "compile.h"
6800 #include "frameobject.h"
6801 #include "traceback.h"
6803 #if CYTHON_PROFILE_REUSE_FRAME
6804 #define CYTHON_FRAME_MODIFIER static
6805 #define CYTHON_FRAME_DEL
6807 #define CYTHON_FRAME_MODIFIER
6808 #define CYTHON_FRAME_DEL Py_DECREF(%(FRAME)s)
6811 #define __Pyx_TraceDeclarations \\
6812 static PyCodeObject *%(FRAME_CODE)s = NULL; \\
6813 CYTHON_FRAME_MODIFIER PyFrameObject *%(FRAME)s = NULL; \\
6814 int __Pyx_use_tracing = 0;
6816 #define __Pyx_TraceCall(funcname, srcfile, firstlineno) \\
6817 if (unlikely(PyThreadState_GET()->use_tracing && PyThreadState_GET()->c_profilefunc)) { \\
6818 __Pyx_use_tracing = __Pyx_TraceSetupAndCall(&%(FRAME_CODE)s, &%(FRAME)s, funcname, srcfile, firstlineno); \\
6821 #define __Pyx_TraceException() \\
6822 if (unlikely(__Pyx_use_tracing( && PyThreadState_GET()->use_tracing && PyThreadState_GET()->c_profilefunc) { \\
6823 PyObject *exc_info = __Pyx_GetExceptionTuple(); \\
6825 PyThreadState_GET()->c_profilefunc( \\
6826 PyThreadState_GET()->c_profileobj, %(FRAME)s, PyTrace_EXCEPTION, exc_info); \\
6827 Py_DECREF(exc_info); \\
6831 #define __Pyx_TraceReturn(result) \\
6832 if (unlikely(__Pyx_use_tracing) && PyThreadState_GET()->use_tracing && PyThreadState_GET()->c_profilefunc) { \\
6833 PyThreadState_GET()->c_profilefunc( \\
6834 PyThreadState_GET()->c_profileobj, %(FRAME)s, PyTrace_RETURN, (PyObject*)result); \\
6835 CYTHON_FRAME_DEL; \\
6838 static PyCodeObject *__Pyx_createFrameCodeObject(const char *funcname, const char *srcfile, int firstlineno); /*proto*/
6839 static int __Pyx_TraceSetupAndCall(PyCodeObject** code, PyFrameObject** frame, const char *funcname, const char *srcfile, int firstlineno); /*proto*/
6843 #define __Pyx_TraceDeclarations
6844 #define __Pyx_TraceCall(funcname, srcfile, firstlineno)
6845 #define __Pyx_TraceException()
6846 #define __Pyx_TraceReturn(result)
6848 #endif /* CYTHON_PROFILE */
6851 "FRAME": Naming.frame_cname,
6852 "FRAME_CODE": Naming.frame_code_cname,
6858 static int __Pyx_TraceSetupAndCall(PyCodeObject** code,
6859 PyFrameObject** frame,
6860 const char *funcname,
6861 const char *srcfile,
6863 if (*frame == NULL || !CYTHON_PROFILE_REUSE_FRAME) {
6864 if (*code == NULL) {
6865 *code = __Pyx_createFrameCodeObject(funcname, srcfile, firstlineno);
6866 if (*code == NULL) return 0;
6868 *frame = PyFrame_New(
6869 PyThreadState_GET(), /*PyThreadState *tstate*/
6870 *code, /*PyCodeObject *code*/
6871 PyModule_GetDict(%(MODULE)s), /*PyObject *globals*/
6872 0 /*PyObject *locals*/
6874 if (*frame == NULL) return 0;
6877 (*frame)->f_tstate = PyThreadState_GET();
6879 return PyThreadState_GET()->c_profilefunc(PyThreadState_GET()->c_profileobj, *frame, PyTrace_CALL, NULL) == 0;
6882 static PyCodeObject *__Pyx_createFrameCodeObject(const char *funcname, const char *srcfile, int firstlineno) {
6883 PyObject *py_srcfile = 0;
6884 PyObject *py_funcname = 0;
6885 PyCodeObject *py_code = 0;
6887 #if PY_MAJOR_VERSION < 3
6888 py_funcname = PyString_FromString(funcname);
6889 py_srcfile = PyString_FromString(srcfile);
6891 py_funcname = PyUnicode_FromString(funcname);
6892 py_srcfile = PyUnicode_FromString(srcfile);
6894 if (!py_funcname | !py_srcfile) goto bad;
6896 py_code = PyCode_New(
6897 0, /*int argcount,*/
6898 #if PY_MAJOR_VERSION >= 3
6899 0, /*int kwonlyargcount,*/
6902 0, /*int stacksize,*/
6904 %(EMPTY_BYTES)s, /*PyObject *code,*/
6905 %(EMPTY_TUPLE)s, /*PyObject *consts,*/
6906 %(EMPTY_TUPLE)s, /*PyObject *names,*/
6907 %(EMPTY_TUPLE)s, /*PyObject *varnames,*/
6908 %(EMPTY_TUPLE)s, /*PyObject *freevars,*/
6909 %(EMPTY_TUPLE)s, /*PyObject *cellvars,*/
6910 py_srcfile, /*PyObject *filename,*/
6911 py_funcname, /*PyObject *name,*/
6912 firstlineno, /*int firstlineno,*/
6913 %(EMPTY_BYTES)s /*PyObject *lnotab*/
6917 Py_XDECREF(py_srcfile);
6918 Py_XDECREF(py_funcname);
6923 #endif /* CYTHON_PROFILE */
6925 'EMPTY_TUPLE' : Naming.empty_tuple,
6926 'EMPTY_BYTES' : Naming.empty_bytes,
6927 "MODULE": Naming.module_cname,