3 # Pyrex - Parse tree nodes
8 cython.declare(sys=object, os=object, time=object, copy=object,
9 Builtin=object, error=object, warning=object, Naming=object, PyrexTypes=object,
10 py_object_type=object, ModuleScope=object, LocalScope=object, ClosureScope=object, \
11 StructOrUnionScope=object, PyClassScope=object, CClassScope=object,
12 CppClassScope=object, UtilityCode=object, EncodedString=object,
13 absolute_path_length=cython.Py_ssize_t)
15 import sys, os, time, copy
18 from Errors import error, warning, InternalError
22 from PyrexTypes import py_object_type, error_type, CFuncType
23 from Symtab import ModuleScope, LocalScope, ClosureScope, \
24 StructOrUnionScope, PyClassScope, CClassScope, CppClassScope
25 from Cython.Utils import open_new_file, replace_suffix
26 from Code import UtilityCode
27 from StringEncoding import EncodedString, escape_byte_string, split_string_literal
32 absolute_path_length = 0
34 def relative_position(pos):
36 We embed the relative filename in the generated C file, since we
37 don't want to have to regnerate and compile all the source code
38 whenever the Python install directory moves (which could happen,
39 e.g,. when distributing binaries.)
42 a position tuple -- (absolute filename, line number column position)
50 global absolute_path_length
51 if absolute_path_length==0:
52 absolute_path_length = len(os.path.abspath(os.getcwd()))
53 return (pos[0].get_filenametable_entry()[absolute_path_length+1:], pos[1])
55 def embed_position(pos, docstring):
56 if not Options.embed_pos_in_docstring:
58 pos_line = u'File: %s (starting at line %s)' % relative_position(pos)
61 return EncodedString(pos_line)
63 # make sure we can encode the filename in the docstring encoding
64 # otherwise make the docstring a unicode string
65 encoding = docstring.encoding
66 if encoding is not None:
68 encoded_bytes = pos_line.encode(encoding)
69 except UnicodeEncodeError:
73 # reuse the string encoding of the original docstring
74 doc = EncodedString(pos_line)
76 doc = EncodedString(pos_line + u'\n' + docstring)
77 doc.encoding = encoding
81 from Code import CCodeWriter
82 from types import FunctionType
84 def write_func_call(func):
86 if len(args) > 1 and isinstance(args[1], CCodeWriter):
87 # here we annotate the code with this function call
88 # but only if new code is generated
90 marker = ' /* %s -> %s.%s %s */' % (
91 ' ' * code.call_level,
92 node.__class__.__name__,
95 pristine = code.buffer.stream.tell()
97 start = code.buffer.stream.tell()
99 res = func(*args, **kwds)
101 if start == code.buffer.stream.tell():
102 code.buffer.stream.seek(pristine)
104 marker = marker.replace('->', '<-')
108 return func(*args, **kwds)
111 class VerboseCodeWriter(type):
112 # Set this as a metaclass to trace function calls in code.
113 # This slows down code generation and makes much larger files.
114 def __new__(cls, name, bases, attrs):
116 for mname, m in attrs.items():
117 if isinstance(m, FunctionType):
118 attrs[mname] = write_func_call(m)
119 return super(VerboseCodeWriter, cls).__new__(cls, name, bases, attrs)
123 # pos (string, int, int) Source file position
124 # is_name boolean Is a NameNode
125 # is_literal boolean Is a ConstNode
127 if DebugFlags.debug_trace_code_generation:
128 __metaclass__ = VerboseCodeWriter
134 # All descandants should set child_attrs to a list of the attributes
135 # containing nodes considered "children" in the tree. Each such attribute
136 # can either contain a single node or a list of nodes. See Visitor.py.
139 def __init__(self, pos, **kw):
141 self.__dict__.update(kw)
143 gil_message = "Operation"
147 def gil_error(self, env=None):
148 error(self.pos, "%s not allowed without gil" % self.gil_message)
150 cpp_message = "Operation"
152 def cpp_check(self, env):
157 error(self.pos, "%s only allowed in c++" % self.cpp_message)
159 def clone_node(self):
160 """Clone the node. This is defined as a shallow copy, except for member lists
161 amongst the child attributes (from get_child_accessors) which are also
162 copied. Lists containing child nodes are thus seen as a way for the node
163 to hold multiple children directly; the list is not treated as a seperate
164 level in the tree."""
165 result = copy.copy(self)
166 for attrname in result.child_attrs:
167 value = getattr(result, attrname)
168 if isinstance(value, list):
169 setattr(result, attrname, [x for x in value])
174 # There are 4 phases of parse tree processing, applied in order to
175 # all the statements in a given scope-block:
177 # (0) analyse_control_flow
178 # Create the control flow tree into which state can be asserted and
181 # (1) analyse_declarations
182 # Make symbol table entries for all declarations at the current
183 # level, both explicit (def, cdef, etc.) and implicit (assignment
184 # to an otherwise undeclared name).
186 # (2) analyse_expressions
187 # Determine the result types of expressions and fill in the
188 # 'type' attribute of each ExprNode. Insert coercion nodes into the
189 # tree where needed to convert to and from Python objects.
190 # Allocate temporary locals for intermediate results. Fill
191 # in the 'result_code' attribute of each ExprNode with a C code
195 # Emit C code for all declarations, statements and expressions.
196 # Recursively applies the 3 processing phases to the bodies of
200 def analyse_control_flow(self, env):
203 def analyse_declarations(self, env):
206 def analyse_expressions(self, env):
207 raise InternalError("analyse_expressions not implemented for %s" % \
208 self.__class__.__name__)
210 def generate_code(self, code):
211 raise InternalError("generate_code not implemented for %s" % \
212 self.__class__.__name__)
214 def annotate(self, code):
215 # mro does the wrong thing
216 if isinstance(self, BlockNode):
217 self.body.annotate(code)
222 except AttributeError:
224 if not self.child_attrs:
227 for attr in self.child_attrs:
228 child = getattr(self, attr)
229 # Sometimes lists, sometimes nodes
232 elif isinstance(child, list):
234 pos = max(pos, c.end_pos())
236 pos = max(pos, child.end_pos())
240 def dump(self, level=0, filter_out=("pos",), cutoff=100, encountered=None):
242 return "<...nesting level cutoff...>"
243 if encountered is None:
245 if id(self) in encountered:
246 return "<%s (0x%x) -- already output>" % (self.__class__.__name__, id(self))
247 encountered.add(id(self))
249 def dump_child(x, level):
250 if isinstance(x, Node):
251 return x.dump(level, filter_out, cutoff-1, encountered)
252 elif isinstance(x, list):
253 return "[%s]" % ", ".join([dump_child(item, level) for item in x])
258 attrs = [(key, value) for key, value in self.__dict__.items() if key not in filter_out]
260 return "<%s (0x%x)>" % (self.__class__.__name__, id(self))
263 res = "<%s (0x%x)\n" % (self.__class__.__name__, id(self))
264 for key, value in attrs:
265 res += "%s %s: %s\n" % (indent, key, dump_child(value, level + 1))
266 res += "%s>" % indent
269 class CompilerDirectivesNode(Node):
271 Sets compiler directives for the children nodes
273 # directives {string:value} A dictionary holding the right value for
274 # *all* possible directives.
276 child_attrs = ["body"]
278 def analyse_control_flow(self, env):
280 env.directives = self.directives
281 self.body.analyse_control_flow(env)
284 def analyse_declarations(self, env):
286 env.directives = self.directives
287 self.body.analyse_declarations(env)
290 def analyse_expressions(self, env):
292 env.directives = self.directives
293 self.body.analyse_expressions(env)
296 def generate_function_definitions(self, env, code):
297 env_old = env.directives
298 code_old = code.globalstate.directives
299 code.globalstate.directives = self.directives
300 self.body.generate_function_definitions(env, code)
301 env.directives = env_old
302 code.globalstate.directives = code_old
304 def generate_execution_code(self, code):
305 old = code.globalstate.directives
306 code.globalstate.directives = self.directives
307 self.body.generate_execution_code(code)
308 code.globalstate.directives = old
310 def annotate(self, code):
311 old = code.globalstate.directives
312 code.globalstate.directives = self.directives
313 self.body.annotate(code)
314 code.globalstate.directives = old
316 class BlockNode(object):
317 # Mixin class for nodes representing a declaration block.
319 def generate_cached_builtins_decls(self, env, code):
320 entries = env.global_scope().undeclared_cached_builtins
321 for entry in entries:
322 code.globalstate.add_cached_builtin_decl(entry)
326 class StatListNode(Node):
327 # stats a list of StatNode
329 child_attrs = ["stats"]
331 def create_analysed(pos, env, *args, **kw):
332 node = StatListNode(pos, *args, **kw)
333 return node # No node-specific analysis necesarry
334 create_analysed = staticmethod(create_analysed)
336 def analyse_control_flow(self, env):
337 for stat in self.stats:
338 stat.analyse_control_flow(env)
340 def analyse_declarations(self, env):
341 #print "StatListNode.analyse_declarations" ###
342 for stat in self.stats:
343 stat.analyse_declarations(env)
345 def analyse_expressions(self, env):
346 #print "StatListNode.analyse_expressions" ###
347 for stat in self.stats:
348 stat.analyse_expressions(env)
350 def generate_function_definitions(self, env, code):
351 #print "StatListNode.generate_function_definitions" ###
352 for stat in self.stats:
353 stat.generate_function_definitions(env, code)
355 def generate_execution_code(self, code):
356 #print "StatListNode.generate_execution_code" ###
357 for stat in self.stats:
358 code.mark_pos(stat.pos)
359 stat.generate_execution_code(code)
361 def annotate(self, code):
362 for stat in self.stats:
366 class StatNode(Node):
368 # Code generation for statements is split into the following subphases:
370 # (1) generate_function_definitions
371 # Emit C code for the definitions of any structs,
372 # unions, enums and functions defined in the current
375 # (2) generate_execution_code
376 # Emit C code for executable statements.
379 def generate_function_definitions(self, env, code):
382 def generate_execution_code(self, code):
383 raise InternalError("generate_execution_code not implemented for %s" % \
384 self.__class__.__name__)
387 class CDefExternNode(StatNode):
388 # include_file string or None
391 child_attrs = ["body"]
393 def analyse_declarations(self, env):
394 if self.include_file:
395 env.add_include_file(self.include_file)
396 old_cinclude_flag = env.in_cinclude
398 self.body.analyse_declarations(env)
399 env.in_cinclude = old_cinclude_flag
401 def analyse_expressions(self, env):
404 def generate_execution_code(self, code):
407 def annotate(self, code):
408 self.body.annotate(code)
411 class CDeclaratorNode(Node):
412 # Part of a C declaration.
414 # Processing during analyse_declarations phase:
417 # Returns (name, type) pair where name is the
418 # CNameDeclaratorNode of the name being declared
419 # and type is the type it is being declared as.
421 # calling_convention string Calling convention of CFuncDeclaratorNode
422 # for which this is a base
426 calling_convention = ""
429 class CNameDeclaratorNode(CDeclaratorNode):
430 # name string The Pyrex name being declared
431 # cname string or None C name, if specified
432 # default ExprNode or None the value assigned on declaration
434 child_attrs = ['default']
438 def analyse(self, base_type, env, nonempty = 0):
439 if nonempty and self.name == '':
440 # May have mistaken the name for the type.
441 if base_type.is_ptr or base_type.is_array or base_type.is_buffer:
442 error(self.pos, "Missing argument name")
443 elif base_type.is_void:
444 error(self.pos, "Use spam() rather than spam(void) to declare a function with no arguments.")
446 self.name = base_type.declaration_code("", for_display=1, pyrex=1)
447 base_type = py_object_type
448 self.type = base_type
449 return self, base_type
451 class CPtrDeclaratorNode(CDeclaratorNode):
452 # base CDeclaratorNode
454 child_attrs = ["base"]
456 def analyse(self, base_type, env, nonempty = 0):
457 if base_type.is_pyobject:
459 "Pointer base type cannot be a Python object")
460 ptr_type = PyrexTypes.c_ptr_type(base_type)
461 return self.base.analyse(ptr_type, env, nonempty = nonempty)
463 class CReferenceDeclaratorNode(CDeclaratorNode):
464 # base CDeclaratorNode
466 child_attrs = ["base"]
468 def analyse(self, base_type, env, nonempty = 0):
469 if base_type.is_pyobject:
471 "Reference base type cannot be a Python object")
472 ref_type = PyrexTypes.c_ref_type(base_type)
473 return self.base.analyse(ref_type, env, nonempty = nonempty)
475 class CArrayDeclaratorNode(CDeclaratorNode):
476 # base CDeclaratorNode
479 child_attrs = ["base", "dimension"]
481 def analyse(self, base_type, env, nonempty = 0):
482 if base_type.is_cpp_class:
483 from ExprNodes import TupleNode
484 if isinstance(self.dimension, TupleNode):
485 args = self.dimension.args
487 args = self.dimension,
488 values = [v.analyse_as_type(env) for v in args]
490 ix = values.index(None)
491 error(args[ix].pos, "Template parameter not a type.")
493 base_type = base_type.specialize_here(self.pos, values)
494 return self.base.analyse(base_type, env, nonempty = nonempty)
496 self.dimension.analyse_const_expression(env)
497 if not self.dimension.type.is_int:
498 error(self.dimension.pos, "Array dimension not integer")
499 size = self.dimension.get_constant_c_result_code()
508 if not base_type.is_complete():
510 "Array element type '%s' is incomplete" % base_type)
511 if base_type.is_pyobject:
513 "Array element cannot be a Python object")
514 if base_type.is_cfunction:
516 "Array element cannot be a function")
517 array_type = PyrexTypes.c_array_type(base_type, size)
518 return self.base.analyse(array_type, env, nonempty = nonempty)
521 class CFuncDeclaratorNode(CDeclaratorNode):
522 # base CDeclaratorNode
523 # args [CArgDeclNode]
524 # has_varargs boolean
525 # exception_value ConstNode
526 # exception_check boolean True if PyErr_Occurred check needed
527 # nogil boolean Can be called without gil
528 # with_gil boolean Acquire gil around function body
530 child_attrs = ["base", "args", "exception_value"]
533 optional_arg_count = 0
535 def analyse(self, return_type, env, nonempty = 0):
539 for i, arg_node in enumerate(self.args):
540 name_declarator, type = arg_node.analyse(env, nonempty = nonempty,
541 is_self_arg = (i == 0 and env.is_c_class_scope))
542 name = name_declarator.name
543 if name_declarator.cname:
545 "Function argument cannot have C name specification")
546 # Turn *[] argument into **
548 type = PyrexTypes.c_ptr_type(type.base_type)
549 # Catch attempted C-style func(void) decl
551 error(arg_node.pos, "Use spam() rather than spam(void) to declare a function with no arguments.")
552 func_type_args.append(
553 PyrexTypes.CFuncTypeArg(name, type, arg_node.pos))
555 self.optional_arg_count += 1
556 elif self.optional_arg_count:
557 error(self.pos, "Non-default argument follows default argument")
559 if self.optional_arg_count:
560 scope = StructOrUnionScope()
561 arg_count_member = '%sn' % Naming.pyrex_prefix
562 scope.declare_var(arg_count_member, PyrexTypes.c_int_type, self.pos)
563 for arg in func_type_args[len(func_type_args)-self.optional_arg_count:]:
564 scope.declare_var(arg.name, arg.type, arg.pos, allow_pyobject = 1)
565 struct_cname = env.mangle(Naming.opt_arg_prefix, self.base.name)
566 self.op_args_struct = env.global_scope().declare_struct_or_union(name = struct_cname,
571 cname = struct_cname)
572 self.op_args_struct.defined_in_pxd = 1
573 self.op_args_struct.used = 1
577 if self.exception_check == '+':
578 env.add_include_file('stdexcept')
579 if return_type.is_pyobject \
580 and (self.exception_value or self.exception_check) \
581 and self.exception_check != '+':
583 "Exception clause not allowed for function returning Python object")
585 if self.exception_value:
586 self.exception_value.analyse_const_expression(env)
587 if self.exception_check == '+':
588 self.exception_value.analyse_types(env)
589 exc_val_type = self.exception_value.type
590 if not exc_val_type.is_error and \
591 not exc_val_type.is_pyobject and \
592 not (exc_val_type.is_cfunction and not exc_val_type.return_type.is_pyobject and len(exc_val_type.args)==0):
593 error(self.exception_value.pos,
594 "Exception value must be a Python exception or cdef function with no arguments.")
595 exc_val = self.exception_value
597 self.exception_value = self.exception_value.coerce_to(return_type, env)
598 if self.exception_value.analyse_const_expression(env):
599 exc_val = self.exception_value.get_constant_c_result_code()
601 raise InternalError("get_constant_c_result_code not implemented for %s" %
602 self.exception_value.__class__.__name__)
603 if not return_type.assignable_from(self.exception_value.type):
604 error(self.exception_value.pos,
605 "Exception value incompatible with function return type")
606 exc_check = self.exception_check
607 if return_type.is_array:
609 "Function cannot return an array")
610 if return_type.is_cfunction:
612 "Function cannot return a function")
613 func_type = PyrexTypes.CFuncType(
614 return_type, func_type_args, self.has_varargs,
615 optional_arg_count = self.optional_arg_count,
616 exception_value = exc_val, exception_check = exc_check,
617 calling_convention = self.base.calling_convention,
618 nogil = self.nogil, with_gil = self.with_gil, is_overridable = self.overridable)
619 if self.optional_arg_count:
620 func_type.op_arg_struct = PyrexTypes.c_ptr_type(self.op_args_struct.type)
621 callspec = env.directives['callspec']
623 current = func_type.calling_convention
624 if current and current != callspec:
625 error(self.pos, "cannot have both '%s' and '%s' "
626 "calling conventions" % (current, callspec))
627 func_type.calling_convention = callspec
628 return self.base.analyse(func_type, env)
631 class CArgDeclNode(Node):
632 # Item in a function declaration argument list.
634 # base_type CBaseTypeNode
635 # declarator CDeclaratorNode
636 # not_none boolean Tagged with 'not None'
637 # or_none boolean Tagged with 'or None'
638 # accept_none boolean Resolved boolean for not_none/or_none
639 # default ExprNode or None
640 # default_value PyObjectConst constant for default value
641 # annotation ExprNode or None Py3 function arg annotation
642 # is_self_arg boolean Is the "self" arg of an extension type method
643 # is_type_arg boolean Is the "class" arg of an extension type classmethod
644 # is_kw_only boolean Is a keyword-only argument
646 child_attrs = ["base_type", "declarator", "default"]
652 name_declarator = None
656 def analyse(self, env, nonempty = 0, is_self_arg = False):
658 self.base_type.is_self_arg = self.is_self_arg = True
659 if self.type is None:
660 # The parser may missinterpret names as types...
662 if isinstance(self.declarator, CNameDeclaratorNode) and self.declarator.name == '':
664 self.declarator.name = self.base_type.name
665 self.base_type.name = None
666 self.base_type.is_basic_c_type = False
669 could_be_name = False
670 base_type = self.base_type.analyse(env, could_be_name = could_be_name)
671 if hasattr(self.base_type, 'arg_name') and self.base_type.arg_name:
672 self.declarator.name = self.base_type.arg_name
673 # The parser is unable to resolve the ambiguity of [] as part of the
674 # type (e.g. in buffers) or empty declarator (as with arrays).
675 # This is only arises for empty multi-dimensional arrays.
676 if (base_type.is_array
677 and isinstance(self.base_type, TemplatedTypeNode)
678 and isinstance(self.declarator, CArrayDeclaratorNode)):
679 declarator = self.declarator
680 while isinstance(declarator.base, CArrayDeclaratorNode):
681 declarator = declarator.base
682 declarator.base = self.base_type.array_declarator
683 base_type = base_type.base_type
684 return self.declarator.analyse(base_type, env, nonempty = nonempty)
686 return self.name_declarator, self.type
688 def calculate_default_value_code(self, code):
689 if self.default_value is None:
691 if self.default.is_literal:
692 # will not output any code, just assign the result_code
693 self.default.generate_evaluation_code(code)
694 return self.type.cast_code(self.default.result())
695 self.default_value = code.get_argument_default_const(self.type)
696 return self.default_value
698 def annotate(self, code):
700 self.default.annotate(code)
703 class CBaseTypeNode(Node):
704 # Abstract base class for C base type nodes.
706 # Processing during analyse_declarations phase:
713 def analyse_as_type(self, env):
714 return self.analyse(env)
716 class CAnalysedBaseTypeNode(Node):
721 def analyse(self, env, could_be_name = False):
724 class CSimpleBaseTypeNode(CBaseTypeNode):
726 # module_path [string] Qualifying name components
727 # is_basic_c_type boolean
731 # is_self_arg boolean Is self argument of C method
732 # ##is_type_arg boolean Is type argument of class method
735 arg_name = None # in case the argument name was interpreted as a type
737 def analyse(self, env, could_be_name = False):
738 # Return type descriptor.
739 #print "CSimpleBaseTypeNode.analyse: is_self_arg =", self.is_self_arg ###
741 if self.is_basic_c_type:
742 type = PyrexTypes.simple_c_type(self.signed, self.longness, self.name)
744 error(self.pos, "Unrecognised type modifier combination")
745 elif self.name == "object" and not self.module_path:
746 type = py_object_type
747 elif self.name is None:
748 if self.is_self_arg and env.is_c_class_scope:
749 #print "CSimpleBaseTypeNode.analyse: defaulting to parent type" ###
750 type = env.parent_type
751 ## elif self.is_type_arg and env.is_c_class_scope:
752 ## type = Builtin.type_type
754 type = py_object_type
757 scope = env.find_imported_module(self.module_path, self.pos)
761 if scope.is_c_class_scope:
762 scope = scope.global_scope()
763 entry = scope.lookup(self.name)
764 if entry and entry.is_type:
767 if self.is_self_arg and env.is_c_class_scope:
768 type = env.parent_type
769 ## elif self.is_type_arg and env.is_c_class_scope:
770 ## type = Builtin.type_type
772 type = py_object_type
773 self.arg_name = self.name
776 if not self.name in self.templates:
777 error(self.pos, "'%s' is not a type identifier" % self.name)
778 type = PyrexTypes.TemplatePlaceholderType(self.name)
780 error(self.pos, "'%s' is not a type identifier" % self.name)
782 if not type.is_numeric or type.is_complex:
783 error(self.pos, "can only complexify c numeric types")
784 type = PyrexTypes.CComplexType(type)
785 type.create_declaration_utility_code(env)
789 return PyrexTypes.error_type
791 class CNestedBaseTypeNode(CBaseTypeNode):
792 # For C++ classes that live inside other C++ classes.
795 # base_type CBaseTypeNode
797 child_attrs = ['base_type']
799 def analyse(self, env, could_be_name = None):
800 base_type = self.base_type.analyse(env)
801 if base_type is PyrexTypes.error_type:
802 return PyrexTypes.error_type
803 if not base_type.is_cpp_class:
804 error(self.pos, "'%s' is not a valid type scope" % base_type)
805 return PyrexTypes.error_type
806 type_entry = base_type.scope.lookup_here(self.name)
807 if not type_entry or not type_entry.is_type:
808 error(self.pos, "'%s.%s' is not a type identifier" % (base_type, self.name))
809 return PyrexTypes.error_type
810 return type_entry.type
812 class TemplatedTypeNode(CBaseTypeNode):
814 # positional_args [ExprNode] List of positional arguments
815 # keyword_args DictNode Keyword arguments
816 # base_type_node CBaseTypeNode
819 # type PyrexTypes.BufferType or PyrexTypes.CppClassType ...containing the right options
822 child_attrs = ["base_type_node", "positional_args",
823 "keyword_args", "dtype_node"]
829 def analyse(self, env, could_be_name = False, base_type = None):
830 if base_type is None:
831 base_type = self.base_type_node.analyse(env)
832 if base_type.is_error: return base_type
834 if base_type.is_cpp_class:
836 if self.keyword_args and self.keyword_args.key_value_pairs:
837 error(self.pos, "c++ templates cannot take keyword arguments");
838 self.type = PyrexTypes.error_type
841 for template_node in self.positional_args:
842 type = template_node.analyse_as_type(env)
844 error(template_node.pos, "unknown type in template argument")
846 template_types.append(type)
847 self.type = base_type.specialize_here(self.pos, template_types)
849 elif base_type.is_pyobject:
853 options = Buffer.analyse_buffer_options(
856 self.positional_args,
858 base_type.buffer_defaults)
860 if sys.version_info[0] < 3:
861 # Py 2.x enforces byte strings as keyword arguments ...
862 options = dict([ (name.encode('ASCII'), value)
863 for name, value in options.items() ])
865 self.type = PyrexTypes.BufferType(base_type, **options)
869 empty_declarator = CNameDeclaratorNode(self.pos, name="", cname=None)
870 if len(self.positional_args) > 1 or self.keyword_args.key_value_pairs:
871 error(self.pos, "invalid array declaration")
872 self.type = PyrexTypes.error_type
874 # It would be nice to merge this class with CArrayDeclaratorNode,
875 # but arrays are part of the declaration, not the type...
876 if not self.positional_args:
879 dimension = self.positional_args[0]
880 self.array_declarator = CArrayDeclaratorNode(self.pos,
881 base = empty_declarator,
882 dimension = dimension)
883 self.type = self.array_declarator.analyse(base_type, env)[1]
887 class CComplexBaseTypeNode(CBaseTypeNode):
888 # base_type CBaseTypeNode
889 # declarator CDeclaratorNode
891 child_attrs = ["base_type", "declarator"]
893 def analyse(self, env, could_be_name = False):
894 base = self.base_type.analyse(env, could_be_name)
895 _, type = self.declarator.analyse(base, env)
899 class CVarDefNode(StatNode):
900 # C variable definition or forward/extern function declaration.
902 # visibility 'private' or 'public' or 'extern'
903 # base_type CBaseTypeNode
904 # declarators [CDeclaratorNode]
908 # decorators [cython.locals(...)] or None
909 # directive_locals { string : NameNode } locals defined by cython.locals(...)
911 child_attrs = ["base_type", "declarators"]
914 directive_locals = {}
916 def analyse_declarations(self, env, dest_scope = None):
919 self.dest_scope = dest_scope
920 base_type = self.base_type.analyse(env)
922 # If the field is an external typedef, we cannot be sure about the type,
923 # so do conversion ourself rather than rely on the CPython mechanism (through
924 # a property; made in AnalyseDeclarationsTransform).
925 if (dest_scope.is_c_class_scope
926 and self.visibility in ('public', 'readonly')):
929 need_property = False
930 visibility = self.visibility
932 for declarator in self.declarators:
933 name_declarator, type = declarator.analyse(base_type, env)
934 if not type.is_complete():
935 if not (self.visibility == 'extern' and type.is_array):
936 error(declarator.pos,
937 "Variable type '%s' is incomplete" % type)
938 if self.visibility == 'extern' and type.is_pyobject:
939 error(declarator.pos,
940 "Python object cannot be declared extern")
941 name = name_declarator.name
942 cname = name_declarator.cname
944 error(declarator.pos, "Missing name in declaration.")
946 if type.is_cfunction:
947 entry = dest_scope.declare_cfunction(name, type, declarator.pos,
948 cname = cname, visibility = self.visibility, in_pxd = self.in_pxd,
950 if entry is not None:
951 entry.directive_locals = self.directive_locals
953 if self.directive_locals:
954 error(self.pos, "Decorators can only be followed by functions")
955 if self.in_pxd and self.visibility != 'extern':
957 "Only 'extern' C variable declaration allowed in .pxd file")
958 entry = dest_scope.declare_var(name, type, declarator.pos,
959 cname = cname, visibility = visibility, is_cdef = 1)
960 entry.needs_property = need_property
963 class CStructOrUnionDefNode(StatNode):
965 # cname string or None
966 # kind "struct" or "union"
967 # typedef_flag boolean
968 # visibility "public" or "private"
970 # attributes [CVarDefNode] or None
974 child_attrs = ["attributes"]
976 def analyse_declarations(self, env):
978 if self.visibility == 'extern' and self.packed:
979 error(self.pos, "Cannot declare extern struct as 'packed'")
980 if self.attributes is not None:
981 scope = StructOrUnionScope(self.name)
982 self.entry = env.declare_struct_or_union(
983 self.name, self.kind, scope, self.typedef_flag, self.pos,
984 self.cname, visibility = self.visibility, packed = self.packed)
985 if self.attributes is not None:
986 if self.in_pxd and not env.in_cinclude:
987 self.entry.defined_in_pxd = 1
988 for attr in self.attributes:
989 attr.analyse_declarations(env, scope)
990 if self.visibility != 'extern':
991 need_typedef_indirection = False
992 for attr in scope.var_entries:
995 type = type.base_type
996 if type == self.entry.type:
997 error(attr.pos, "Struct cannot contain itself as a member.")
998 if self.typedef_flag:
1000 type = type.base_type
1001 if type == self.entry.type:
1002 need_typedef_indirection = True
1003 if need_typedef_indirection:
1004 # C can't handle typedef structs that refer to themselves.
1005 struct_entry = self.entry
1006 self.entry = env.declare_typedef(
1007 self.name, struct_entry.type, self.pos,
1008 cname = self.cname, visibility='ignore')
1009 struct_entry.type.typedef_flag = False
1010 # FIXME: this might be considered a hack ;-)
1011 struct_entry.cname = struct_entry.type.cname = \
1012 '_' + self.entry.type.typedef_cname
1014 def analyse_expressions(self, env):
1017 def generate_execution_code(self, code):
1021 class CppClassNode(CStructOrUnionDefNode):
1024 # cname string or None
1025 # visibility "extern"
1027 # attributes [CVarDefNode] or None
1029 # base_classes [string]
1030 # templates [string] or None
1032 def analyse_declarations(self, env):
1034 if self.attributes is not None:
1035 scope = CppClassScope(self.name, env)
1036 base_class_types = []
1037 for base_class_name in self.base_classes:
1038 base_class_entry = env.lookup(base_class_name)
1039 if base_class_entry is None:
1040 error(self.pos, "'%s' not found" % base_class_name)
1041 elif not base_class_entry.is_type or not base_class_entry.type.is_cpp_class:
1042 error(self.pos, "'%s' is not a cpp class type" % base_class_name)
1044 base_class_types.append(base_class_entry.type)
1045 if self.templates is None:
1046 template_types = None
1048 template_types = [PyrexTypes.TemplatePlaceholderType(template_name) for template_name in self.templates]
1049 self.entry = env.declare_cpp_class(
1050 self.name, scope, self.pos,
1051 self.cname, base_class_types, visibility = self.visibility, templates = template_types)
1052 self.entry.is_cpp_class = 1
1053 if self.attributes is not None:
1054 if self.in_pxd and not env.in_cinclude:
1055 self.entry.defined_in_pxd = 1
1056 for attr in self.attributes:
1057 attr.analyse_declarations(scope)
1059 class CEnumDefNode(StatNode):
1060 # name string or None
1061 # cname string or None
1062 # items [CEnumDefItemNode]
1063 # typedef_flag boolean
1064 # visibility "public" or "private"
1068 child_attrs = ["items"]
1070 def analyse_declarations(self, env):
1071 self.entry = env.declare_enum(self.name, self.pos,
1072 cname = self.cname, typedef_flag = self.typedef_flag,
1073 visibility = self.visibility)
1074 if self.items is not None:
1075 if self.in_pxd and not env.in_cinclude:
1076 self.entry.defined_in_pxd = 1
1077 for item in self.items:
1078 item.analyse_declarations(env, self.entry)
1080 def analyse_expressions(self, env):
1083 def generate_execution_code(self, code):
1084 if self.visibility == 'public':
1085 temp = code.funcstate.allocate_temp(PyrexTypes.py_object_type, manage_ref=True)
1086 for item in self.entry.enum_values:
1087 code.putln("%s = PyInt_FromLong(%s); %s" % (
1090 code.error_goto_if_null(temp, item.pos)))
1091 code.put_gotref(temp)
1092 code.putln('if (__Pyx_SetAttrString(%s, "%s", %s) < 0) %s' % (
1093 Naming.module_cname,
1096 code.error_goto(item.pos)))
1097 code.put_decref_clear(temp, PyrexTypes.py_object_type)
1098 code.funcstate.release_temp(temp)
1101 class CEnumDefItemNode(StatNode):
1103 # cname string or None
1104 # value ExprNode or None
1106 child_attrs = ["value"]
1108 def analyse_declarations(self, env, enum_entry):
1110 self.value.analyse_const_expression(env)
1111 if not self.value.type.is_int:
1112 self.value = self.value.coerce_to(PyrexTypes.c_int_type, env)
1113 self.value.analyse_const_expression(env)
1114 entry = env.declare_const(self.name, enum_entry.type,
1115 self.value, self.pos, cname = self.cname,
1116 visibility = enum_entry.visibility)
1117 enum_entry.enum_values.append(entry)
1120 class CTypeDefNode(StatNode):
1121 # base_type CBaseTypeNode
1122 # declarator CDeclaratorNode
1123 # visibility "public" or "private"
1126 child_attrs = ["base_type", "declarator"]
1128 def analyse_declarations(self, env):
1129 base = self.base_type.analyse(env)
1130 name_declarator, type = self.declarator.analyse(base, env)
1131 name = name_declarator.name
1132 cname = name_declarator.cname
1133 entry = env.declare_typedef(name, type, self.pos,
1134 cname = cname, visibility = self.visibility)
1135 if self.in_pxd and not env.in_cinclude:
1136 entry.defined_in_pxd = 1
1138 def analyse_expressions(self, env):
1140 def generate_execution_code(self, code):
1144 class FuncDefNode(StatNode, BlockNode):
1145 # Base class for function definition nodes.
1147 # return_type PyrexType
1148 # #filename string C name of filename string const
1149 # entry Symtab.Entry
1150 # needs_closure boolean Whether or not this function has inner functions/classes/yield
1151 # needs_outer_scope boolean Whether or not this function requires outer scope
1152 # directive_locals { string : NameNode } locals defined by cython.locals(...)
1156 needs_closure = False
1157 needs_outer_scope = False
1160 def analyse_default_values(self, env):
1161 genv = env.global_scope()
1163 for arg in self.args:
1167 arg.default.analyse_types(env)
1168 arg.default = arg.default.coerce_to(arg.type, genv)
1171 "This argument cannot have a default value")
1176 error(arg.pos, "Non-default argument following default argument")
1178 def need_gil_acquisition(self, lenv):
1181 def create_local_scope(self, env):
1183 while genv.is_py_class_scope or genv.is_c_class_scope:
1184 genv = genv.outer_scope
1185 if self.needs_closure:
1186 lenv = ClosureScope(name=self.entry.name,
1188 scope_name=self.entry.cname)
1190 lenv = LocalScope(name=self.entry.name,
1193 lenv.return_type = self.return_type
1194 type = self.entry.type
1195 if type.is_cfunction:
1196 lenv.nogil = type.nogil and not type.with_gil
1197 self.local_scope = lenv
1198 lenv.directives = env.directives
1201 def generate_function_definitions(self, env, code):
1204 lenv = self.local_scope
1205 if lenv.is_closure_scope and not lenv.is_passthrough:
1206 outer_scope_cname = "%s->%s" % (Naming.cur_scope_cname,
1207 Naming.outer_scope_cname)
1209 outer_scope_cname = Naming.outer_scope_cname
1210 lenv.mangle_closure_cnames(outer_scope_cname)
1211 # Generate closure function definitions
1212 self.body.generate_function_definitions(lenv, code)
1213 # generate lambda function definitions
1214 for node in lenv.lambda_defs:
1215 node.generate_function_definitions(lenv, code)
1217 is_getbuffer_slot = (self.entry.name == "__getbuffer__" and
1218 self.entry.scope.is_c_class_scope)
1219 is_releasebuffer_slot = (self.entry.name == "__releasebuffer__" and
1220 self.entry.scope.is_c_class_scope)
1221 is_buffer_slot = is_getbuffer_slot or is_releasebuffer_slot
1223 if 'cython_unused' not in self.modifiers:
1224 self.modifiers = self.modifiers + ['cython_unused']
1226 preprocessor_guard = None
1227 if self.entry.is_special and not is_buffer_slot:
1228 slot = TypeSlots.method_name_to_slot.get(self.entry.name)
1230 preprocessor_guard = slot.preprocessor_guard_code()
1231 if (self.entry.name == '__long__' and
1232 not self.entry.scope.lookup_here('__int__')):
1233 preprocessor_guard = None
1235 profile = code.globalstate.directives['profile']
1238 error(self.pos, "Cannot profile nogil function.")
1239 code.globalstate.use_utility_code(profile_utility_code)
1241 # Generate C code for header and body of function
1242 code.enter_cfunc_scope()
1243 code.return_from_error_cleanup_label = code.new_label()
1245 # ----- Top-level constants used by this function
1246 code.mark_pos(self.pos)
1247 self.generate_cached_builtins_decls(lenv, code)
1248 # ----- Function header
1251 if preprocessor_guard:
1252 code.putln(preprocessor_guard)
1254 with_pymethdef = self.needs_assignment_synthesis(env, code)
1256 self.py_func.generate_function_header(code,
1257 with_pymethdef = with_pymethdef,
1259 self.generate_function_header(code,
1260 with_pymethdef = with_pymethdef)
1261 # ----- Local variable declarations
1262 # Find function scope
1264 while cenv.is_py_class_scope or cenv.is_c_class_scope:
1265 cenv = cenv.outer_scope
1266 if self.needs_closure:
1267 code.put(lenv.scope_class.type.declaration_code(Naming.cur_scope_cname))
1269 elif self.needs_outer_scope:
1270 if lenv.is_passthrough:
1271 code.put(lenv.scope_class.type.declaration_code(Naming.cur_scope_cname))
1273 code.put(cenv.scope_class.type.declaration_code(Naming.outer_scope_cname))
1275 self.generate_argument_declarations(lenv, code)
1276 for entry in lenv.var_entries:
1277 if not entry.in_closure:
1278 code.put_var_declaration(entry)
1280 if not self.return_type.is_void:
1281 if self.return_type.is_pyobject:
1285 (self.return_type.declaration_code(Naming.retval_cname),
1287 tempvardecl_code = code.insertion_point()
1288 self.generate_keyword_list(code)
1290 code.put_trace_declarations()
1291 # ----- Extern library function declarations
1292 lenv.generate_library_function_declarations(code)
1293 # ----- GIL acquisition
1294 acquire_gil = self.acquire_gil
1296 env.use_utility_code(force_init_threads_utility_code)
1297 code.putln("#ifdef WITH_THREAD")
1298 code.putln("PyGILState_STATE _save = PyGILState_Ensure();")
1299 code.putln("#endif")
1300 # ----- set up refnanny
1302 code.put_setup_refcount_context(self.entry.name)
1303 # ----- Automatic lead-ins for certain special functions
1304 if is_getbuffer_slot:
1305 self.getbuffer_init(code)
1306 # ----- Create closure scope object
1307 if self.needs_closure:
1308 code.putln("%s = (%s)%s->tp_new(%s, %s, NULL);" % (
1309 Naming.cur_scope_cname,
1310 lenv.scope_class.type.declaration_code(''),
1311 lenv.scope_class.type.typeptr_cname,
1312 lenv.scope_class.type.typeptr_cname,
1313 Naming.empty_tuple))
1314 code.putln("if (unlikely(!%s)) {" % Naming.cur_scope_cname)
1315 if is_getbuffer_slot:
1316 self.getbuffer_error_cleanup(code)
1318 code.put_finish_refcount_context()
1319 # FIXME: what if the error return value is a Python value?
1320 code.putln("return %s;" % self.error_value())
1322 code.put_gotref(Naming.cur_scope_cname)
1323 # Note that it is unsafe to decref the scope at this point.
1324 if self.needs_outer_scope:
1325 code.putln("%s = (%s)%s;" % (
1327 cenv.scope_class.type.declaration_code(''),
1329 if lenv.is_passthrough:
1330 code.putln("%s = %s;" % (Naming.cur_scope_cname, outer_scope_cname));
1331 elif self.needs_closure:
1332 # inner closures own a reference to their outer parent
1333 code.put_incref(outer_scope_cname, cenv.scope_class.type)
1334 code.put_giveref(outer_scope_cname)
1335 # ----- Trace function call
1337 # this looks a bit late, but if we don't get here due to a
1338 # fatal error before hand, it's not really worth tracing
1339 code.put_trace_call(self.entry.name, self.pos)
1340 # ----- Fetch arguments
1341 self.generate_argument_parsing_code(env, code)
1342 # If an argument is assigned to in the body, we must
1343 # incref it to properly keep track of refcounts.
1344 for entry in lenv.arg_entries:
1345 if entry.type.is_pyobject:
1346 if entry.assignments and not entry.in_closure:
1347 code.put_var_incref(entry)
1348 # ----- Initialise local variables
1349 for entry in lenv.var_entries:
1350 if entry.type.is_pyobject and entry.init_to_none and entry.used:
1351 code.put_init_var_to_py_none(entry)
1352 # ----- Initialise local buffer auxiliary variables
1353 for entry in lenv.var_entries + lenv.arg_entries:
1354 if entry.type.is_buffer and entry.buffer_aux.buffer_info_var.used:
1355 code.putln("%s.buf = NULL;" %
1356 entry.buffer_aux.buffer_info_var.cname)
1357 # ----- Check and convert arguments
1358 self.generate_argument_type_tests(code)
1359 # ----- Acquire buffer arguments
1360 for entry in lenv.arg_entries:
1361 if entry.type.is_buffer:
1362 Buffer.put_acquire_arg_buffer(entry, code, self.pos)
1364 # -------------------------
1365 # ----- Function body -----
1366 # -------------------------
1367 self.body.generate_execution_code(code)
1369 # ----- Default return value
1371 if self.return_type.is_pyobject:
1372 #if self.return_type.is_extension_type:
1373 # lhs = "(PyObject *)%s" % Naming.retval_cname
1375 lhs = Naming.retval_cname
1376 code.put_init_to_py_none(lhs, self.return_type)
1378 val = self.return_type.default_value
1380 code.putln("%s = %s;" % (Naming.retval_cname, val))
1381 # ----- Error cleanup
1382 if code.error_label in code.labels_used:
1383 code.put_goto(code.return_label)
1384 code.put_label(code.error_label)
1385 for cname, type in code.funcstate.all_managed_temps():
1386 code.put_xdecref(cname, type)
1388 # Clean up buffers -- this calls a Python function
1389 # so need to save and restore error state
1390 buffers_present = len(lenv.buffer_entries) > 0
1392 code.globalstate.use_utility_code(restore_exception_utility_code)
1393 code.putln("{ PyObject *__pyx_type, *__pyx_value, *__pyx_tb;")
1394 code.putln("__Pyx_ErrFetch(&__pyx_type, &__pyx_value, &__pyx_tb);")
1395 for entry in lenv.buffer_entries:
1396 Buffer.put_release_buffer_code(code, entry)
1397 #code.putln("%s = 0;" % entry.cname)
1398 code.putln("__Pyx_ErrRestore(__pyx_type, __pyx_value, __pyx_tb);}")
1400 err_val = self.error_value()
1401 exc_check = self.caller_will_check_exceptions()
1402 if err_val is not None or exc_check:
1403 # TODO: Fix exception tracing (though currently unused by cProfile).
1404 # code.globalstate.use_utility_code(get_exception_tuple_utility_code)
1405 # code.put_trace_exception()
1406 code.putln('__Pyx_AddTraceback("%s");' % self.entry.qualified_name)
1408 warning(self.entry.pos, "Unraisable exception in function '%s'." \
1409 % self.entry.qualified_name, 0)
1411 '__Pyx_WriteUnraisable("%s");' %
1412 self.entry.qualified_name)
1413 env.use_utility_code(unraisable_exception_utility_code)
1414 env.use_utility_code(restore_exception_utility_code)
1415 default_retval = self.return_type.default_value
1416 if err_val is None and default_retval:
1417 err_val = default_retval
1418 if err_val is not None:
1419 code.putln("%s = %s;" % (Naming.retval_cname, err_val))
1421 if is_getbuffer_slot:
1422 self.getbuffer_error_cleanup(code)
1424 # If we are using the non-error cleanup section we should
1425 # jump past it if we have an error. The if-test below determine
1426 # whether this section is used.
1427 if buffers_present or is_getbuffer_slot:
1428 code.put_goto(code.return_from_error_cleanup_label)
1431 # ----- Non-error return cleanup
1432 code.put_label(code.return_label)
1433 for entry in lenv.buffer_entries:
1435 Buffer.put_release_buffer_code(code, entry)
1436 if is_getbuffer_slot:
1437 self.getbuffer_normal_cleanup(code)
1438 # ----- Return cleanup for both error and no-error return
1439 code.put_label(code.return_from_error_cleanup_label)
1440 if not Options.init_local_none:
1441 for entry in lenv.var_entries:
1442 if lenv.control_flow.get_state((entry.name, 'initialized')) is not True:
1443 entry.xdecref_cleanup = 1
1445 for entry in lenv.var_entries:
1446 if entry.type.is_pyobject:
1447 if entry.used and not entry.in_closure:
1448 code.put_var_decref(entry)
1449 elif entry.in_closure and self.needs_closure:
1450 code.put_giveref(entry.cname)
1451 # Decref any increfed args
1452 for entry in lenv.arg_entries:
1453 if entry.type.is_pyobject:
1454 if entry.in_closure:
1455 code.put_var_giveref(entry)
1456 elif entry.assignments:
1457 code.put_var_decref(entry)
1458 if self.needs_closure:
1459 code.put_decref(Naming.cur_scope_cname, lenv.scope_class.type)
1462 # This code is duplicated in ModuleNode.generate_module_init_func
1464 default_retval = self.return_type.default_value
1465 err_val = self.error_value()
1466 if err_val is None and default_retval:
1467 err_val = default_retval
1468 if self.return_type.is_pyobject:
1469 code.put_xgiveref(self.return_type.as_pyobject(Naming.retval_cname))
1471 if self.entry.is_special and self.entry.name == "__hash__":
1472 # Returning -1 for __hash__ is supposed to signal an error
1473 # We do as Python instances and coerce -1 into -2.
1474 code.putln("if (unlikely(%s == -1) && !PyErr_Occurred()) %s = -2;" % (
1475 Naming.retval_cname, Naming.retval_cname))
1478 if self.return_type.is_pyobject:
1479 code.put_trace_return(Naming.retval_cname)
1481 code.put_trace_return("Py_None")
1483 code.put_finish_refcount_context()
1486 code.putln("#ifdef WITH_THREAD")
1487 code.putln("PyGILState_Release(_save);")
1488 code.putln("#endif")
1490 if not self.return_type.is_void:
1491 code.putln("return %s;" % Naming.retval_cname)
1495 if preprocessor_guard:
1496 code.putln("#endif /*!(%s)*/" % preprocessor_guard)
1498 # ----- Go back and insert temp variable declarations
1499 tempvardecl_code.put_temp_declarations(code.funcstate)
1500 # ----- Python version
1501 code.exit_cfunc_scope()
1503 self.py_func.generate_function_definitions(env, code)
1504 self.generate_wrapper_functions(code)
1506 def declare_argument(self, env, arg):
1507 if arg.type.is_void:
1508 error(arg.pos, "Invalid use of 'void'")
1509 elif not arg.type.is_complete() and not arg.type.is_array:
1511 "Argument type '%s' is incomplete" % arg.type)
1512 return env.declare_arg(arg.name, arg.type, arg.pos)
1514 def generate_arg_type_test(self, arg, code):
1515 # Generate type test for one argument.
1516 if arg.type.typeobj_is_available():
1517 code.globalstate.use_utility_code(arg_type_test_utility_code)
1518 typeptr_cname = arg.type.typeptr_cname
1519 arg_code = "((PyObject *)%s)" % arg.entry.cname
1521 'if (unlikely(!__Pyx_ArgTypeTest(%s, %s, %d, "%s", %s))) %s' % (
1526 arg.type.is_builtin_type,
1527 code.error_goto(arg.pos)))
1529 error(arg.pos, "Cannot test type of extern C class "
1530 "without type object name specification")
1532 def generate_arg_none_check(self, arg, code):
1533 # Generate None check for one argument.
1534 code.globalstate.use_utility_code(arg_type_test_utility_code)
1535 code.putln('if (unlikely(((PyObject *)%s) == Py_None)) {' % arg.entry.cname)
1536 code.putln('''PyErr_Format(PyExc_TypeError, "Argument '%s' must not be None"); %s''' % (
1538 code.error_goto(arg.pos)))
1541 def generate_wrapper_functions(self, code):
1544 def generate_execution_code(self, code):
1545 # Evaluate and store argument default values
1546 for arg in self.args:
1547 default = arg.default
1549 if not default.is_literal:
1550 default.generate_evaluation_code(code)
1551 default.make_owned_reference(code)
1552 result = default.result_as(arg.type)
1555 arg.calculate_default_value_code(code),
1557 if arg.type.is_pyobject:
1558 code.put_giveref(default.result())
1559 default.generate_post_assignment_code(code)
1560 default.free_temps(code)
1561 # For Python class methods, create and store function object
1563 self.assmt.generate_execution_code(code)
1566 # Special code for the __getbuffer__ function
1568 def getbuffer_init(self, code):
1569 info = self.local_scope.arg_entries[1].cname
1570 # Python 3.0 betas have a bug in memoryview which makes it call
1571 # getbuffer with a NULL parameter. For now we work around this;
1572 # the following line should be removed when this bug is fixed.
1573 code.putln("if (%s == NULL) return 0;" % info)
1574 code.putln("%s->obj = Py_None; __Pyx_INCREF(Py_None);" % info)
1575 code.put_giveref("%s->obj" % info) # Do not refnanny object within structs
1577 def getbuffer_error_cleanup(self, code):
1578 info = self.local_scope.arg_entries[1].cname
1579 code.put_gotref("%s->obj" % info)
1580 code.putln("__Pyx_DECREF(%s->obj); %s->obj = NULL;" %
1583 def getbuffer_normal_cleanup(self, code):
1584 info = self.local_scope.arg_entries[1].cname
1585 code.putln("if (%s->obj == Py_None) {" % info)
1586 code.put_gotref("Py_None")
1587 code.putln("__Pyx_DECREF(Py_None); %s->obj = NULL;" % info)
1590 class CFuncDefNode(FuncDefNode):
1591 # C function definition.
1593 # modifiers ['inline']
1594 # visibility 'private' or 'public' or 'extern'
1595 # base_type CBaseTypeNode
1596 # declarator CDeclaratorNode
1599 # decorators [DecoratorNode] list of decorators
1601 # with_gil boolean Acquire GIL around body
1603 # py_func wrapper for calling from Python
1604 # overridable whether or not this is a cpdef function
1605 # inline_in_pxd whether this is an inline function in a pxd file
1607 child_attrs = ["base_type", "declarator", "body", "py_func"]
1609 inline_in_pxd = False
1611 directive_locals = {}
1613 def unqualified_name(self):
1614 return self.entry.name
1616 def analyse_declarations(self, env):
1617 self.directive_locals.update(env.directives['locals'])
1618 base_type = self.base_type.analyse(env)
1619 # The 2 here is because we need both function and argument names.
1620 name_declarator, type = self.declarator.analyse(base_type, env, nonempty = 2 * (self.body is not None))
1621 if not type.is_cfunction:
1623 "Suite attached to non-function declaration")
1624 # Remember the actual type according to the function header
1625 # written here, because the type in the symbol table entry
1626 # may be different if we're overriding a C method inherited
1627 # from the base type of an extension type.
1629 type.is_overridable = self.overridable
1630 declarator = self.declarator
1631 while not hasattr(declarator, 'args'):
1632 declarator = declarator.base
1633 self.args = declarator.args
1634 for formal_arg, type_arg in zip(self.args, type.args):
1635 formal_arg.type = type_arg.type
1636 formal_arg.name = type_arg.name
1637 formal_arg.cname = type_arg.cname
1638 name = name_declarator.name
1639 cname = name_declarator.cname
1640 self.entry = env.declare_cfunction(
1641 name, type, self.pos,
1642 cname = cname, visibility = self.visibility,
1643 defining = self.body is not None,
1644 api = self.api, modifiers = self.modifiers)
1645 self.entry.inline_func_in_pxd = self.inline_in_pxd
1646 self.return_type = type.return_type
1648 if self.overridable and not env.is_module_scope:
1649 if len(self.args) < 1 or not self.args[0].type.is_pyobject:
1650 # An error will be produced in the cdef function
1651 self.overridable = False
1653 if self.overridable:
1655 py_func_body = self.call_self_node(is_module_scope = env.is_module_scope)
1656 self.py_func = DefNode(pos = self.pos,
1657 name = self.entry.name,
1660 starstar_arg = None,
1662 body = py_func_body,
1664 self.py_func.is_module_scope = env.is_module_scope
1665 self.py_func.analyse_declarations(env)
1666 self.entry.as_variable = self.py_func.entry
1667 # Reset scope entry the above cfunction
1668 env.entries[name] = self.entry
1669 if not env.is_module_scope or Options.lookup_module_cpdef:
1670 self.override = OverrideCheckNode(self.pos, py_func = self.py_func)
1671 self.body = StatListNode(self.pos, stats=[self.override, self.body])
1672 self.create_local_scope(env)
1674 def call_self_node(self, omit_optional_args=0, is_module_scope=0):
1676 args = self.type.args
1677 if omit_optional_args:
1678 args = args[:len(args) - self.type.optional_arg_count]
1679 arg_names = [arg.name for arg in args]
1681 cfunc = ExprNodes.NameNode(self.pos, name=self.entry.name)
1683 self_arg = ExprNodes.NameNode(self.pos, name=arg_names[0])
1684 cfunc = ExprNodes.AttributeNode(self.pos, obj=self_arg, attribute=self.entry.name)
1685 skip_dispatch = not is_module_scope or Options.lookup_module_cpdef
1686 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)
1687 return ReturnStatNode(pos=self.pos, return_type=PyrexTypes.py_object_type, value=c_call)
1689 def declare_arguments(self, env):
1690 for arg in self.type.args:
1692 error(arg.pos, "Missing argument name")
1693 self.declare_argument(env, arg)
1695 def need_gil_acquisition(self, lenv):
1696 return self.type.with_gil
1698 def nogil_check(self, env):
1700 with_gil = type.with_gil
1701 if type.nogil and not with_gil:
1702 if type.return_type.is_pyobject:
1704 "Function with Python return type cannot be declared nogil")
1705 for entry in self.local_scope.var_entries:
1706 if entry.type.is_pyobject:
1707 error(self.pos, "Function declared nogil has Python locals or temporaries")
1709 def analyse_expressions(self, env):
1710 self.local_scope.directives = env.directives
1711 if self.py_func is not None:
1712 # this will also analyse the default values
1713 self.py_func.analyse_expressions(env)
1715 self.analyse_default_values(env)
1716 self.acquire_gil = self.need_gil_acquisition(self.local_scope)
1718 def needs_assignment_synthesis(self, env, code=None):
1721 def generate_function_header(self, code, with_pymethdef, with_opt_args = 1, with_dispatch = 1, cname = None):
1724 visibility = self.entry.visibility
1725 for arg in type.args[:len(type.args)-type.optional_arg_count]:
1726 arg_decls.append(arg.declaration_code())
1727 if with_dispatch and self.overridable:
1728 arg_decls.append(PyrexTypes.c_int_type.declaration_code(Naming.skip_dispatch_cname))
1729 if type.optional_arg_count and with_opt_args:
1730 arg_decls.append(type.op_arg_struct.declaration_code(Naming.optional_args_cname))
1731 if type.has_varargs:
1732 arg_decls.append("...")
1734 arg_decls = ["void"]
1736 cname = self.entry.func_cname
1737 entity = type.function_header_code(cname, ', '.join(arg_decls))
1738 if visibility == 'public':
1739 dll_linkage = "DL_EXPORT"
1742 header = self.return_type.declaration_code(entity,
1743 dll_linkage = dll_linkage)
1744 if visibility == 'extern':
1745 storage_class = "%s " % Naming.extern_c_macro
1746 elif visibility == 'public':
1749 storage_class = "static "
1750 if 'inline' in self.modifiers:
1751 self.modifiers[self.modifiers.index('inline')] = 'cython_inline'
1752 code.putln("%s%s %s {" % (
1754 ' '.join(self.modifiers).upper(), # macro forms
1757 def generate_argument_declarations(self, env, code):
1758 for arg in self.args:
1760 result = arg.calculate_default_value_code(code)
1761 code.putln('%s = %s;' % (
1762 arg.type.declaration_code(arg.cname), result))
1764 def generate_keyword_list(self, code):
1767 def generate_argument_parsing_code(self, env, code):
1769 if self.type.optional_arg_count:
1770 code.putln('if (%s) {' % Naming.optional_args_cname)
1771 for arg in self.args:
1773 code.putln('if (%s->%sn > %s) {' % (Naming.optional_args_cname, Naming.pyrex_prefix, i))
1774 declarator = arg.declarator
1775 while not hasattr(declarator, 'name'):
1776 declarator = declarator.base
1777 code.putln('%s = %s->%s;' % (arg.cname, Naming.optional_args_cname, self.type.opt_arg_cname(declarator.name)))
1779 for _ in range(self.type.optional_arg_count):
1783 def generate_argument_conversion_code(self, code):
1786 def generate_argument_type_tests(self, code):
1787 # Generate type tests for args whose type in a parent
1788 # class is a supertype of the declared type.
1789 for arg in self.type.args:
1790 if arg.needs_type_test:
1791 self.generate_arg_type_test(arg, code)
1792 elif arg.type.is_pyobject and not arg.accept_none:
1793 self.generate_arg_none_check(arg, code)
1795 def error_value(self):
1796 if self.return_type.is_pyobject:
1800 return self.entry.type.exception_value
1802 def caller_will_check_exceptions(self):
1803 return self.entry.type.exception_check
1805 def generate_wrapper_functions(self, code):
1806 # If the C signature of a function has changed, we need to generate
1807 # wrappers to put in the slots here.
1810 func_type = entry.type
1811 while entry.prev_entry is not None:
1813 entry = entry.prev_entry
1814 entry.func_cname = "%s%swrap_%s" % (self.entry.func_cname, Naming.pyrex_prefix, k)
1816 self.generate_function_header(code,
1818 with_dispatch = entry.type.is_overridable,
1819 with_opt_args = entry.type.optional_arg_count,
1820 cname = entry.func_cname)
1821 if not self.return_type.is_void:
1823 args = self.type.args
1824 arglist = [arg.cname for arg in args[:len(args)-self.type.optional_arg_count]]
1825 if entry.type.is_overridable:
1826 arglist.append(Naming.skip_dispatch_cname)
1827 elif func_type.is_overridable:
1829 if entry.type.optional_arg_count:
1830 arglist.append(Naming.optional_args_cname)
1831 elif func_type.optional_arg_count:
1832 arglist.append('NULL')
1833 code.putln('%s(%s);' % (self.entry.func_cname, ', '.join(arglist)))
1837 class PyArgDeclNode(Node):
1838 # Argument which must be a Python object (used
1839 # for * and ** arguments).
1842 # entry Symtab.Entry
1843 # annotation ExprNode or None Py3 argument annotation
1846 def generate_function_definitions(self, env, code):
1847 self.entry.generate_function_definitions(env, code)
1849 class DecoratorNode(Node):
1852 # decorator NameNode or CallNode or AttributeNode
1853 child_attrs = ['decorator']
1856 class DefNode(FuncDefNode):
1857 # A Python function definition.
1859 # name string the Python name of the function
1860 # lambda_name string the internal name of a lambda 'function'
1861 # decorators [DecoratorNode] list of decorators
1862 # args [CArgDeclNode] formal arguments
1863 # star_arg PyArgDeclNode or None * argument
1864 # starstar_arg PyArgDeclNode or None ** argument
1865 # doc EncodedString or None
1867 # return_type_annotation
1868 # ExprNode or None the Py3 return type annotation
1870 # The following subnode is constructed internally
1871 # when the def statement is inside a Python class definition.
1873 # assmt AssignmentNode Function construction/assignment
1875 child_attrs = ["args", "star_arg", "starstar_arg", "body", "decorators"]
1880 num_required_kw_args = 0
1881 reqd_kw_flags_cname = "0"
1884 return_type_annotation = None
1889 def __init__(self, pos, **kwds):
1890 FuncDefNode.__init__(self, pos, **kwds)
1892 for arg in self.args:
1899 self.num_kwonly_args = k
1900 self.num_required_kw_args = rk
1901 self.num_required_args = r
1903 def as_cfunction(self, cfunc=None, scope=None):
1905 error(self.star_arg.pos, "cdef function cannot have star argument")
1906 if self.starstar_arg:
1907 error(self.starstar_arg.pos, "cdef function cannot have starstar argument")
1910 for formal_arg in self.args:
1911 name_declarator, type = formal_arg.analyse(scope, nonempty=1)
1912 cfunc_args.append(PyrexTypes.CFuncTypeArg(name = name_declarator.name,
1914 type = py_object_type,
1915 pos = formal_arg.pos))
1916 cfunc_type = PyrexTypes.CFuncType(return_type = py_object_type,
1918 has_varargs = False,
1919 exception_value = None,
1920 exception_check = False,
1923 is_overridable = True)
1924 cfunc = CVarDefNode(self.pos, type=cfunc_type)
1928 cfunc_type = cfunc.type
1929 if len(self.args) != len(cfunc_type.args) or cfunc_type.has_varargs:
1930 error(self.pos, "wrong number of arguments")
1931 error(cfunc.pos, "previous declaration here")
1932 for i, (formal_arg, type_arg) in enumerate(zip(self.args, cfunc_type.args)):
1933 name_declarator, type = formal_arg.analyse(scope, nonempty=1,
1934 is_self_arg = (i == 0 and scope.is_c_class_scope))
1935 if type is None or type is PyrexTypes.py_object_type:
1936 formal_arg.type = type_arg.type
1937 formal_arg.name_declarator = name_declarator
1939 if cfunc_type.exception_value is None:
1940 exception_value = None
1942 exception_value = ExprNodes.ConstNode(self.pos, value=cfunc_type.exception_value, type=cfunc_type.return_type)
1943 declarator = CFuncDeclaratorNode(self.pos,
1944 base = CNameDeclaratorNode(self.pos, name=self.name, cname=None),
1946 has_varargs = False,
1947 exception_check = cfunc_type.exception_check,
1948 exception_value = exception_value,
1949 with_gil = cfunc_type.with_gil,
1950 nogil = cfunc_type.nogil)
1951 return CFuncDefNode(self.pos,
1953 base_type = CAnalysedBaseTypeNode(self.pos, type=cfunc_type.return_type),
1954 declarator = declarator,
1957 overridable = cfunc_type.is_overridable,
1959 with_gil = cfunc_type.with_gil,
1960 nogil = cfunc_type.nogil,
1961 visibility = 'private',
1963 directive_locals = getattr(cfunc, 'directive_locals', {}))
1965 def analyse_declarations(self, env):
1966 self.is_classmethod = self.is_staticmethod = False
1968 for decorator in self.decorators:
1969 func = decorator.decorator
1971 self.is_classmethod |= func.name == 'classmethod'
1972 self.is_staticmethod |= func.name == 'staticmethod'
1974 if self.is_classmethod and env.lookup_here('classmethod'):
1975 # classmethod() was overridden - not much we can do here ...
1976 self.is_classmethod = False
1977 if self.is_staticmethod and env.lookup_here('staticmethod'):
1978 # staticmethod() was overridden - not much we can do here ...
1979 self.is_staticmethod = False
1981 if self.name == '__new__':
1982 self.is_staticmethod = 1
1984 self.analyse_argument_types(env)
1985 if self.name == '<lambda>':
1986 self.declare_lambda_function(env)
1988 self.declare_pyfunction(env)
1989 self.analyse_signature(env)
1990 self.return_type = self.entry.signature.return_type()
1991 self.create_local_scope(env)
1993 def analyse_argument_types(self, env):
1994 directive_locals = self.directive_locals = env.directives['locals']
1995 allow_none_for_extension_args = env.directives['allow_none_for_extension_args']
1996 for arg in self.args:
1997 if hasattr(arg, 'name'):
1999 name_declarator = None
2001 base_type = arg.base_type.analyse(env)
2002 name_declarator, type = \
2003 arg.declarator.analyse(base_type, env)
2004 arg.name = name_declarator.name
2005 if arg.name in directive_locals:
2006 type_node = directive_locals[arg.name]
2007 other_type = type_node.analyse_as_type(env)
2008 if other_type is None:
2009 error(type_node.pos, "Not a type")
2010 elif (type is not PyrexTypes.py_object_type
2011 and not type.same_as(other_type)):
2012 error(arg.base_type.pos, "Signature does not agree with previous declaration")
2013 error(type_node.pos, "Previous declaration here")
2016 if name_declarator and name_declarator.cname:
2018 "Python function argument cannot have C name specification")
2019 arg.type = type.as_argument_type()
2021 arg.needs_conversion = 0
2022 arg.needs_type_test = 0
2024 if arg.type.is_pyobject:
2026 arg.accept_none = True
2028 arg.accept_none = False
2029 elif arg.type.is_extension_type or arg.type.is_builtin_type:
2030 if arg.default and arg.default.constant_result is None:
2031 # special case: def func(MyType obj = None)
2032 arg.accept_none = True
2034 # default depends on compiler directive
2035 arg.accept_none = allow_none_for_extension_args
2037 # probably just a plain 'object'
2038 arg.accept_none = True
2040 arg.accept_none = True # won't be used, but must be there
2042 error(arg.pos, "Only Python type arguments can have 'not None'")
2044 error(arg.pos, "Only Python type arguments can have 'or None'")
2046 def analyse_signature(self, env):
2047 if self.entry.is_special:
2048 self.entry.trivial_signature = len(self.args) == 1 and not (self.star_arg or self.starstar_arg)
2049 elif not env.directives['always_allow_keywords'] and not (self.star_arg or self.starstar_arg):
2050 # Use the simpler calling signature for zero- and one-argument functions.
2051 if self.entry.signature is TypeSlots.pyfunction_signature:
2052 if len(self.args) == 0:
2053 self.entry.signature = TypeSlots.pyfunction_noargs
2054 elif len(self.args) == 1:
2055 if self.args[0].default is None and not self.args[0].kw_only:
2056 self.entry.signature = TypeSlots.pyfunction_onearg
2057 elif self.entry.signature is TypeSlots.pymethod_signature:
2058 if len(self.args) == 1:
2059 self.entry.signature = TypeSlots.unaryfunc
2060 elif len(self.args) == 2:
2061 if self.args[1].default is None and not self.args[1].kw_only:
2062 self.entry.signature = TypeSlots.ibinaryfunc
2064 sig = self.entry.signature
2065 nfixed = sig.num_fixed_args()
2066 if sig is TypeSlots.pymethod_signature and nfixed == 1 \
2067 and len(self.args) == 0 and self.star_arg:
2068 # this is the only case where a diverging number of
2069 # arguments is not an error - when we have no explicit
2070 # 'self' parameter as in method(*args)
2071 sig = self.entry.signature = TypeSlots.pyfunction_signature # self is not 'really' used
2072 self.self_in_stararg = 1
2075 for i in range(min(nfixed, len(self.args))):
2078 if sig.is_self_arg(i) and not self.is_staticmethod:
2079 if self.is_classmethod:
2081 arg.hdr_type = arg.type = Builtin.type_type
2084 arg.hdr_type = arg.type = env.parent_type
2085 arg.needs_conversion = 0
2087 arg.hdr_type = sig.fixed_arg_type(i)
2088 if not arg.type.same_as(arg.hdr_type):
2089 if arg.hdr_type.is_pyobject and arg.type.is_pyobject:
2090 arg.needs_type_test = 1
2092 arg.needs_conversion = 1
2093 if arg.needs_conversion:
2094 arg.hdr_cname = Naming.arg_prefix + arg.name
2096 arg.hdr_cname = Naming.var_prefix + arg.name
2098 if nfixed > len(self.args):
2099 self.bad_signature()
2101 elif nfixed < len(self.args):
2102 if not sig.has_generic_args:
2103 self.bad_signature()
2104 for arg in self.args:
2105 if arg.is_generic and \
2106 (arg.type.is_extension_type or arg.type.is_builtin_type):
2107 arg.needs_type_test = 1
2109 def bad_signature(self):
2110 sig = self.entry.signature
2111 expected_str = "%d" % sig.num_fixed_args()
2112 if sig.has_generic_args:
2113 expected_str = expected_str + " or more"
2115 if name.startswith("__") and name.endswith("__"):
2116 desc = "Special method"
2120 "%s %s has wrong number of arguments "
2121 "(%d declared, %s expected)" % (
2122 desc, self.name, len(self.args), expected_str))
2124 def signature_has_nongeneric_args(self):
2125 argcount = len(self.args)
2126 if argcount == 0 or (
2127 argcount == 1 and (self.args[0].is_self_arg or
2128 self.args[0].is_type_arg)):
2132 def signature_has_generic_args(self):
2133 return self.entry.signature.has_generic_args
2135 def declare_pyfunction(self, env):
2136 #print "DefNode.declare_pyfunction:", self.name, "in", env ###
2138 entry = env.lookup_here(name)
2139 if entry and entry.type.is_cfunction and not self.is_wrapper:
2140 warning(self.pos, "Overriding cdef method with def method.", 5)
2141 entry = env.declare_pyfunction(name, self.pos)
2143 prefix = env.scope_prefix
2144 entry.func_cname = \
2145 Naming.pyfunc_prefix + prefix + name
2146 entry.pymethdef_cname = \
2147 Naming.pymethdef_prefix + prefix + name
2148 if Options.docstrings:
2149 entry.doc = embed_position(self.pos, self.doc)
2151 Naming.funcdoc_prefix + prefix + name
2152 if entry.is_special:
2153 if entry.name in TypeSlots.invisible or not entry.doc or (entry.name in '__getattr__' and env.directives['fast_getattr']):
2154 entry.wrapperbase_cname = None
2156 entry.wrapperbase_cname = Naming.wrapperbase_prefix + prefix + name
2160 def declare_lambda_function(self, env):
2162 prefix = env.scope_prefix
2164 Naming.lambda_func_prefix + u'funcdef' + prefix + self.lambda_name
2165 entry = env.declare_lambda_function(func_cname, self.pos)
2166 entry.pymethdef_cname = \
2167 Naming.lambda_func_prefix + u'methdef' + prefix + self.lambda_name
2168 entry.qualified_name = env.qualify_name(self.lambda_name)
2172 def declare_arguments(self, env):
2173 for arg in self.args:
2175 error(arg.pos, "Missing argument name")
2177 env.control_flow.set_state((), (arg.name, 'source'), 'arg')
2178 env.control_flow.set_state((), (arg.name, 'initialized'), True)
2179 if arg.needs_conversion:
2180 arg.entry = env.declare_var(arg.name, arg.type, arg.pos)
2181 if arg.type.is_pyobject:
2182 arg.entry.init = "0"
2183 arg.entry.init_to_none = 0
2185 arg.entry = self.declare_argument(env, arg)
2187 arg.entry.is_self_arg = arg.is_self_arg
2189 if arg.is_self_arg or arg.is_type_arg or \
2190 (arg.type.is_extension_type and not arg.hdr_type.is_extension_type):
2191 arg.entry.is_declared_generic = 1
2192 self.declare_python_arg(env, self.star_arg)
2193 self.declare_python_arg(env, self.starstar_arg)
2195 def declare_python_arg(self, env, arg):
2197 if env.directives['infer_types'] != False:
2198 type = PyrexTypes.unspecified_type
2200 type = py_object_type
2201 entry = env.declare_var(arg.name, type, arg.pos)
2204 entry.init_to_none = 0
2205 entry.xdecref_cleanup = 1
2207 env.control_flow.set_state((), (arg.name, 'initialized'), True)
2209 def analyse_expressions(self, env):
2210 self.local_scope.directives = env.directives
2211 self.analyse_default_values(env)
2212 if self.needs_assignment_synthesis(env):
2213 # Shouldn't we be doing this at the module level too?
2214 self.synthesize_assignment_node(env)
2216 def needs_assignment_synthesis(self, env, code=None):
2217 # Should enable for module level as well, that will require more testing...
2218 if self.entry.is_lambda:
2220 if env.is_module_scope:
2222 return env.directives['binding']
2224 return code.globalstate.directives['binding']
2225 return env.is_py_class_scope or env.is_closure_scope
2227 def synthesize_assignment_node(self, env):
2230 while genv.is_py_class_scope or genv.is_c_class_scope:
2231 genv = genv.outer_scope
2233 if genv.is_closure_scope:
2234 rhs = ExprNodes.InnerFunctionNode(
2235 self.pos, pymethdef_cname = self.entry.pymethdef_cname)
2237 rhs = ExprNodes.PyCFunctionNode(
2238 self.pos, pymethdef_cname = self.entry.pymethdef_cname, binding = env.directives['binding'])
2240 if env.is_py_class_scope:
2241 if not self.is_staticmethod and not self.is_classmethod:
2244 self.assmt = SingleAssignmentNode(self.pos,
2245 lhs = ExprNodes.NameNode(self.pos, name = self.name),
2247 self.assmt.analyse_declarations(env)
2248 self.assmt.analyse_expressions(env)
2250 def generate_function_header(self, code, with_pymethdef, proto_only=0):
2252 sig = self.entry.signature
2253 if sig.has_dummy_arg or self.self_in_stararg:
2254 arg_code_list.append(
2255 "PyObject *%s" % Naming.self_cname)
2256 for arg in self.args:
2257 if not arg.is_generic:
2258 if arg.is_self_arg or arg.is_type_arg:
2259 arg_code_list.append("PyObject *%s" % arg.hdr_cname)
2261 arg_code_list.append(
2262 arg.hdr_type.declaration_code(arg.hdr_cname))
2263 if not self.entry.is_special and sig.method_flags() == [TypeSlots.method_noargs]:
2264 arg_code_list.append("CYTHON_UNUSED PyObject *unused")
2265 if sig.has_generic_args:
2266 arg_code_list.append(
2267 "PyObject *%s, PyObject *%s"
2268 % (Naming.args_cname, Naming.kwds_cname))
2269 arg_code = ", ".join(arg_code_list)
2270 dc = self.return_type.declaration_code(self.entry.func_cname)
2271 mf = " ".join(self.modifiers).upper()
2273 header = "static %s%s(%s)" % (mf, dc, arg_code)
2274 code.putln("%s; /*proto*/" % header)
2277 if (Options.docstrings and self.entry.doc and
2278 not self.entry.scope.is_property_scope and
2279 (not self.entry.is_special or self.entry.wrapperbase_cname)):
2280 docstr = self.entry.doc
2281 if docstr.is_unicode:
2282 docstr = docstr.utf8encode()
2284 'static char %s[] = "%s";' % (
2285 self.entry.doc_cname,
2286 split_string_literal(escape_byte_string(docstr))))
2287 if self.entry.is_special:
2289 "struct wrapperbase %s;" % self.entry.wrapperbase_cname)
2292 "static PyMethodDef %s = " %
2293 self.entry.pymethdef_cname)
2294 code.put_pymethoddef(self.entry, ";", allow_skip=False)
2295 code.putln("%s {" % header)
2297 def generate_argument_declarations(self, env, code):
2298 for arg in self.args:
2299 if arg.is_generic: # or arg.needs_conversion:
2300 if arg.needs_conversion:
2301 code.putln("PyObject *%s = 0;" % arg.hdr_cname)
2302 elif not arg.entry.in_closure:
2303 code.put_var_declaration(arg.entry)
2305 def generate_keyword_list(self, code):
2306 if self.signature_has_generic_args() and \
2307 self.signature_has_nongeneric_args():
2309 "static PyObject **%s[] = {" %
2310 Naming.pykwdlist_cname)
2311 for arg in self.args:
2313 pystring_cname = code.intern_identifier(arg.name)
2314 code.put('&%s,' % pystring_cname)
2317 def generate_argument_parsing_code(self, env, code):
2318 # Generate PyArg_ParseTuple call for generic
2319 # arguments, if any.
2320 if self.entry.signature.has_dummy_arg and not self.self_in_stararg:
2321 # get rid of unused argument warning
2322 code.putln("%s = %s;" % (Naming.self_cname, Naming.self_cname))
2324 old_error_label = code.new_error_label()
2325 our_error_label = code.error_label
2326 end_label = code.new_label("argument_unpacking_done")
2328 has_kwonly_args = self.num_kwonly_args > 0
2329 has_star_or_kw_args = self.star_arg is not None \
2330 or self.starstar_arg is not None or has_kwonly_args
2332 for arg in self.args:
2333 if not arg.type.is_pyobject:
2334 done = arg.type.create_from_py_utility_code(env)
2335 if not done: pass # will fail later
2337 if not self.signature_has_generic_args():
2338 if has_star_or_kw_args:
2339 error(self.pos, "This method cannot have * or keyword arguments")
2340 self.generate_argument_conversion_code(code)
2342 elif not self.signature_has_nongeneric_args():
2343 # func(*args) or func(**kw) or func(*args, **kw)
2344 self.generate_stararg_copy_code(code)
2347 positional_args = []
2349 for arg in self.args:
2350 arg_entry = arg.entry
2353 if not arg.is_self_arg and not arg.is_type_arg:
2355 kw_only_args.append(arg)
2357 positional_args.append(arg)
2359 kw_only_args.append(arg)
2360 elif not arg.is_self_arg and not arg.is_type_arg:
2361 positional_args.append(arg)
2363 self.generate_tuple_and_keyword_parsing_code(
2364 positional_args, kw_only_args, end_label, code)
2366 code.error_label = old_error_label
2367 if code.label_used(our_error_label):
2368 if not code.label_used(end_label):
2369 code.put_goto(end_label)
2370 code.put_label(our_error_label)
2371 if has_star_or_kw_args:
2372 self.generate_arg_decref(self.star_arg, code)
2373 if self.starstar_arg:
2374 if self.starstar_arg.entry.xdecref_cleanup:
2375 code.put_var_xdecref(self.starstar_arg.entry)
2377 code.put_var_decref(self.starstar_arg.entry)
2378 code.putln('__Pyx_AddTraceback("%s");' % self.entry.qualified_name)
2379 # The arguments are put into the closure one after the
2380 # other, so when type errors are found, all references in
2381 # the closure instance must be properly ref-counted to
2382 # facilitate generic closure instance deallocation. In
2383 # the case of an argument type error, it's best to just
2384 # DECREF+clear the already handled references, as this
2385 # frees their references as early as possible.
2386 for arg in self.args:
2387 if arg.type.is_pyobject and arg.entry.in_closure:
2388 code.put_var_xdecref_clear(arg.entry)
2389 if self.needs_closure:
2390 code.put_decref(Naming.cur_scope_cname, self.local_scope.scope_class.type)
2391 code.put_finish_refcount_context()
2392 code.putln("return %s;" % self.error_value())
2393 if code.label_used(end_label):
2394 code.put_label(end_label)
2396 def generate_arg_assignment(self, arg, item, code):
2397 if arg.type.is_pyobject:
2399 item = PyrexTypes.typecast(arg.type, PyrexTypes.py_object_type, item)
2401 code.putln("%s = %s;" % (entry.cname, item))
2402 if entry.in_closure:
2403 code.put_var_incref(entry)
2405 func = arg.type.from_py_function
2407 code.putln("%s = %s(%s); %s" % (
2411 code.error_goto_if(arg.type.error_condition(arg.entry.cname), arg.pos)))
2413 error(arg.pos, "Cannot convert Python object argument to type '%s'" % arg.type)
2415 def generate_arg_xdecref(self, arg, code):
2417 code.put_var_xdecref(arg.entry)
2419 def generate_arg_decref(self, arg, code):
2421 code.put_var_decref(arg.entry)
2423 def generate_stararg_copy_code(self, code):
2424 if not self.star_arg:
2425 code.globalstate.use_utility_code(raise_argtuple_invalid_utility_code)
2426 code.putln("if (unlikely(PyTuple_GET_SIZE(%s) > 0)) {" %
2428 code.put('__Pyx_RaiseArgtupleInvalid("%s", 1, 0, 0, PyTuple_GET_SIZE(%s)); return %s;' % (
2429 self.name, Naming.args_cname, self.error_value()))
2432 code.globalstate.use_utility_code(keyword_string_check_utility_code)
2434 if self.starstar_arg:
2436 kwarg_check = "unlikely(%s)" % Naming.kwds_cname
2438 kwarg_check = "%s" % Naming.kwds_cname
2440 kwarg_check = "unlikely(%s) && unlikely(PyDict_Size(%s) > 0)" % (
2441 Naming.kwds_cname, Naming.kwds_cname)
2443 "if (%s && unlikely(!__Pyx_CheckKeywordStrings(%s, \"%s\", %d))) return %s;" % (
2444 kwarg_check, Naming.kwds_cname, self.name,
2445 bool(self.starstar_arg), self.error_value()))
2447 if self.starstar_arg:
2448 code.putln("%s = (%s) ? PyDict_Copy(%s) : PyDict_New();" % (
2449 self.starstar_arg.entry.cname,
2452 code.putln("if (unlikely(!%s)) return %s;" % (
2453 self.starstar_arg.entry.cname, self.error_value()))
2454 self.starstar_arg.entry.xdecref_cleanup = 0
2455 code.put_gotref(self.starstar_arg.entry.cname)
2457 if self.self_in_stararg:
2458 # need to create a new tuple with 'self' inserted as first item
2459 code.put("%s = PyTuple_New(PyTuple_GET_SIZE(%s)+1); if (unlikely(!%s)) " % (
2460 self.star_arg.entry.cname,
2462 self.star_arg.entry.cname))
2463 if self.starstar_arg:
2465 code.put_decref_clear(self.starstar_arg.entry.cname, py_object_type)
2466 code.putln("return %s;" % self.error_value())
2469 code.putln("return %s;" % self.error_value())
2470 code.put_gotref(self.star_arg.entry.cname)
2471 code.put_incref(Naming.self_cname, py_object_type)
2472 code.put_giveref(Naming.self_cname)
2473 code.putln("PyTuple_SET_ITEM(%s, 0, %s);" % (
2474 self.star_arg.entry.cname, Naming.self_cname))
2475 temp = code.funcstate.allocate_temp(PyrexTypes.c_py_ssize_t_type, manage_ref=False)
2476 code.putln("for (%s=0; %s < PyTuple_GET_SIZE(%s); %s++) {" % (
2477 temp, temp, Naming.args_cname, temp))
2478 code.putln("PyObject* item = PyTuple_GET_ITEM(%s, %s);" % (
2479 Naming.args_cname, temp))
2480 code.put_incref("item", py_object_type)
2481 code.put_giveref("item")
2482 code.putln("PyTuple_SET_ITEM(%s, %s+1, item);" % (
2483 self.star_arg.entry.cname, temp))
2485 code.funcstate.release_temp(temp)
2486 self.star_arg.entry.xdecref_cleanup = 0
2488 code.put_incref(Naming.args_cname, py_object_type)
2489 code.putln("%s = %s;" % (
2490 self.star_arg.entry.cname,
2492 self.star_arg.entry.xdecref_cleanup = 0
2494 def generate_tuple_and_keyword_parsing_code(self, positional_args,
2495 kw_only_args, success_label, code):
2496 argtuple_error_label = code.new_label("argtuple_error")
2498 min_positional_args = self.num_required_args - self.num_required_kw_args
2499 if len(self.args) > 0 and (self.args[0].is_self_arg or self.args[0].is_type_arg):
2500 min_positional_args -= 1
2501 max_positional_args = len(positional_args)
2502 has_fixed_positional_count = not self.star_arg and \
2503 min_positional_args == max_positional_args
2505 code.globalstate.use_utility_code(raise_double_keywords_utility_code)
2506 code.globalstate.use_utility_code(raise_argtuple_invalid_utility_code)
2507 if self.num_required_kw_args:
2508 code.globalstate.use_utility_code(raise_keyword_required_utility_code)
2510 if self.starstar_arg or self.star_arg:
2511 self.generate_stararg_init_code(max_positional_args, code)
2513 # --- optimised code when we receive keyword arguments
2514 if self.num_required_kw_args:
2515 likely_hint = "likely"
2517 likely_hint = "unlikely"
2518 code.putln("if (%s(%s)) {" % (likely_hint, Naming.kwds_cname))
2519 self.generate_keyword_unpacking_code(
2520 min_positional_args, max_positional_args,
2521 has_fixed_positional_count,
2522 positional_args, kw_only_args, argtuple_error_label, code)
2524 # --- optimised code when we do not receive any keyword arguments
2525 if (self.num_required_kw_args and min_positional_args > 0) or min_positional_args == max_positional_args:
2526 # Python raises arg tuple related errors first, so we must
2527 # check the length here
2528 if min_positional_args == max_positional_args and not self.star_arg:
2532 code.putln('} else if (PyTuple_GET_SIZE(%s) %s %d) {' % (
2533 Naming.args_cname, compare, min_positional_args))
2534 code.put_goto(argtuple_error_label)
2536 if self.num_required_kw_args:
2537 # pure error case: keywords required but not passed
2538 if max_positional_args > min_positional_args and not self.star_arg:
2539 code.putln('} else if (PyTuple_GET_SIZE(%s) > %d) {' % (
2540 Naming.args_cname, max_positional_args))
2541 code.put_goto(argtuple_error_label)
2542 code.putln('} else {')
2543 for i, arg in enumerate(kw_only_args):
2545 pystring_cname = code.intern_identifier(arg.name)
2546 # required keyword-only argument missing
2547 code.put('__Pyx_RaiseKeywordRequired("%s", %s); ' % (
2550 code.putln(code.error_goto(self.pos))
2553 elif min_positional_args == max_positional_args:
2554 # parse the exact number of positional arguments from the
2556 code.putln('} else {')
2557 for i, arg in enumerate(positional_args):
2558 item = "PyTuple_GET_ITEM(%s, %d)" % (Naming.args_cname, i)
2559 self.generate_arg_assignment(arg, item, code)
2560 self.generate_arg_default_assignments(code)
2563 # parse the positional arguments from the variable length
2565 code.putln('} else {')
2566 self.generate_arg_default_assignments(code)
2567 code.putln('switch (PyTuple_GET_SIZE(%s)) {' % Naming.args_cname)
2569 code.putln('default:')
2570 reversed_args = list(enumerate(positional_args))[::-1]
2571 for i, arg in reversed_args:
2572 if i >= min_positional_args-1:
2573 if min_positional_args > 1:
2574 code.putln('case %2d:' % (i+1)) # pure code beautification
2576 code.put('case %2d: ' % (i+1))
2577 item = "PyTuple_GET_ITEM(%s, %d)" % (Naming.args_cname, i)
2578 self.generate_arg_assignment(arg, item, code)
2579 if min_positional_args == 0:
2580 code.put('case 0: ')
2581 code.putln('break;')
2583 if min_positional_args:
2584 for i in range(min_positional_args-1, -1, -1):
2585 code.putln('case %2d:' % i)
2586 code.put_goto(argtuple_error_label)
2588 code.put('default: ')
2589 code.put_goto(argtuple_error_label)
2594 if code.label_used(argtuple_error_label):
2595 code.put_goto(success_label)
2596 code.put_label(argtuple_error_label)
2597 code.put('__Pyx_RaiseArgtupleInvalid("%s", %d, %d, %d, PyTuple_GET_SIZE(%s)); ' % (
2598 self.name, has_fixed_positional_count,
2599 min_positional_args, max_positional_args,
2601 code.putln(code.error_goto(self.pos))
2603 def generate_arg_default_assignments(self, code):
2604 for arg in self.args:
2605 if arg.is_generic and arg.default:
2609 arg.calculate_default_value_code(code)))
2611 def generate_stararg_init_code(self, max_positional_args, code):
2612 if self.starstar_arg:
2613 self.starstar_arg.entry.xdecref_cleanup = 0
2614 code.putln('%s = PyDict_New(); if (unlikely(!%s)) return %s;' % (
2615 self.starstar_arg.entry.cname,
2616 self.starstar_arg.entry.cname,
2617 self.error_value()))
2618 code.put_gotref(self.starstar_arg.entry.cname)
2620 self.star_arg.entry.xdecref_cleanup = 0
2621 code.putln('if (PyTuple_GET_SIZE(%s) > %d) {' % (
2623 max_positional_args))
2624 code.put('%s = PyTuple_GetSlice(%s, %d, PyTuple_GET_SIZE(%s)); ' % (
2625 self.star_arg.entry.cname, Naming.args_cname,
2626 max_positional_args, Naming.args_cname))
2627 code.put_gotref(self.star_arg.entry.cname)
2628 if self.starstar_arg:
2630 code.putln("if (unlikely(!%s)) {" % self.star_arg.entry.cname)
2631 code.put_decref(self.starstar_arg.entry.cname, py_object_type)
2632 code.putln('return %s;' % self.error_value())
2635 code.putln("if (unlikely(!%s)) return %s;" % (
2636 self.star_arg.entry.cname, self.error_value()))
2637 code.putln('} else {')
2638 code.put("%s = %s; " % (self.star_arg.entry.cname, Naming.empty_tuple))
2639 code.put_incref(Naming.empty_tuple, py_object_type)
2642 def generate_keyword_unpacking_code(self, min_positional_args, max_positional_args,
2643 has_fixed_positional_count, positional_args,
2644 kw_only_args, argtuple_error_label, code):
2645 all_args = tuple(positional_args) + tuple(kw_only_args)
2646 max_args = len(all_args)
2648 code.putln("Py_ssize_t kw_args = PyDict_Size(%s);" %
2650 # the 'values' array collects borrowed references to arguments
2651 # before doing any type coercion etc.
2652 code.putln("PyObject* values[%d] = {%s};" % (
2653 max_args, ','.join('0'*max_args)))
2655 # assign borrowed Python default values to the values array,
2656 # so that they can be overwritten by received arguments below
2657 for i, arg in enumerate(all_args):
2658 if arg.default and arg.type.is_pyobject:
2659 default_value = arg.calculate_default_value_code(code)
2660 code.putln('values[%d] = %s;' % (i, arg.type.as_pyobject(default_value)))
2662 # parse the args tuple and check that it's not too long
2663 code.putln('switch (PyTuple_GET_SIZE(%s)) {' % Naming.args_cname)
2665 code.putln('default:')
2666 for i in range(max_positional_args-1, -1, -1):
2667 code.put('case %2d: ' % (i+1))
2668 code.putln("values[%d] = PyTuple_GET_ITEM(%s, %d);" % (
2669 i, Naming.args_cname, i))
2670 code.putln('case 0: break;')
2671 if not self.star_arg:
2672 code.put('default: ') # more arguments than allowed
2673 code.put_goto(argtuple_error_label)
2676 # now fill up the positional/required arguments with values
2678 if self.num_required_args or max_positional_args > 0:
2679 last_required_arg = -1
2680 for i, arg in enumerate(all_args):
2682 last_required_arg = i
2683 if last_required_arg < max_positional_args:
2684 last_required_arg = max_positional_args-1
2685 num_required_args = self.num_required_args
2686 if max_positional_args > 0:
2687 code.putln('switch (PyTuple_GET_SIZE(%s)) {' % Naming.args_cname)
2688 for i, arg in enumerate(all_args[:last_required_arg+1]):
2689 if max_positional_args > 0 and i <= max_positional_args:
2690 if self.star_arg and i == max_positional_args:
2691 code.putln('default:')
2693 code.putln('case %2d:' % i)
2694 pystring_cname = code.intern_identifier(arg.name)
2697 # handled separately below
2699 code.putln('if (kw_args > 0) {')
2700 code.putln('PyObject* value = PyDict_GetItem(%s, %s);' % (
2701 Naming.kwds_cname, pystring_cname))
2702 code.putln('if (value) { values[%d] = value; kw_args--; }' % i)
2705 num_required_args -= 1
2706 code.putln('values[%d] = PyDict_GetItem(%s, %s);' % (
2707 i, Naming.kwds_cname, pystring_cname))
2708 code.putln('if (likely(values[%d])) kw_args--;' % i);
2709 if i < min_positional_args:
2711 # special case: we know arg 0 is missing
2713 code.put_goto(argtuple_error_label)
2715 # print the correct number of values (args or
2716 # kwargs) that were passed into positional
2717 # arguments up to this point
2718 code.putln('else {')
2719 code.put('__Pyx_RaiseArgtupleInvalid("%s", %d, %d, %d, %d); ' % (
2720 self.name, has_fixed_positional_count,
2721 min_positional_args, max_positional_args, i))
2722 code.putln(code.error_goto(self.pos))
2725 code.putln('else {')
2726 code.put('__Pyx_RaiseKeywordRequired("%s", %s); ' %(
2727 self.name, pystring_cname))
2728 code.putln(code.error_goto(self.pos))
2730 if max_positional_args > 0:
2733 if kw_only_args and not self.starstar_arg:
2734 # unpack optional keyword-only arguments
2735 # checking for interned strings in a dict is faster than iterating
2736 # but it's too likely that we must iterate if we expect **kwargs
2738 for i, arg in enumerate(all_args[max_positional_args:]):
2739 if not arg.kw_only or not arg.default:
2741 optional_args.append((i+max_positional_args, arg))
2743 # this mimics an unrolled loop so that we can "break" out of it
2744 code.putln('while (kw_args > 0) {')
2745 code.putln('PyObject* value;')
2746 for i, arg in optional_args:
2747 pystring_cname = code.intern_identifier(arg.name)
2749 'value = PyDict_GetItem(%s, %s);' % (
2750 Naming.kwds_cname, pystring_cname))
2752 'if (value) { values[%d] = value; if (!(--kw_args)) break; }' % i)
2753 code.putln('break;')
2756 code.putln('if (unlikely(kw_args > 0)) {')
2757 # non-positional/-required kw args left in dict: default args,
2758 # kw-only args, **kwargs or error
2760 # This is sort of a catch-all: except for checking required
2761 # arguments, this will always do the right thing for unpacking
2762 # keyword arguments, so that we can concentrate on optimising
2763 # common cases above.
2764 if max_positional_args == 0:
2767 code.putln("const Py_ssize_t used_pos_args = (PyTuple_GET_SIZE(%s) < %d) ? PyTuple_GET_SIZE(%s) : %d;" % (
2768 Naming.args_cname, max_positional_args,
2769 Naming.args_cname, max_positional_args))
2770 pos_arg_count = "used_pos_args"
2772 pos_arg_count = "PyTuple_GET_SIZE(%s)" % Naming.args_cname
2773 code.globalstate.use_utility_code(parse_keywords_utility_code)
2775 'if (unlikely(__Pyx_ParseOptionalKeywords(%s, %s, %s, values, %s, "%s") < 0)) ' % (
2777 Naming.pykwdlist_cname,
2778 self.starstar_arg and self.starstar_arg.entry.cname or '0',
2781 code.putln(code.error_goto(self.pos))
2784 # convert arg values to their final type and assign them
2785 for i, arg in enumerate(all_args):
2786 if arg.default and not arg.type.is_pyobject:
2787 code.putln("if (values[%d]) {" % i)
2788 self.generate_arg_assignment(arg, "values[%d]" % i, code)
2789 if arg.default and not arg.type.is_pyobject:
2790 code.putln('} else {')
2794 arg.calculate_default_value_code(code)))
2797 def generate_argument_conversion_code(self, code):
2798 # Generate code to convert arguments from signature type to
2799 # declared type, if needed. Also copies signature arguments
2800 # into closure fields.
2801 for arg in self.args:
2802 if arg.needs_conversion:
2803 self.generate_arg_conversion(arg, code)
2804 elif arg.entry.in_closure:
2805 code.putln('%s = %s;' % (arg.entry.cname, arg.hdr_cname))
2806 if arg.type.is_pyobject:
2807 code.put_var_incref(arg.entry)
2809 def generate_arg_conversion(self, arg, code):
2810 # Generate conversion code for one argument.
2811 old_type = arg.hdr_type
2813 if old_type.is_pyobject:
2815 code.putln("if (%s) {" % arg.hdr_cname)
2817 code.putln("assert(%s); {" % arg.hdr_cname)
2818 self.generate_arg_conversion_from_pyobject(arg, code)
2820 elif new_type.is_pyobject:
2821 self.generate_arg_conversion_to_pyobject(arg, code)
2823 if new_type.assignable_from(old_type):
2825 "%s = %s;" % (arg.entry.cname, arg.hdr_cname))
2828 "Cannot convert 1 argument from '%s' to '%s'" %
2829 (old_type, new_type))
2831 def generate_arg_conversion_from_pyobject(self, arg, code):
2833 func = new_type.from_py_function
2834 # copied from CoerceFromPyTypeNode
2836 lhs = arg.entry.cname
2837 rhs = "%s(%s)" % (func, arg.hdr_cname)
2838 if new_type.is_enum:
2839 rhs = PyrexTypes.typecast(new_type, PyrexTypes.c_long_type, rhs)
2840 code.putln("%s = %s; %s" % (
2843 code.error_goto_if(new_type.error_condition(arg.entry.cname), arg.pos)))
2846 "Cannot convert Python object argument to type '%s'"
2849 def generate_arg_conversion_to_pyobject(self, arg, code):
2850 old_type = arg.hdr_type
2851 func = old_type.to_py_function
2853 code.putln("%s = %s(%s); %s" % (
2857 code.error_goto_if_null(arg.entry.cname, arg.pos)))
2858 code.put_var_gotref(arg.entry)
2861 "Cannot convert argument of type '%s' to Python object"
2864 def generate_argument_type_tests(self, code):
2865 # Generate type tests for args whose signature
2866 # type is PyObject * and whose declared type is
2867 # a subtype thereof.
2868 for arg in self.args:
2869 if arg.needs_type_test:
2870 self.generate_arg_type_test(arg, code)
2871 elif not arg.accept_none and arg.type.is_pyobject:
2872 self.generate_arg_none_check(arg, code)
2874 def error_value(self):
2875 return self.entry.signature.error_value
2877 def caller_will_check_exceptions(self):
2880 class OverrideCheckNode(StatNode):
2881 # A Node for dispatching to the def method if it
2890 child_attrs = ['body']
2894 def analyse_expressions(self, env):
2895 self.args = env.arg_entries
2896 if self.py_func.is_module_scope:
2901 self.func_node = ExprNodes.RawCNameExprNode(self.pos, py_object_type)
2902 call_tuple = ExprNodes.TupleNode(self.pos, args=[ExprNodes.NameNode(self.pos, name=arg.name) for arg in self.args[first_arg:]])
2903 call_node = ExprNodes.SimpleCallNode(self.pos,
2904 function=self.func_node,
2905 args=[ExprNodes.NameNode(self.pos, name=arg.name) for arg in self.args[first_arg:]])
2906 self.body = ReturnStatNode(self.pos, value=call_node)
2907 self.body.analyse_expressions(env)
2909 def generate_execution_code(self, code):
2910 interned_attr_cname = code.intern_identifier(self.py_func.entry.name)
2911 # Check to see if we are an extension type
2912 if self.py_func.is_module_scope:
2913 self_arg = "((PyObject *)%s)" % Naming.module_cname
2915 self_arg = "((PyObject *)%s)" % self.args[0].cname
2916 code.putln("/* Check if called by wrapper */")
2917 code.putln("if (unlikely(%s)) ;" % Naming.skip_dispatch_cname)
2918 code.putln("/* Check if overriden in Python */")
2919 if self.py_func.is_module_scope:
2920 code.putln("else {")
2922 code.putln("else if (unlikely(Py_TYPE(%s)->tp_dictoffset != 0)) {" % self_arg)
2923 func_node_temp = code.funcstate.allocate_temp(py_object_type, manage_ref=True)
2924 self.func_node.set_cname(func_node_temp)
2925 # need to get attribute manually--scope would return cdef method
2926 err = code.error_goto_if_null(func_node_temp, self.pos)
2927 code.putln("%s = PyObject_GetAttr(%s, %s); %s" % (
2928 func_node_temp, self_arg, interned_attr_cname, err))
2929 code.put_gotref(func_node_temp)
2930 is_builtin_function_or_method = "PyCFunction_Check(%s)" % func_node_temp
2931 is_overridden = "(PyCFunction_GET_FUNCTION(%s) != (void *)&%s)" % (
2932 func_node_temp, self.py_func.entry.func_cname)
2933 code.putln("if (!%s || %s) {" % (is_builtin_function_or_method, is_overridden))
2934 self.body.generate_execution_code(code)
2936 code.put_decref_clear(func_node_temp, PyrexTypes.py_object_type)
2937 code.funcstate.release_temp(func_node_temp)
2940 class ClassDefNode(StatNode, BlockNode):
2943 class PyClassDefNode(ClassDefNode):
2944 # A Python class definition.
2946 # name EncodedString Name of the class
2947 # doc string or None
2948 # body StatNode Attribute definition code
2949 # entry Symtab.Entry
2950 # scope PyClassScope
2951 # decorators [DecoratorNode] list of decorators or None
2953 # The following subnodes are constructed internally:
2955 # dict DictNode Class dictionary or Py3 namespace
2956 # classobj ClassNode Class object
2957 # target NameNode Variable to assign class object to
2959 child_attrs = ["body", "dict", "metaclass", "mkw", "bases", "classobj", "target"]
2961 py3_style_class = False # Python3 style class (bases+kwargs)
2963 def __init__(self, pos, name, bases, doc, body, decorators = None,
2964 keyword_args = None, starstar_arg = None):
2965 StatNode.__init__(self, pos)
2969 self.decorators = decorators
2971 if self.doc and Options.docstrings:
2972 doc = embed_position(self.pos, self.doc)
2973 doc_node = ExprNodes.StringNode(pos, value = doc)
2976 if keyword_args or starstar_arg:
2977 self.py3_style_class = True
2979 self.metaclass = None
2980 if keyword_args and not starstar_arg:
2981 for i, item in list(enumerate(keyword_args.key_value_pairs))[::-1]:
2982 if item.key.value == 'metaclass':
2983 if self.metaclass is not None:
2984 error(item.pos, "keyword argument 'metaclass' passed multiple times")
2985 # special case: we already know the metaclass,
2986 # so we don't need to do the "build kwargs,
2987 # find metaclass" dance at runtime
2988 self.metaclass = item.value
2989 del keyword_args.key_value_pairs[i]
2990 if starstar_arg or (keyword_args and keyword_args.key_value_pairs):
2991 self.mkw = ExprNodes.KeywordArgsNode(
2992 pos, keyword_args = keyword_args, starstar_arg = starstar_arg)
2994 self.mkw = ExprNodes.NullNode(pos)
2995 if self.metaclass is None:
2996 self.metaclass = ExprNodes.PyClassMetaclassNode(
2997 pos, mkw = self.mkw, bases = self.bases)
2998 self.dict = ExprNodes.PyClassNamespaceNode(pos, name = name,
2999 doc = doc_node, metaclass = self.metaclass, bases = self.bases,
3001 self.classobj = ExprNodes.Py3ClassNode(pos, name = name,
3002 bases = self.bases, dict = self.dict, doc = doc_node,
3003 metaclass = self.metaclass, mkw = self.mkw)
3005 self.dict = ExprNodes.DictNode(pos, key_value_pairs = [])
3006 self.metaclass = None
3009 self.classobj = ExprNodes.ClassNode(pos, name = name,
3010 bases = bases, dict = self.dict, doc = doc_node)
3011 self.target = ExprNodes.NameNode(pos, name = name)
3013 def as_cclass(self):
3015 Return this node as if it were declared as an extension class
3017 if self.py3_style_class:
3018 error(self.classobj.pos, "Python3 style class could not be represented as C class")
3020 bases = self.classobj.bases.args
3022 base_class_name = None
3023 base_class_module = None
3024 elif len(bases) == 1:
3027 from ExprNodes import AttributeNode, NameNode
3028 while isinstance(base, AttributeNode):
3029 path.insert(0, base.attribute)
3031 if isinstance(base, NameNode):
3032 path.insert(0, base.name)
3033 base_class_name = path[-1]
3035 base_class_module = u'.'.join(path[:-1])
3037 base_class_module = None
3039 error(self.classobj.bases.args.pos, "Invalid base class")
3041 error(self.classobj.bases.args.pos, "C class may only have one base class")
3044 return CClassDefNode(self.pos,
3045 visibility = 'private',
3047 class_name = self.name,
3048 base_class_module = base_class_module,
3049 base_class_name = base_class_name,
3050 decorators = self.decorators,
3055 def create_scope(self, env):
3057 while genv.is_py_class_scope or genv.is_c_class_scope:
3058 genv = genv.outer_scope
3059 cenv = self.scope = PyClassScope(name = self.name, outer_scope = genv)
3062 def analyse_declarations(self, env):
3063 self.target.analyse_target_declaration(env)
3064 cenv = self.create_scope(env)
3065 cenv.directives = env.directives
3066 cenv.class_obj_cname = self.target.entry.cname
3067 self.body.analyse_declarations(cenv)
3069 def analyse_expressions(self, env):
3070 if self.py3_style_class:
3071 self.bases.analyse_expressions(env)
3072 self.metaclass.analyse_expressions(env)
3073 self.mkw.analyse_expressions(env)
3074 self.dict.analyse_expressions(env)
3075 self.classobj.analyse_expressions(env)
3076 genv = env.global_scope()
3078 self.body.analyse_expressions(cenv)
3079 self.target.analyse_target_expression(env, self.classobj)
3081 def generate_function_definitions(self, env, code):
3082 self.body.generate_function_definitions(self.scope, code)
3084 def generate_execution_code(self, code):
3085 code.pyclass_stack.append(self)
3087 if self.py3_style_class:
3088 self.bases.generate_evaluation_code(code)
3089 self.mkw.generate_evaluation_code(code)
3090 self.metaclass.generate_evaluation_code(code)
3091 self.dict.generate_evaluation_code(code)
3092 cenv.namespace_cname = cenv.class_obj_cname = self.dict.result()
3093 self.body.generate_execution_code(code)
3094 self.classobj.generate_evaluation_code(code)
3095 cenv.namespace_cname = cenv.class_obj_cname = self.classobj.result()
3096 self.target.generate_assignment_code(self.classobj, code)
3097 self.dict.generate_disposal_code(code)
3098 self.dict.free_temps(code)
3099 if self.py3_style_class:
3100 self.mkw.generate_disposal_code(code)
3101 self.mkw.free_temps(code)
3102 self.metaclass.generate_disposal_code(code)
3103 self.metaclass.free_temps(code)
3104 self.bases.generate_disposal_code(code)
3105 self.bases.free_temps(code)
3106 code.pyclass_stack.pop()
3108 class CClassDefNode(ClassDefNode):
3109 # An extension type definition.
3111 # visibility 'private' or 'public' or 'extern'
3112 # typedef_flag boolean
3114 # module_name string or None For import of extern type objects
3115 # class_name string Unqualified name of class
3116 # as_name string or None Name to declare as in this scope
3117 # base_class_module string or None Module containing the base class
3118 # base_class_name string or None Name of the base class
3119 # objstruct_name string or None Specified C name of object struct
3120 # typeobj_name string or None Specified C name of type object
3121 # in_pxd boolean Is in a .pxd file
3122 # decorators [DecoratorNode] list of decorators or None
3123 # doc string or None
3124 # body StatNode or None
3125 # entry Symtab.Entry
3126 # base_type PyExtensionType or None
3127 # buffer_defaults_node DictNode or None Declares defaults for a buffer
3128 # buffer_defaults_pos
3130 child_attrs = ["body"]
3131 buffer_defaults_node = None
3132 buffer_defaults_pos = None
3133 typedef_flag = False
3135 objstruct_name = None
3139 def analyse_declarations(self, env):
3140 #print "CClassDefNode.analyse_declarations:", self.class_name
3141 #print "...visibility =", self.visibility
3142 #print "...module_name =", self.module_name
3145 if self.buffer_defaults_node:
3146 buffer_defaults = Buffer.analyse_buffer_options(self.buffer_defaults_pos,
3147 env, [], self.buffer_defaults_node,
3148 need_complete=False)
3150 buffer_defaults = None
3152 if env.in_cinclude and not self.objstruct_name:
3153 error(self.pos, "Object struct name specification required for "
3154 "C class defined in 'extern from' block")
3155 self.base_type = None
3156 # Now that module imports are cached, we need to
3157 # import the modules for extern classes.
3158 if self.module_name:
3160 for module in env.cimported_modules:
3161 if module.name == self.module_name:
3162 self.module = module
3163 if self.module is None:
3164 self.module = ModuleScope(self.module_name, None, env.context)
3165 self.module.has_extern_class = 1
3166 env.add_imported_module(self.module)
3168 if self.base_class_name:
3169 if self.base_class_module:
3170 base_class_scope = env.find_module(self.base_class_module, self.pos)
3172 base_class_scope = env
3173 if self.base_class_name == 'object':
3174 # extension classes are special and don't need to inherit from object
3175 if base_class_scope is None or base_class_scope.lookup('object') is None:
3176 self.base_class_name = None
3177 self.base_class_module = None
3178 base_class_scope = None
3179 if base_class_scope:
3180 base_class_entry = base_class_scope.find(self.base_class_name, self.pos)
3181 if base_class_entry:
3182 if not base_class_entry.is_type:
3183 error(self.pos, "'%s' is not a type name" % self.base_class_name)
3184 elif not base_class_entry.type.is_extension_type:
3185 error(self.pos, "'%s' is not an extension type" % self.base_class_name)
3186 elif not base_class_entry.type.is_complete():
3187 error(self.pos, "Base class '%s' of type '%s' is incomplete" % (
3188 self.base_class_name, self.class_name))
3189 elif base_class_entry.type.scope and base_class_entry.type.scope.directives and \
3190 base_class_entry.type.scope.directives['final']:
3191 error(self.pos, "Base class '%s' of type '%s' is final" % (
3192 self.base_class_name, self.class_name))
3194 self.base_type = base_class_entry.type
3195 has_body = self.body is not None
3196 if self.module_name and self.visibility != 'extern':
3197 module_path = self.module_name.split(".")
3198 home_scope = env.find_imported_module(module_path, self.pos)
3204 if self.visibility == 'extern':
3205 if self.module_name == '__builtin__' and self.class_name in Builtin.builtin_types:
3206 warning(self.pos, "%s already a builtin Cython type" % self.class_name, 1)
3208 self.entry = home_scope.declare_c_class(
3209 name = self.class_name,
3211 defining = has_body and self.in_pxd,
3212 implementing = has_body and not self.in_pxd,
3213 module_name = self.module_name,
3214 base_type = self.base_type,
3215 objstruct_cname = self.objstruct_name,
3216 typeobj_cname = self.typeobj_name,
3217 visibility = self.visibility,
3218 typedef_flag = self.typedef_flag,
3220 buffer_defaults = buffer_defaults)
3221 if home_scope is not env and self.visibility == 'extern':
3222 env.add_imported_entry(self.class_name, self.entry, self.pos)
3223 self.scope = scope = self.entry.type.scope
3224 if scope is not None:
3225 scope.directives = env.directives
3227 if self.doc and Options.docstrings:
3228 scope.doc = embed_position(self.pos, self.doc)
3231 self.body.analyse_declarations(scope)
3235 scope.implemented = 1
3236 env.allocate_vtable_names(self.entry)
3238 def analyse_expressions(self, env):
3240 scope = self.entry.type.scope
3241 self.body.analyse_expressions(scope)
3243 def generate_function_definitions(self, env, code):
3245 self.body.generate_function_definitions(
3246 self.entry.type.scope, code)
3248 def generate_execution_code(self, code):
3249 # This is needed to generate evaluation code for
3250 # default values of method arguments.
3252 self.body.generate_execution_code(code)
3254 def annotate(self, code):
3256 self.body.annotate(code)
3259 class PropertyNode(StatNode):
3260 # Definition of a property in an extension type.
3263 # doc EncodedString or None Doc string
3266 child_attrs = ["body"]
3268 def analyse_declarations(self, env):
3269 entry = env.declare_property(self.name, self.doc, self.pos)
3271 entry.scope.directives = env.directives
3272 self.body.analyse_declarations(entry.scope)
3274 def analyse_expressions(self, env):
3275 self.body.analyse_expressions(env)
3277 def generate_function_definitions(self, env, code):
3278 self.body.generate_function_definitions(env, code)
3280 def generate_execution_code(self, code):
3283 def annotate(self, code):
3284 self.body.annotate(code)
3287 class GlobalNode(StatNode):
3288 # Global variable declaration.
3294 def analyse_declarations(self, env):
3295 for name in self.names:
3296 env.declare_global(name, self.pos)
3298 def analyse_expressions(self, env):
3301 def generate_execution_code(self, code):
3305 class ExprStatNode(StatNode):
3306 # Expression used as a statement.
3310 child_attrs = ["expr"]
3312 def analyse_declarations(self, env):
3314 if isinstance(self.expr, ExprNodes.GeneralCallNode):
3315 func = self.expr.function.as_cython_attribute()
3316 if func == u'declare':
3317 args, kwds = self.expr.explicit_args_kwds()
3319 error(self.expr.pos, "Variable names must be specified.")
3320 for var, type_node in kwds.key_value_pairs:
3321 type = type_node.analyse_as_type(env)
3323 error(type_node.pos, "Unknown type")
3325 env.declare_var(var.value, type, var.pos, is_cdef = True)
3326 self.__class__ = PassStatNode
3328 def analyse_expressions(self, env):
3329 self.expr.analyse_expressions(env)
3331 def generate_execution_code(self, code):
3332 self.expr.generate_evaluation_code(code)
3333 if not self.expr.is_temp and self.expr.result():
3334 code.putln("%s;" % self.expr.result())
3335 self.expr.generate_disposal_code(code)
3336 self.expr.free_temps(code)
3338 def generate_function_definitions(self, env, code):
3339 self.expr.generate_function_definitions(env, code)
3341 def annotate(self, code):
3342 self.expr.annotate(code)
3345 class AssignmentNode(StatNode):
3346 # Abstract base class for assignment nodes.
3348 # The analyse_expressions and generate_execution_code
3349 # phases of assignments are split into two sub-phases
3350 # each, to enable all the right hand sides of a
3351 # parallel assignment to be evaluated before assigning
3352 # to any of the left hand sides.
3354 def analyse_expressions(self, env):
3355 self.analyse_types(env)
3357 # def analyse_expressions(self, env):
3358 # self.analyse_expressions_1(env)
3359 # self.analyse_expressions_2(env)
3361 def generate_execution_code(self, code):
3362 self.generate_rhs_evaluation_code(code)
3363 self.generate_assignment_code(code)
3366 class SingleAssignmentNode(AssignmentNode):
3367 # The simplest case:
3371 # lhs ExprNode Left hand side
3372 # rhs ExprNode Right hand side
3373 # first bool Is this guaranteed the first assignment to lhs?
3375 child_attrs = ["lhs", "rhs"]
3377 declaration_only = False
3379 def analyse_declarations(self, env):
3382 # handle declarations of the form x = cython.foo()
3383 if isinstance(self.rhs, ExprNodes.CallNode):
3384 func_name = self.rhs.function.as_cython_attribute()
3386 args, kwds = self.rhs.explicit_args_kwds()
3388 if func_name in ['declare', 'typedef']:
3389 if len(args) > 2 or kwds is not None:
3390 error(self.rhs.pos, "Can only declare one type at a time.")
3392 type = args[0].analyse_as_type(env)
3394 error(args[0].pos, "Unknown type")
3397 if func_name == 'declare':
3398 if isinstance(lhs, ExprNodes.NameNode):
3399 vars = [(lhs.name, lhs.pos)]
3400 elif isinstance(lhs, ExprNodes.TupleNode):
3401 vars = [(var.name, var.pos) for var in lhs.args]
3403 error(lhs.pos, "Invalid declaration")
3405 for var, pos in vars:
3406 env.declare_var(var, type, pos, is_cdef = True)
3411 self.declaration_only = True
3413 self.declaration_only = True
3414 if not isinstance(lhs, ExprNodes.NameNode):
3415 error(lhs.pos, "Invalid declaration.")
3416 env.declare_typedef(lhs.name, type, self.pos, visibility='private')
3418 elif func_name in ['struct', 'union']:
3419 self.declaration_only = True
3420 if len(args) > 0 or kwds is None:
3421 error(self.rhs.pos, "Struct or union members must be given by name.")
3424 for member, type_node in kwds.key_value_pairs:
3425 type = type_node.analyse_as_type(env)
3427 error(type_node.pos, "Unknown type")
3429 members.append((member.value, type, member.pos))
3430 if len(members) < len(kwds.key_value_pairs):
3432 if not isinstance(self.lhs, ExprNodes.NameNode):
3433 error(self.lhs.pos, "Invalid declaration.")
3434 name = self.lhs.name
3435 scope = StructOrUnionScope(name)
3436 env.declare_struct_or_union(name, func_name, scope, False, self.rhs.pos)
3437 for member, type, pos in members:
3438 scope.declare_var(member, type, pos)
3440 if self.declaration_only:
3443 self.lhs.analyse_target_declaration(env)
3445 def analyse_types(self, env, use_temp = 0):
3446 self.rhs.analyse_types(env)
3447 self.lhs.analyse_target_types(env)
3448 self.lhs.gil_assignment_check(env)
3449 self.rhs = self.rhs.coerce_to(self.lhs.type, env)
3451 self.rhs = self.rhs.coerce_to_temp(env)
3453 def generate_rhs_evaluation_code(self, code):
3454 self.rhs.generate_evaluation_code(code)
3456 def generate_assignment_code(self, code):
3457 self.lhs.generate_assignment_code(self.rhs, code)
3459 def generate_function_definitions(self, env, code):
3460 self.rhs.generate_function_definitions(env, code)
3462 def annotate(self, code):
3463 self.lhs.annotate(code)
3464 self.rhs.annotate(code)
3467 class CascadedAssignmentNode(AssignmentNode):
3468 # An assignment with multiple left hand sides:
3472 # lhs_list [ExprNode] Left hand sides
3473 # rhs ExprNode Right hand sides
3477 # coerced_rhs_list [ExprNode] RHS coerced to type of each LHS
3479 child_attrs = ["lhs_list", "rhs", "coerced_rhs_list"]
3480 coerced_rhs_list = None
3482 def analyse_declarations(self, env):
3483 for lhs in self.lhs_list:
3484 lhs.analyse_target_declaration(env)
3486 def analyse_types(self, env, use_temp = 0):
3487 self.rhs.analyse_types(env)
3488 if not self.rhs.is_simple():
3490 self.rhs = self.rhs.coerce_to_temp(env)
3492 self.rhs = self.rhs.coerce_to_simple(env)
3493 from ExprNodes import CloneNode
3494 self.coerced_rhs_list = []
3495 for lhs in self.lhs_list:
3496 lhs.analyse_target_types(env)
3497 lhs.gil_assignment_check(env)
3498 rhs = CloneNode(self.rhs)
3499 rhs = rhs.coerce_to(lhs.type, env)
3500 self.coerced_rhs_list.append(rhs)
3502 def generate_rhs_evaluation_code(self, code):
3503 self.rhs.generate_evaluation_code(code)
3505 def generate_assignment_code(self, code):
3506 for i in range(len(self.lhs_list)):
3507 lhs = self.lhs_list[i]
3508 rhs = self.coerced_rhs_list[i]
3509 rhs.generate_evaluation_code(code)
3510 lhs.generate_assignment_code(rhs, code)
3511 # Assignment has disposed of the cloned RHS
3512 self.rhs.generate_disposal_code(code)
3513 self.rhs.free_temps(code)
3515 def generate_function_definitions(self, env, code):
3516 self.rhs.generate_function_definitions(env, code)
3518 def annotate(self, code):
3519 for i in range(len(self.lhs_list)):
3520 lhs = self.lhs_list[i].annotate(code)
3521 rhs = self.coerced_rhs_list[i].annotate(code)
3522 self.rhs.annotate(code)
3525 class ParallelAssignmentNode(AssignmentNode):
3526 # A combined packing/unpacking assignment:
3530 # This has been rearranged by the parser into
3532 # a = d ; b = e ; c = f
3534 # but we must evaluate all the right hand sides
3535 # before assigning to any of the left hand sides.
3537 # stats [AssignmentNode] The constituent assignments
3539 child_attrs = ["stats"]
3541 def analyse_declarations(self, env):
3542 for stat in self.stats:
3543 stat.analyse_declarations(env)
3545 def analyse_expressions(self, env):
3546 for stat in self.stats:
3547 stat.analyse_types(env, use_temp = 1)
3549 # def analyse_expressions(self, env):
3550 # for stat in self.stats:
3551 # stat.analyse_expressions_1(env, use_temp = 1)
3552 # for stat in self.stats:
3553 # stat.analyse_expressions_2(env)
3555 def generate_execution_code(self, code):
3556 for stat in self.stats:
3557 stat.generate_rhs_evaluation_code(code)
3558 for stat in self.stats:
3559 stat.generate_assignment_code(code)
3561 def generate_function_definitions(self, env, code):
3562 for stat in self.stats:
3563 stat.generate_function_definitions(env, code)
3565 def annotate(self, code):
3566 for stat in self.stats:
3570 class InPlaceAssignmentNode(AssignmentNode):
3571 # An in place arithmetic operand:
3577 # lhs ExprNode Left hand side
3578 # rhs ExprNode Right hand side
3579 # op char one of "+-*/%^&|"
3580 # dup (ExprNode) copy of lhs used for operation (auto-generated)
3582 # This code is a bit tricky because in order to obey Python
3583 # semantics the sub-expressions (e.g. indices) of the lhs must
3584 # not be evaluated twice. So we must re-use the values calculated
3585 # in evaluation phase for the assignment phase as well.
3586 # Fortunately, the type of the lhs node is fairly constrained
3587 # (it must be a NameNode, AttributeNode, or IndexNode).
3589 child_attrs = ["lhs", "rhs"]
3591 def analyse_declarations(self, env):
3592 self.lhs.analyse_target_declaration(env)
3594 def analyse_types(self, env):
3595 self.rhs.analyse_types(env)
3596 self.lhs.analyse_target_types(env)
3598 def generate_execution_code(self, code):
3600 self.rhs.generate_evaluation_code(code)
3601 self.lhs.generate_subexpr_evaluation_code(code)
3602 c_op = self.operator
3606 error(self.pos, "No C inplace power operator")
3607 if isinstance(self.lhs, ExprNodes.IndexNode) and self.lhs.is_buffer_access:
3608 if self.lhs.type.is_pyobject:
3609 error(self.pos, "In-place operators not allowed on object buffers in this release.")
3610 if c_op in ('/', '%') and self.lhs.type.is_int and not code.directives['cdivision']:
3611 error(self.pos, "In-place non-c divide operators not allowed on int buffers.")
3612 self.lhs.generate_buffer_setitem_code(self.rhs, code, c_op)
3615 # TODO: make sure overload is declared
3616 code.putln("%s %s= %s;" % (self.lhs.result(), c_op, self.rhs.result()))
3617 self.lhs.generate_subexpr_disposal_code(code)
3618 self.lhs.free_subexpr_temps(code)
3619 self.rhs.generate_disposal_code(code)
3620 self.rhs.free_temps(code)
3622 def annotate(self, code):
3623 self.lhs.annotate(code)
3624 self.rhs.annotate(code)
3626 def create_binop_node(self):
3628 return ExprNodes.binop_node(self.pos, self.operator, self.lhs, self.rhs)
3631 class PrintStatNode(StatNode):
3634 # arg_tuple TupleNode
3635 # stream ExprNode or None (stdout)
3636 # append_newline boolean
3638 child_attrs = ["arg_tuple", "stream"]
3640 def analyse_expressions(self, env):
3642 self.stream.analyse_expressions(env)
3643 self.stream = self.stream.coerce_to_pyobject(env)
3644 self.arg_tuple.analyse_expressions(env)
3645 self.arg_tuple = self.arg_tuple.coerce_to_pyobject(env)
3646 env.use_utility_code(printing_utility_code)
3647 if len(self.arg_tuple.args) == 1 and self.append_newline:
3648 env.use_utility_code(printing_one_utility_code)
3650 nogil_check = Node.gil_error
3651 gil_message = "Python print statement"
3653 def generate_execution_code(self, code):
3655 self.stream.generate_evaluation_code(code)
3656 stream_result = self.stream.py_result()
3659 if len(self.arg_tuple.args) == 1 and self.append_newline:
3660 arg = self.arg_tuple.args[0]
3661 arg.generate_evaluation_code(code)
3664 "if (__Pyx_PrintOne(%s, %s) < 0) %s" % (
3667 code.error_goto(self.pos)))
3668 arg.generate_disposal_code(code)
3669 arg.free_temps(code)
3671 self.arg_tuple.generate_evaluation_code(code)
3673 "if (__Pyx_Print(%s, %s, %d) < 0) %s" % (
3675 self.arg_tuple.py_result(),
3676 self.append_newline,
3677 code.error_goto(self.pos)))
3678 self.arg_tuple.generate_disposal_code(code)
3679 self.arg_tuple.free_temps(code)
3682 self.stream.generate_disposal_code(code)
3683 self.stream.free_temps(code)
3685 def generate_function_definitions(self, env, code):
3687 self.stream.generate_function_definitions(env, code)
3688 self.arg_tuple.generate_function_definitions(env, code)
3690 def annotate(self, code):
3692 self.stream.annotate(code)
3693 self.arg_tuple.annotate(code)
3696 class ExecStatNode(StatNode):
3701 child_attrs = ["args"]
3703 def analyse_expressions(self, env):
3704 for i, arg in enumerate(self.args):
3705 arg.analyse_expressions(env)
3706 arg = arg.coerce_to_pyobject(env)
3708 env.use_utility_code(Builtin.pyexec_utility_code)
3710 nogil_check = Node.gil_error
3711 gil_message = "Python exec statement"
3713 def generate_execution_code(self, code):
3715 for arg in self.args:
3716 arg.generate_evaluation_code(code)
3717 args.append( arg.py_result() )
3718 args = tuple(args + ['0', '0'][:3-len(args)])
3719 temp_result = code.funcstate.allocate_temp(PyrexTypes.py_object_type, manage_ref=True)
3720 code.putln("%s = __Pyx_PyRun(%s, %s, %s);" % (
3721 (temp_result,) + args))
3722 for arg in self.args:
3723 arg.generate_disposal_code(code)
3724 arg.free_temps(code)
3726 code.error_goto_if_null(temp_result, self.pos))
3727 code.put_gotref(temp_result)
3728 code.put_decref_clear(temp_result, py_object_type)
3729 code.funcstate.release_temp(temp_result)
3731 def annotate(self, code):
3732 for arg in self.args:
3736 class DelStatNode(StatNode):
3741 child_attrs = ["args"]
3743 def analyse_declarations(self, env):
3744 for arg in self.args:
3745 arg.analyse_target_declaration(env)
3747 def analyse_expressions(self, env):
3748 for arg in self.args:
3749 arg.analyse_target_expression(env, None)
3750 if arg.type.is_pyobject:
3752 elif arg.type.is_ptr and arg.type.base_type.is_cpp_class:
3754 elif arg.type.is_cpp_class:
3755 error(arg.pos, "Deletion of non-heap C++ object")
3757 error(arg.pos, "Deletion of non-Python, non-C++ object")
3758 #arg.release_target_temp(env)
3760 def nogil_check(self, env):
3761 for arg in self.args:
3762 if arg.type.is_pyobject:
3765 gil_message = "Deleting Python object"
3767 def generate_execution_code(self, code):
3768 for arg in self.args:
3769 if arg.type.is_pyobject:
3770 arg.generate_deletion_code(code)
3771 elif arg.type.is_ptr and arg.type.base_type.is_cpp_class:
3772 arg.generate_result_code(code)
3773 code.putln("delete %s;" % arg.result())
3774 # else error reported earlier
3776 def annotate(self, code):
3777 for arg in self.args:
3781 class PassStatNode(StatNode):
3786 def analyse_expressions(self, env):
3789 def generate_execution_code(self, code):
3793 class BreakStatNode(StatNode):
3797 def analyse_expressions(self, env):
3800 def generate_execution_code(self, code):
3801 if not code.break_label:
3802 error(self.pos, "break statement not inside loop")
3804 code.put_goto(code.break_label)
3807 class ContinueStatNode(StatNode):
3811 def analyse_expressions(self, env):
3814 def generate_execution_code(self, code):
3815 if code.funcstate.in_try_finally:
3816 error(self.pos, "continue statement inside try of try...finally")
3817 elif not code.continue_label:
3818 error(self.pos, "continue statement not inside loop")
3820 code.put_goto(code.continue_label)
3823 class ReturnStatNode(StatNode):
3826 # value ExprNode or None
3827 # return_type PyrexType
3829 child_attrs = ["value"]
3831 def analyse_expressions(self, env):
3832 return_type = env.return_type
3833 self.return_type = return_type
3835 error(self.pos, "Return not inside a function body")
3838 self.value.analyse_types(env)
3839 if return_type.is_void or return_type.is_returncode:
3840 error(self.value.pos,
3841 "Return with value in void function")
3843 self.value = self.value.coerce_to(env.return_type, env)
3845 if (not return_type.is_void
3846 and not return_type.is_pyobject
3847 and not return_type.is_returncode):
3848 error(self.pos, "Return value required")
3850 def nogil_check(self, env):
3851 if self.return_type.is_pyobject:
3854 gil_message = "Returning Python object"
3856 def generate_execution_code(self, code):
3857 code.mark_pos(self.pos)
3858 if not self.return_type:
3859 # error reported earlier
3861 if self.return_type.is_pyobject:
3862 code.put_xdecref(Naming.retval_cname,
3865 self.value.generate_evaluation_code(code)
3866 self.value.make_owned_reference(code)
3869 Naming.retval_cname,
3870 self.value.result_as(self.return_type)))
3871 self.value.generate_post_assignment_code(code)
3872 self.value.free_temps(code)
3874 if self.return_type.is_pyobject:
3875 code.put_init_to_py_none(Naming.retval_cname, self.return_type)
3876 elif self.return_type.is_returncode:
3879 Naming.retval_cname,
3880 self.return_type.default_value))
3881 for cname, type in code.funcstate.temps_holding_reference():
3882 code.put_decref_clear(cname, type)
3883 code.put_goto(code.return_label)
3885 def generate_function_definitions(self, env, code):
3886 if self.value is not None:
3887 self.value.generate_function_definitions(env, code)
3889 def annotate(self, code):
3891 self.value.annotate(code)
3894 class RaiseStatNode(StatNode):
3897 # exc_type ExprNode or None
3898 # exc_value ExprNode or None
3899 # exc_tb ExprNode or None
3901 child_attrs = ["exc_type", "exc_value", "exc_tb"]
3903 def analyse_expressions(self, env):
3905 self.exc_type.analyse_types(env)
3906 self.exc_type = self.exc_type.coerce_to_pyobject(env)
3908 self.exc_value.analyse_types(env)
3909 self.exc_value = self.exc_value.coerce_to_pyobject(env)
3911 self.exc_tb.analyse_types(env)
3912 self.exc_tb = self.exc_tb.coerce_to_pyobject(env)
3913 env.use_utility_code(raise_utility_code)
3915 nogil_check = Node.gil_error
3916 gil_message = "Raising exception"
3918 def generate_execution_code(self, code):
3920 self.exc_type.generate_evaluation_code(code)
3921 type_code = self.exc_type.py_result()
3925 self.exc_value.generate_evaluation_code(code)
3926 value_code = self.exc_value.py_result()
3930 self.exc_tb.generate_evaluation_code(code)
3931 tb_code = self.exc_tb.py_result()
3935 "__Pyx_Raise(%s, %s, %s);" % (
3939 for obj in (self.exc_type, self.exc_value, self.exc_tb):
3941 obj.generate_disposal_code(code)
3942 obj.free_temps(code)
3944 code.error_goto(self.pos))
3946 def generate_function_definitions(self, env, code):
3947 if self.exc_type is not None:
3948 self.exc_type.generate_function_definitions(env, code)
3949 if self.exc_value is not None:
3950 self.exc_value.generate_function_definitions(env, code)
3951 if self.exc_tb is not None:
3952 self.exc_tb.generate_function_definitions(env, code)
3954 def annotate(self, code):
3956 self.exc_type.annotate(code)
3958 self.exc_value.annotate(code)
3960 self.exc_tb.annotate(code)
3963 class ReraiseStatNode(StatNode):
3967 def analyse_expressions(self, env):
3968 env.use_utility_code(restore_exception_utility_code)
3970 nogil_check = Node.gil_error
3971 gil_message = "Raising exception"
3973 def generate_execution_code(self, code):
3974 vars = code.funcstate.exc_vars
3976 for varname in vars:
3977 code.put_giveref(varname)
3978 code.putln("__Pyx_ErrRestore(%s, %s, %s);" % tuple(vars))
3979 for varname in vars:
3980 code.put("%s = 0; " % varname)
3982 code.putln(code.error_goto(self.pos))
3984 error(self.pos, "Reraise not inside except clause")
3987 class AssertStatNode(StatNode):
3991 # value ExprNode or None
3993 child_attrs = ["cond", "value"]
3995 def analyse_expressions(self, env):
3996 self.cond = self.cond.analyse_boolean_expression(env)
3998 self.value.analyse_types(env)
3999 self.value = self.value.coerce_to_pyobject(env)
4001 nogil_check = Node.gil_error
4002 gil_message = "Raising exception"
4004 def generate_execution_code(self, code):
4005 code.putln("#ifndef CYTHON_WITHOUT_ASSERTIONS")
4006 self.cond.generate_evaluation_code(code)
4008 "if (unlikely(!%s)) {" %
4011 self.value.generate_evaluation_code(code)
4013 "PyErr_SetObject(PyExc_AssertionError, %s);" %
4014 self.value.py_result())
4015 self.value.generate_disposal_code(code)
4016 self.value.free_temps(code)
4019 "PyErr_SetNone(PyExc_AssertionError);")
4021 code.error_goto(self.pos))
4024 self.cond.generate_disposal_code(code)
4025 self.cond.free_temps(code)
4026 code.putln("#endif")
4028 def generate_function_definitions(self, env, code):
4029 self.cond.generate_function_definitions(env, code)
4030 if self.value is not None:
4031 self.value.generate_function_definitions(env, code)
4033 def annotate(self, code):
4034 self.cond.annotate(code)
4036 self.value.annotate(code)
4039 class IfStatNode(StatNode):
4042 # if_clauses [IfClauseNode]
4043 # else_clause StatNode or None
4045 child_attrs = ["if_clauses", "else_clause"]
4047 def analyse_control_flow(self, env):
4048 env.start_branching(self.pos)
4049 for if_clause in self.if_clauses:
4050 if_clause.analyse_control_flow(env)
4051 env.next_branch(if_clause.end_pos())
4052 if self.else_clause:
4053 self.else_clause.analyse_control_flow(env)
4054 env.finish_branching(self.end_pos())
4056 def analyse_declarations(self, env):
4057 for if_clause in self.if_clauses:
4058 if_clause.analyse_declarations(env)
4059 if self.else_clause:
4060 self.else_clause.analyse_declarations(env)
4062 def analyse_expressions(self, env):
4063 for if_clause in self.if_clauses:
4064 if_clause.analyse_expressions(env)
4065 if self.else_clause:
4066 self.else_clause.analyse_expressions(env)
4068 def generate_execution_code(self, code):
4069 code.mark_pos(self.pos)
4070 end_label = code.new_label()
4071 for if_clause in self.if_clauses:
4072 if_clause.generate_execution_code(code, end_label)
4073 if self.else_clause:
4074 code.putln("/*else*/ {")
4075 self.else_clause.generate_execution_code(code)
4077 code.put_label(end_label)
4079 def generate_function_definitions(self, env, code):
4080 for clause in self.if_clauses:
4081 clause.generate_function_definitions(env, code)
4082 if self.else_clause is not None:
4083 self.else_clause.generate_function_definitions(env, code)
4085 def annotate(self, code):
4086 for if_clause in self.if_clauses:
4087 if_clause.annotate(code)
4088 if self.else_clause:
4089 self.else_clause.annotate(code)
4092 class IfClauseNode(Node):
4093 # if or elif clause in an if statement
4095 # condition ExprNode
4098 child_attrs = ["condition", "body"]
4100 def analyse_control_flow(self, env):
4101 self.body.analyse_control_flow(env)
4103 def analyse_declarations(self, env):
4104 self.body.analyse_declarations(env)
4106 def analyse_expressions(self, env):
4108 self.condition.analyse_temp_boolean_expression(env)
4109 self.body.analyse_expressions(env)
4111 def get_constant_condition_result(self):
4112 if self.condition.has_constant_result():
4113 return bool(self.condition.constant_result)
4117 def generate_execution_code(self, code, end_label):
4118 self.condition.generate_evaluation_code(code)
4121 self.condition.result())
4122 self.condition.generate_disposal_code(code)
4123 self.condition.free_temps(code)
4124 self.body.generate_execution_code(code)
4125 code.put_goto(end_label)
4128 def generate_function_definitions(self, env, code):
4129 self.condition.generate_function_definitions(env, code)
4130 self.body.generate_function_definitions(env, code)
4132 def annotate(self, code):
4133 self.condition.annotate(code)
4134 self.body.annotate(code)
4137 class SwitchCaseNode(StatNode):
4138 # Generated in the optimization of an if-elif-else node
4140 # conditions [ExprNode]
4143 child_attrs = ['conditions', 'body']
4145 def generate_execution_code(self, code):
4146 for cond in self.conditions:
4147 code.mark_pos(cond.pos)
4148 cond.generate_evaluation_code(code)
4149 code.putln("case %s:" % cond.result())
4150 self.body.generate_execution_code(code)
4151 code.putln("break;")
4153 def generate_function_definitions(self, env, code):
4154 for cond in self.conditions:
4155 cond.generate_function_definitions(env, code)
4156 self.body.generate_function_definitions(env, code)
4158 def annotate(self, code):
4159 for cond in self.conditions:
4161 self.body.annotate(code)
4163 class SwitchStatNode(StatNode):
4164 # Generated in the optimization of an if-elif-else node
4167 # cases [SwitchCaseNode]
4168 # else_clause StatNode or None
4170 child_attrs = ['test', 'cases', 'else_clause']
4172 def generate_execution_code(self, code):
4173 self.test.generate_evaluation_code(code)
4174 code.putln("switch (%s) {" % self.test.result())
4175 for case in self.cases:
4176 case.generate_execution_code(code)
4177 if self.else_clause is not None:
4178 code.putln("default:")
4179 self.else_clause.generate_execution_code(code)
4180 code.putln("break;")
4183 def generate_function_definitions(self, env, code):
4184 self.test.generate_function_definitions(env, code)
4185 for case in self.cases:
4186 case.generate_function_definitions(env, code)
4187 if self.else_clause is not None:
4188 self.else_clause.generate_function_definitions(env, code)
4190 def annotate(self, code):
4191 self.test.annotate(code)
4192 for case in self.cases:
4194 if self.else_clause is not None:
4195 self.else_clause.annotate(code)
4197 class LoopNode(object):
4199 def analyse_control_flow(self, env):
4200 env.start_branching(self.pos)
4201 self.body.analyse_control_flow(env)
4202 env.next_branch(self.body.end_pos())
4203 if self.else_clause:
4204 self.else_clause.analyse_control_flow(env)
4205 env.finish_branching(self.end_pos())
4208 class WhileStatNode(LoopNode, StatNode):
4211 # condition ExprNode
4213 # else_clause StatNode
4215 child_attrs = ["condition", "body", "else_clause"]
4217 def analyse_declarations(self, env):
4218 self.body.analyse_declarations(env)
4219 if self.else_clause:
4220 self.else_clause.analyse_declarations(env)
4222 def analyse_expressions(self, env):
4224 self.condition.analyse_temp_boolean_expression(env)
4225 self.body.analyse_expressions(env)
4226 if self.else_clause:
4227 self.else_clause.analyse_expressions(env)
4229 def generate_execution_code(self, code):
4230 old_loop_labels = code.new_loop_labels()
4233 self.condition.generate_evaluation_code(code)
4234 self.condition.generate_disposal_code(code)
4237 self.condition.result())
4238 self.condition.free_temps(code)
4239 self.body.generate_execution_code(code)
4240 code.put_label(code.continue_label)
4242 break_label = code.break_label
4243 code.set_loop_labels(old_loop_labels)
4244 if self.else_clause:
4245 code.putln("/*else*/ {")
4246 self.else_clause.generate_execution_code(code)
4248 code.put_label(break_label)
4250 def generate_function_definitions(self, env, code):
4251 self.condition.generate_function_definitions(env, code)
4252 self.body.generate_function_definitions(env, code)
4253 if self.else_clause is not None:
4254 self.else_clause.generate_function_definitions(env, code)
4256 def annotate(self, code):
4257 self.condition.annotate(code)
4258 self.body.annotate(code)
4259 if self.else_clause:
4260 self.else_clause.annotate(code)
4263 def ForStatNode(pos, **kw):
4264 if 'iterator' in kw:
4265 return ForInStatNode(pos, **kw)
4267 return ForFromStatNode(pos, **kw)
4269 class ForInStatNode(LoopNode, StatNode):
4273 # iterator IteratorNode
4275 # else_clause StatNode
4276 # item NextNode used internally
4278 child_attrs = ["target", "iterator", "body", "else_clause"]
4281 def analyse_declarations(self, env):
4282 self.target.analyse_target_declaration(env)
4283 self.body.analyse_declarations(env)
4284 if self.else_clause:
4285 self.else_clause.analyse_declarations(env)
4287 def analyse_expressions(self, env):
4289 self.target.analyse_target_types(env)
4290 self.iterator.analyse_expressions(env)
4291 self.item = ExprNodes.NextNode(self.iterator, env)
4292 self.item = self.item.coerce_to(self.target.type, env)
4293 self.body.analyse_expressions(env)
4294 if self.else_clause:
4295 self.else_clause.analyse_expressions(env)
4297 def generate_execution_code(self, code):
4298 old_loop_labels = code.new_loop_labels()
4299 self.iterator.allocate_counter_temp(code)
4300 self.iterator.generate_evaluation_code(code)
4303 self.item.generate_evaluation_code(code)
4304 self.target.generate_assignment_code(self.item, code)
4305 self.body.generate_execution_code(code)
4306 code.put_label(code.continue_label)
4309 break_label = code.break_label
4310 code.set_loop_labels(old_loop_labels)
4312 if self.else_clause:
4313 # in nested loops, the 'else' block can contain a
4314 # 'continue' statement for the outer loop, but we may need
4315 # to generate cleanup code before taking that path, so we
4317 orig_continue_label = code.continue_label
4318 code.continue_label = code.new_label('outer_continue')
4320 code.putln("/*else*/ {")
4321 self.else_clause.generate_execution_code(code)
4324 if code.label_used(code.continue_label):
4325 code.put_goto(break_label)
4326 code.put_label(code.continue_label)
4327 self.iterator.generate_disposal_code(code)
4328 code.put_goto(orig_continue_label)
4329 code.set_loop_labels(old_loop_labels)
4331 if code.label_used(break_label):
4332 code.put_label(break_label)
4333 self.iterator.release_counter_temp(code)
4334 self.iterator.generate_disposal_code(code)
4335 self.iterator.free_temps(code)
4337 def generate_function_definitions(self, env, code):
4338 self.target.generate_function_definitions(env, code)
4339 self.iterator.generate_function_definitions(env, code)
4340 self.body.generate_function_definitions(env, code)
4341 if self.else_clause is not None:
4342 self.else_clause.generate_function_definitions(env, code)
4344 def annotate(self, code):
4345 self.target.annotate(code)
4346 self.iterator.annotate(code)
4347 self.body.annotate(code)
4348 if self.else_clause:
4349 self.else_clause.annotate(code)
4350 self.item.annotate(code)
4353 class ForFromStatNode(LoopNode, StatNode):
4354 # for name from expr rel name rel expr
4361 # step ExprNode or None
4363 # else_clause StatNode or None
4369 # loopvar_node ExprNode (usually a NameNode or temp node)
4370 # py_loopvar_node PyTempNode or None
4371 child_attrs = ["target", "bound1", "bound2", "step", "body", "else_clause"]
4373 is_py_target = False
4375 py_loopvar_node = None
4378 gil_message = "For-loop using object bounds or target"
4380 def nogil_check(self, env):
4381 for x in (self.target, self.bound1, self.bound2):
4382 if x.type.is_pyobject:
4385 def analyse_declarations(self, env):
4386 self.target.analyse_target_declaration(env)
4387 self.body.analyse_declarations(env)
4388 if self.else_clause:
4389 self.else_clause.analyse_declarations(env)
4391 def analyse_expressions(self, env):
4393 self.target.analyse_target_types(env)
4394 self.bound1.analyse_types(env)
4395 self.bound2.analyse_types(env)
4396 if self.step is not None:
4397 if isinstance(self.step, ExprNodes.UnaryMinusNode):
4398 warning(self.step.pos, "Probable infinite loop in for-from-by statment. Consider switching the directions of the relations.", 2)
4399 self.step.analyse_types(env)
4401 target_type = self.target.type
4402 if self.target.type.is_numeric:
4403 loop_type = self.target.type
4405 loop_type = PyrexTypes.c_int_type
4406 if not self.bound1.type.is_pyobject:
4407 loop_type = PyrexTypes.widest_numeric_type(loop_type, self.bound1.type)
4408 if not self.bound2.type.is_pyobject:
4409 loop_type = PyrexTypes.widest_numeric_type(loop_type, self.bound2.type)
4410 if self.step is not None and not self.step.type.is_pyobject:
4411 loop_type = PyrexTypes.widest_numeric_type(loop_type, self.step.type)
4412 self.bound1 = self.bound1.coerce_to(loop_type, env)
4413 self.bound2 = self.bound2.coerce_to(loop_type, env)
4414 if not self.bound2.is_literal:
4415 self.bound2 = self.bound2.coerce_to_temp(env)
4416 if self.step is not None:
4417 self.step = self.step.coerce_to(loop_type, env)
4418 if not self.step.is_literal:
4419 self.step = self.step.coerce_to_temp(env)
4421 target_type = self.target.type
4422 if not (target_type.is_pyobject or target_type.is_numeric):
4423 error(self.target.pos,
4424 "for-from loop variable must be c numeric type or Python object")
4425 if target_type.is_numeric:
4426 self.is_py_target = False
4427 if isinstance(self.target, ExprNodes.IndexNode) and self.target.is_buffer_access:
4428 raise error(self.pos, "Buffer indexing not allowed as for loop target.")
4429 self.loopvar_node = self.target
4430 self.py_loopvar_node = None
4432 self.is_py_target = True
4433 c_loopvar_node = ExprNodes.TempNode(self.pos, loop_type, env)
4434 self.loopvar_node = c_loopvar_node
4435 self.py_loopvar_node = \
4436 ExprNodes.CloneNode(c_loopvar_node).coerce_to_pyobject(env)
4437 self.body.analyse_expressions(env)
4438 if self.else_clause:
4439 self.else_clause.analyse_expressions(env)
4441 def generate_execution_code(self, code):
4442 old_loop_labels = code.new_loop_labels()
4443 from_range = self.from_range
4444 self.bound1.generate_evaluation_code(code)
4445 self.bound2.generate_evaluation_code(code)
4446 offset, incop = self.relation_table[self.relation1]
4447 if self.step is not None:
4448 self.step.generate_evaluation_code(code)
4449 step = self.step.result()
4450 incop = "%s=%s" % (incop[0], step)
4452 if isinstance(self.loopvar_node, ExprNodes.TempNode):
4453 self.loopvar_node.allocate(code)
4454 if isinstance(self.py_loopvar_node, ExprNodes.TempNode):
4455 self.py_loopvar_node.allocate(code)
4457 loopvar_name = code.funcstate.allocate_temp(self.target.type, False)
4459 loopvar_name = self.loopvar_node.result()
4461 "for (%s = %s%s; %s %s %s; %s%s) {" % (
4463 self.bound1.result(), offset,
4464 loopvar_name, self.relation2, self.bound2.result(),
4465 loopvar_name, incop))
4466 if self.py_loopvar_node:
4467 self.py_loopvar_node.generate_evaluation_code(code)
4468 self.target.generate_assignment_code(self.py_loopvar_node, code)
4470 code.putln("%s = %s;" % (
4471 self.target.result(), loopvar_name))
4472 self.body.generate_execution_code(code)
4473 code.put_label(code.continue_label)
4474 if self.py_loopvar_node:
4475 # This mess is to make for..from loops with python targets behave
4476 # exactly like those with C targets with regards to re-assignment
4477 # of the loop variable.
4479 if self.target.entry.is_pyglobal:
4480 # We know target is a NameNode, this is the only ugly case.
4481 target_node = ExprNodes.PyTempNode(self.target.pos, None)
4482 target_node.allocate(code)
4483 interned_cname = code.intern_identifier(self.target.entry.name)
4484 code.globalstate.use_utility_code(ExprNodes.get_name_interned_utility_code)
4485 code.putln("%s = __Pyx_GetName(%s, %s); %s" % (
4486 target_node.result(),
4487 Naming.module_cname,
4489 code.error_goto_if_null(target_node.result(), self.target.pos)))
4490 code.put_gotref(target_node.result())
4492 target_node = self.target
4493 from_py_node = ExprNodes.CoerceFromPyTypeNode(self.loopvar_node.type, target_node, None)
4494 from_py_node.temp_code = loopvar_name
4495 from_py_node.generate_result_code(code)
4496 if self.target.entry.is_pyglobal:
4497 code.put_decref(target_node.result(), target_node.type)
4498 target_node.release(code)
4500 if self.py_loopvar_node:
4501 # This is potentially wasteful, but we don't want the semantics to
4502 # depend on whether or not the loop is a python type.
4503 self.py_loopvar_node.generate_evaluation_code(code)
4504 self.target.generate_assignment_code(self.py_loopvar_node, code)
4506 code.funcstate.release_temp(loopvar_name)
4507 break_label = code.break_label
4508 code.set_loop_labels(old_loop_labels)
4509 if self.else_clause:
4510 code.putln("/*else*/ {")
4511 self.else_clause.generate_execution_code(code)
4513 code.put_label(break_label)
4514 self.bound1.generate_disposal_code(code)
4515 self.bound1.free_temps(code)
4516 self.bound2.generate_disposal_code(code)
4517 self.bound2.free_temps(code)
4518 if isinstance(self.loopvar_node, ExprNodes.TempNode):
4519 self.loopvar_node.release(code)
4520 if isinstance(self.py_loopvar_node, ExprNodes.TempNode):
4521 self.py_loopvar_node.release(code)
4522 if self.step is not None:
4523 self.step.generate_disposal_code(code)
4524 self.step.free_temps(code)
4527 # {relop : (initial offset, increment op)}
4534 def generate_function_definitions(self, env, code):
4535 self.target.generate_function_definitions(env, code)
4536 self.bound1.generate_function_definitions(env, code)
4537 self.bound2.generate_function_definitions(env, code)
4538 if self.step is not None:
4539 self.step.generate_function_definitions(env, code)
4540 self.body.generate_function_definitions(env, code)
4541 if self.else_clause is not None:
4542 self.else_clause.generate_function_definitions(env, code)
4544 def annotate(self, code):
4545 self.target.annotate(code)
4546 self.bound1.annotate(code)
4547 self.bound2.annotate(code)
4549 self.step.annotate(code)
4550 self.body.annotate(code)
4551 if self.else_clause:
4552 self.else_clause.annotate(code)
4555 class WithStatNode(StatNode):
4557 Represents a Python with statement.
4559 This is only used at parse tree level; and is not present in
4560 analysis or generation phases.
4562 # manager The with statement manager object
4563 # target Node (lhs expression)
4565 child_attrs = ["manager", "target", "body"]
4567 class TryExceptStatNode(StatNode):
4568 # try .. except statement
4571 # except_clauses [ExceptClauseNode]
4572 # else_clause StatNode or None
4574 child_attrs = ["body", "except_clauses", "else_clause"]
4576 def analyse_control_flow(self, env):
4577 env.start_branching(self.pos)
4578 self.body.analyse_control_flow(env)
4579 successful_try = env.control_flow # grab this for later
4580 env.next_branch(self.body.end_pos())
4581 env.finish_branching(self.body.end_pos())
4583 env.start_branching(self.except_clauses[0].pos)
4584 for except_clause in self.except_clauses:
4585 except_clause.analyse_control_flow(env)
4586 env.next_branch(except_clause.end_pos())
4588 # the else cause it executed only when the try clause finishes
4589 env.control_flow.incoming = successful_try
4590 if self.else_clause:
4591 self.else_clause.analyse_control_flow(env)
4592 env.finish_branching(self.end_pos())
4594 def analyse_declarations(self, env):
4595 self.body.analyse_declarations(env)
4596 for except_clause in self.except_clauses:
4597 except_clause.analyse_declarations(env)
4598 if self.else_clause:
4599 self.else_clause.analyse_declarations(env)
4600 env.use_utility_code(reset_exception_utility_code)
4602 def analyse_expressions(self, env):
4603 self.body.analyse_expressions(env)
4604 default_clause_seen = 0
4605 for except_clause in self.except_clauses:
4606 except_clause.analyse_expressions(env)
4607 if default_clause_seen:
4608 error(except_clause.pos, "default 'except:' must be last")
4609 if not except_clause.pattern:
4610 default_clause_seen = 1
4611 self.has_default_clause = default_clause_seen
4612 if self.else_clause:
4613 self.else_clause.analyse_expressions(env)
4615 nogil_check = Node.gil_error
4616 gil_message = "Try-except statement"
4618 def generate_execution_code(self, code):
4619 old_return_label = code.return_label
4620 old_break_label = code.break_label
4621 old_continue_label = code.continue_label
4622 old_error_label = code.new_error_label()
4623 our_error_label = code.error_label
4624 except_end_label = code.new_label('exception_handled')
4625 except_error_label = code.new_label('except_error')
4626 except_return_label = code.new_label('except_return')
4627 try_return_label = code.new_label('try_return')
4628 try_break_label = code.new_label('try_break')
4629 try_continue_label = code.new_label('try_continue')
4630 try_end_label = code.new_label('try_end')
4633 code.putln("PyObject %s;" %
4634 ', '.join(['*%s' % var for var in Naming.exc_save_vars]))
4635 code.putln("__Pyx_ExceptionSave(%s);" %
4636 ', '.join(['&%s' % var for var in Naming.exc_save_vars]))
4637 for var in Naming.exc_save_vars:
4638 code.put_xgotref(var)
4641 code.return_label = try_return_label
4642 code.break_label = try_break_label
4643 code.continue_label = try_continue_label
4644 self.body.generate_execution_code(code)
4647 temps_to_clean_up = code.funcstate.all_free_managed_temps()
4648 code.error_label = except_error_label
4649 code.return_label = except_return_label
4650 if self.else_clause:
4653 self.else_clause.generate_execution_code(code)
4656 for var in Naming.exc_save_vars:
4657 code.put_xdecref_clear(var, py_object_type)
4658 code.put_goto(try_end_label)
4659 if code.label_used(try_return_label):
4660 code.put_label(try_return_label)
4661 for var in Naming.exc_save_vars: code.put_xgiveref(var)
4662 code.putln("__Pyx_ExceptionReset(%s);" %
4663 ', '.join(Naming.exc_save_vars))
4664 code.put_goto(old_return_label)
4665 code.put_label(our_error_label)
4666 for temp_name, type in temps_to_clean_up:
4667 code.put_xdecref_clear(temp_name, type)
4668 for except_clause in self.except_clauses:
4669 except_clause.generate_handling_code(code, except_end_label)
4671 error_label_used = code.label_used(except_error_label)
4672 if error_label_used or not self.has_default_clause:
4673 if error_label_used:
4674 code.put_label(except_error_label)
4675 for var in Naming.exc_save_vars: code.put_xgiveref(var)
4676 code.putln("__Pyx_ExceptionReset(%s);" %
4677 ', '.join(Naming.exc_save_vars))
4678 code.put_goto(old_error_label)
4680 for exit_label, old_label in zip(
4681 [try_break_label, try_continue_label, except_return_label],
4682 [old_break_label, old_continue_label, old_return_label]):
4684 if code.label_used(exit_label):
4685 code.put_label(exit_label)
4686 for var in Naming.exc_save_vars: code.put_xgiveref(var)
4687 code.putln("__Pyx_ExceptionReset(%s);" %
4688 ', '.join(Naming.exc_save_vars))
4689 code.put_goto(old_label)
4691 if code.label_used(except_end_label):
4692 code.put_label(except_end_label)
4693 for var in Naming.exc_save_vars: code.put_xgiveref(var)
4694 code.putln("__Pyx_ExceptionReset(%s);" %
4695 ', '.join(Naming.exc_save_vars))
4696 code.put_label(try_end_label)
4699 code.return_label = old_return_label
4700 code.break_label = old_break_label
4701 code.continue_label = old_continue_label
4702 code.error_label = old_error_label
4704 def generate_function_definitions(self, env, code):
4705 self.body.generate_function_definitions(env, code)
4706 for except_clause in self.except_clauses:
4707 except_clause.generate_function_definitions(env, code)
4708 if self.else_clause is not None:
4709 self.else_clause.generate_function_definitions(env, code)
4711 def annotate(self, code):
4712 self.body.annotate(code)
4713 for except_node in self.except_clauses:
4714 except_node.annotate(code)
4715 if self.else_clause:
4716 self.else_clause.annotate(code)
4719 class ExceptClauseNode(Node):
4720 # Part of try ... except statement.
4722 # pattern [ExprNode]
4723 # target ExprNode or None
4725 # excinfo_target NameNode or None optional target for exception info
4726 # match_flag string result of exception match
4727 # exc_value ExcValueNode used internally
4728 # function_name string qualified name of enclosing function
4729 # exc_vars (string * 3) local exception variables
4731 # excinfo_target is never set by the parser, but can be set by a transform
4732 # in order to extract more extensive information about the exception as a
4733 # sys.exc_info()-style tuple into a target variable
4735 child_attrs = ["pattern", "target", "body", "exc_value", "excinfo_target"]
4738 excinfo_target = None
4740 def analyse_declarations(self, env):
4742 self.target.analyse_target_declaration(env)
4743 if self.excinfo_target is not None:
4744 self.excinfo_target.analyse_target_declaration(env)
4745 self.body.analyse_declarations(env)
4747 def analyse_expressions(self, env):
4749 genv = env.global_scope()
4750 self.function_name = env.qualified_name
4752 # normalise/unpack self.pattern into a list
4753 for i, pattern in enumerate(self.pattern):
4754 pattern.analyse_expressions(env)
4755 self.pattern[i] = pattern.coerce_to_pyobject(env)
4758 self.exc_value = ExprNodes.ExcValueNode(self.pos, env)
4759 self.target.analyse_target_expression(env, self.exc_value)
4760 if self.excinfo_target is not None:
4762 self.excinfo_tuple = ExprNodes.TupleNode(pos=self.pos, args=[
4763 ExprNodes.ExcValueNode(pos=self.pos, env=env) for x in range(3)])
4764 self.excinfo_tuple.analyse_expressions(env)
4765 self.excinfo_target.analyse_target_expression(env, self.excinfo_tuple)
4767 self.body.analyse_expressions(env)
4769 def generate_handling_code(self, code, end_label):
4770 code.mark_pos(self.pos)
4773 for pattern in self.pattern:
4774 pattern.generate_evaluation_code(code)
4775 exc_tests.append("PyErr_ExceptionMatches(%s)" % pattern.py_result())
4777 match_flag = code.funcstate.allocate_temp(PyrexTypes.c_int_type, False)
4779 "%s = %s;" % (match_flag, ' || '.join(exc_tests)))
4780 for pattern in self.pattern:
4781 pattern.generate_disposal_code(code)
4782 pattern.free_temps(code)
4786 code.funcstate.release_temp(match_flag)
4788 code.putln("/*except:*/ {")
4790 if not getattr(self.body, 'stats', True) and \
4791 self.excinfo_target is None and self.target is None:
4792 # most simple case: no exception variable, empty body (pass)
4793 # => reset the exception state, done
4794 code.putln("PyErr_Restore(0,0,0);")
4795 code.put_goto(end_label)
4799 exc_vars = [code.funcstate.allocate_temp(py_object_type,
4802 code.putln('__Pyx_AddTraceback("%s");' % self.function_name)
4803 # We always have to fetch the exception value even if
4804 # there is no target, because this also normalises the
4805 # exception and stores it in the thread state.
4806 code.globalstate.use_utility_code(get_exception_utility_code)
4807 exc_args = "&%s, &%s, &%s" % tuple(exc_vars)
4808 code.putln("if (__Pyx_GetException(%s) < 0) %s" % (exc_args,
4809 code.error_goto(self.pos)))
4813 self.exc_value.set_var(exc_vars[1])
4814 self.exc_value.generate_evaluation_code(code)
4815 self.target.generate_assignment_code(self.exc_value, code)
4816 if self.excinfo_target is not None:
4817 for tempvar, node in zip(exc_vars, self.excinfo_tuple.args):
4818 node.set_var(tempvar)
4819 self.excinfo_tuple.generate_evaluation_code(code)
4820 self.excinfo_target.generate_assignment_code(self.excinfo_tuple, code)
4822 old_break_label, old_continue_label = code.break_label, code.continue_label
4823 code.break_label = code.new_label('except_break')
4824 code.continue_label = code.new_label('except_continue')
4826 old_exc_vars = code.funcstate.exc_vars
4827 code.funcstate.exc_vars = exc_vars
4828 self.body.generate_execution_code(code)
4829 code.funcstate.exc_vars = old_exc_vars
4830 for var in exc_vars:
4831 code.putln("__Pyx_DECREF(%s); %s = 0;" % (var, var))
4832 code.put_goto(end_label)
4834 if code.label_used(code.break_label):
4835 code.put_label(code.break_label)
4836 for var in exc_vars:
4837 code.putln("__Pyx_DECREF(%s); %s = 0;" % (var, var))
4838 code.put_goto(old_break_label)
4839 code.break_label = old_break_label
4841 if code.label_used(code.continue_label):
4842 code.put_label(code.continue_label)
4843 for var in exc_vars:
4844 code.putln("__Pyx_DECREF(%s); %s = 0;" % (var, var))
4845 code.put_goto(old_continue_label)
4846 code.continue_label = old_continue_label
4848 for temp in exc_vars:
4849 code.funcstate.release_temp(temp)
4854 def generate_function_definitions(self, env, code):
4855 if self.target is not None:
4856 self.target.generate_function_definitions(env, code)
4857 self.body.generate_function_definitions(env, code)
4859 def annotate(self, code):
4861 for pattern in self.pattern:
4862 pattern.annotate(code)
4864 self.target.annotate(code)
4865 self.body.annotate(code)
4868 class TryFinallyStatNode(StatNode):
4869 # try ... finally statement
4872 # finally_clause StatNode
4874 # The plan is that we funnel all continue, break
4875 # return and error gotos into the beginning of the
4876 # finally block, setting a variable to remember which
4877 # one we're doing. At the end of the finally block, we
4878 # switch on the variable to figure out where to go.
4879 # In addition, if we're doing an error, we save the
4880 # exception on entry to the finally block and restore
4883 child_attrs = ["body", "finally_clause"]
4885 preserve_exception = 1
4887 disallow_continue_in_try_finally = 0
4888 # There doesn't seem to be any point in disallowing
4889 # continue in the try block, since we have no problem
4892 def create_analysed(pos, env, body, finally_clause):
4893 node = TryFinallyStatNode(pos, body=body, finally_clause=finally_clause)
4895 create_analysed = staticmethod(create_analysed)
4897 def analyse_control_flow(self, env):
4898 env.start_branching(self.pos)
4899 self.body.analyse_control_flow(env)
4900 env.next_branch(self.body.end_pos())
4901 env.finish_branching(self.body.end_pos())
4902 self.finally_clause.analyse_control_flow(env)
4904 def analyse_declarations(self, env):
4905 self.body.analyse_declarations(env)
4906 self.finally_clause.analyse_declarations(env)
4908 def analyse_expressions(self, env):
4909 self.body.analyse_expressions(env)
4910 self.finally_clause.analyse_expressions(env)
4912 nogil_check = Node.gil_error
4913 gil_message = "Try-finally statement"
4915 def generate_execution_code(self, code):
4916 old_error_label = code.error_label
4917 old_labels = code.all_new_labels()
4918 new_labels = code.get_all_labels()
4919 new_error_label = code.error_label
4920 catch_label = code.new_label()
4923 if self.disallow_continue_in_try_finally:
4924 was_in_try_finally = code.funcstate.in_try_finally
4925 code.funcstate.in_try_finally = 1
4926 self.body.generate_execution_code(code)
4927 if self.disallow_continue_in_try_finally:
4928 code.funcstate.in_try_finally = was_in_try_finally
4931 temps_to_clean_up = code.funcstate.all_free_managed_temps()
4932 code.mark_pos(self.finally_clause.pos)
4936 error_label_used = 0
4937 for i, new_label in enumerate(new_labels):
4938 if new_label in code.labels_used:
4939 cases_used.append(i)
4940 if new_label == new_error_label:
4941 error_label_used = 1
4942 error_label_case = i
4946 if error_label_used and self.preserve_exception:
4948 "PyObject *%s, *%s, *%s;" % Naming.exc_vars)
4950 "int %s;" % Naming.exc_lineno_name)
4951 exc_var_init_zero = ''.join(["%s = 0; " % var for var in Naming.exc_vars])
4952 exc_var_init_zero += '%s = 0;' % Naming.exc_lineno_name
4953 code.putln(exc_var_init_zero)
4955 exc_var_init_zero = None
4956 code.use_label(catch_label)
4958 "__pyx_why = 0; goto %s;" % catch_label)
4959 for i in cases_used:
4960 new_label = new_labels[i]
4961 #if new_label and new_label != "<try>":
4962 if new_label == new_error_label and self.preserve_exception:
4963 self.put_error_catcher(code,
4964 new_error_label, i+1, catch_label, temps_to_clean_up)
4966 code.put('%s: ' % new_label)
4967 if exc_var_init_zero:
4968 code.putln(exc_var_init_zero)
4969 code.putln("__pyx_why = %s; goto %s;" % (
4972 code.put_label(catch_label)
4973 code.set_all_labels(old_labels)
4974 if error_label_used:
4975 code.new_error_label()
4976 finally_error_label = code.error_label
4977 self.finally_clause.generate_execution_code(code)
4978 if error_label_used:
4979 if finally_error_label in code.labels_used and self.preserve_exception:
4980 over_label = code.new_label()
4981 code.put_goto(over_label);
4982 code.put_label(finally_error_label)
4983 code.putln("if (__pyx_why == %d) {" % (error_label_case + 1))
4984 for var in Naming.exc_vars:
4985 code.putln("Py_XDECREF(%s);" % var)
4987 code.put_goto(old_error_label)
4988 code.put_label(over_label)
4989 code.error_label = old_error_label
4992 "switch (__pyx_why) {")
4993 for i in cases_used:
4994 old_label = old_labels[i]
4995 if old_label == old_error_label and self.preserve_exception:
4996 self.put_error_uncatcher(code, i+1, old_error_label)
4998 code.use_label(old_label)
5000 "case %s: goto %s;" % (
5008 def generate_function_definitions(self, env, code):
5009 self.body.generate_function_definitions(env, code)
5010 self.finally_clause.generate_function_definitions(env, code)
5012 def put_error_catcher(self, code, error_label, i, catch_label, temps_to_clean_up):
5013 code.globalstate.use_utility_code(restore_exception_utility_code)
5020 for temp_name, type in temps_to_clean_up:
5021 code.put_xdecref_clear(temp_name, type)
5023 "__Pyx_ErrFetch(&%s, &%s, &%s);" %
5027 Naming.exc_lineno_name, Naming.lineno_cname))
5028 code.put_goto(catch_label)
5031 def put_error_uncatcher(self, code, i, error_label):
5032 code.globalstate.use_utility_code(restore_exception_utility_code)
5037 "__Pyx_ErrRestore(%s, %s, %s);" %
5041 Naming.lineno_cname, Naming.exc_lineno_name))
5042 for var in Naming.exc_vars:
5046 code.put_goto(error_label)
5050 def annotate(self, code):
5051 self.body.annotate(code)
5052 self.finally_clause.annotate(code)
5055 class GILStatNode(TryFinallyStatNode):
5056 # 'with gil' or 'with nogil' statement
5058 # state string 'gil' or 'nogil'
5062 preserve_exception = 0
5064 def __init__(self, pos, state, body):
5066 TryFinallyStatNode.__init__(self, pos,
5068 finally_clause = GILExitNode(pos, state = state))
5070 def analyse_expressions(self, env):
5071 env.use_utility_code(force_init_threads_utility_code)
5072 was_nogil = env.nogil
5074 TryFinallyStatNode.analyse_expressions(self, env)
5075 env.nogil = was_nogil
5079 def generate_execution_code(self, code):
5080 code.mark_pos(self.pos)
5082 if self.state == 'gil':
5083 code.putln("#ifdef WITH_THREAD")
5084 code.putln("PyGILState_STATE _save = PyGILState_Ensure();")
5085 code.putln("#endif")
5087 code.putln("#ifdef WITH_THREAD")
5088 code.putln("PyThreadState *_save;")
5089 code.putln("#endif")
5090 code.putln("Py_UNBLOCK_THREADS")
5091 TryFinallyStatNode.generate_execution_code(self, code)
5095 class GILExitNode(StatNode):
5096 # Used as the 'finally' block in a GILStatNode
5098 # state string 'gil' or 'nogil'
5102 def analyse_expressions(self, env):
5105 def generate_execution_code(self, code):
5106 if self.state == 'gil':
5107 code.putln("#ifdef WITH_THREAD")
5108 code.putln("PyGILState_Release(_save);")
5109 code.putln("#endif")
5111 code.putln("Py_BLOCK_THREADS")
5114 class CImportStatNode(StatNode):
5117 # module_name string Qualified name of module being imported
5118 # as_name string or None Name specified in "as" clause, if any
5122 def analyse_declarations(self, env):
5123 if not env.is_module_scope:
5124 error(self.pos, "cimport only allowed at module level")
5126 module_scope = env.find_module(self.module_name, self.pos)
5127 if "." in self.module_name:
5128 names = [EncodedString(name) for name in self.module_name.split(".")]
5130 top_module_scope = env.context.find_submodule(top_name)
5131 module_scope = top_module_scope
5132 for name in names[1:]:
5133 submodule_scope = module_scope.find_submodule(name)
5134 module_scope.declare_module(name, submodule_scope, self.pos)
5135 module_scope = submodule_scope
5137 env.declare_module(self.as_name, module_scope, self.pos)
5139 env.declare_module(top_name, top_module_scope, self.pos)
5141 name = self.as_name or self.module_name
5142 env.declare_module(name, module_scope, self.pos)
5144 def analyse_expressions(self, env):
5147 def generate_execution_code(self, code):
5151 class FromCImportStatNode(StatNode):
5152 # from ... cimport statement
5154 # module_name string Qualified name of module
5155 # imported_names [(pos, name, as_name, kind)] Names to be imported
5159 def analyse_declarations(self, env):
5160 if not env.is_module_scope:
5161 error(self.pos, "cimport only allowed at module level")
5163 module_scope = env.find_module(self.module_name, self.pos)
5164 env.add_imported_module(module_scope)
5165 for pos, name, as_name, kind in self.imported_names:
5167 for local_name, entry in module_scope.entries.items():
5168 env.add_imported_entry(local_name, entry, pos)
5170 entry = module_scope.lookup(name)
5172 if kind and not self.declaration_matches(entry, kind):
5173 entry.redeclared(pos)
5175 if kind == 'struct' or kind == 'union':
5176 entry = module_scope.declare_struct_or_union(name,
5177 kind = kind, scope = None, typedef_flag = 0, pos = pos)
5178 elif kind == 'class':
5179 entry = module_scope.declare_c_class(name, pos = pos,
5180 module_name = self.module_name)
5182 submodule_scope = env.context.find_module(name, relative_to = module_scope, pos = self.pos)
5183 if submodule_scope.parent_module is module_scope:
5184 env.declare_module(as_name or name, submodule_scope, self.pos)
5186 error(pos, "Name '%s' not declared in module '%s'"
5187 % (name, self.module_name))
5190 local_name = as_name or name
5191 env.add_imported_entry(local_name, entry, pos)
5193 def declaration_matches(self, entry, kind):
5194 if not entry.is_type:
5198 if not type.is_extension_type:
5201 if not type.is_struct_or_union:
5203 if kind != type.kind:
5207 def analyse_expressions(self, env):
5210 def generate_execution_code(self, code):
5214 class FromImportStatNode(StatNode):
5215 # from ... import statement
5218 # items [(string, NameNode)]
5219 # interned_items [(string, NameNode, ExprNode)]
5220 # item PyTempNode used internally
5221 # import_star boolean used internally
5223 child_attrs = ["module"]
5226 def analyse_declarations(self, env):
5227 for name, target in self.items:
5229 if not env.is_module_scope:
5230 error(self.pos, "import * only allowed at module level")
5232 env.has_import_star = 1
5233 self.import_star = 1
5235 target.analyse_target_declaration(env)
5237 def analyse_expressions(self, env):
5239 self.module.analyse_expressions(env)
5240 self.item = ExprNodes.RawCNameExprNode(self.pos, py_object_type)
5241 self.interned_items = []
5242 for name, target in self.items:
5244 for _, entry in env.entries.items():
5245 if not entry.is_type and entry.type.is_extension_type:
5246 env.use_utility_code(ExprNodes.type_test_utility_code)
5249 entry = env.lookup(target.name)
5250 # check whether or not entry is already cimported
5251 if (entry.is_type and entry.type.name == name
5252 and hasattr(entry.type, 'module_name')):
5253 if entry.type.module_name == self.module.module_name.value:
5254 # cimported with absolute name
5257 # cimported with relative name
5258 module = env.find_module(self.module.module_name.value,
5260 if entry.type.module_name == module.qualified_name:
5262 except AttributeError:
5264 target.analyse_target_expression(env, None)
5265 if target.type is py_object_type:
5268 coerced_item = self.item.coerce_to(target.type, env)
5269 self.interned_items.append((name, target, coerced_item))
5271 def generate_execution_code(self, code):
5272 self.module.generate_evaluation_code(code)
5273 if self.import_star:
5275 'if (%s(%s) < 0) %s;' % (
5277 self.module.py_result(),
5278 code.error_goto(self.pos)))
5279 item_temp = code.funcstate.allocate_temp(py_object_type, manage_ref=True)
5280 self.item.set_cname(item_temp)
5281 for name, target, coerced_item in self.interned_items:
5282 cname = code.intern_identifier(name)
5284 '%s = PyObject_GetAttr(%s, %s); %s' % (
5286 self.module.py_result(),
5288 code.error_goto_if_null(item_temp, self.pos)))
5289 code.put_gotref(item_temp)
5290 if coerced_item is None:
5291 target.generate_assignment_code(self.item, code)
5293 coerced_item.allocate_temp_result(code)
5294 coerced_item.generate_result_code(code)
5295 target.generate_assignment_code(coerced_item, code)
5296 code.put_decref_clear(item_temp, py_object_type)
5297 code.funcstate.release_temp(item_temp)
5298 self.module.generate_disposal_code(code)
5299 self.module.free_temps(code)
5303 #------------------------------------------------------------------------------------
5305 # Runtime support code
5307 #------------------------------------------------------------------------------------
5309 utility_function_predeclarations = \
5311 /* inline attribute */
5312 #ifndef CYTHON_INLINE
5313 #if defined(__GNUC__)
5314 #define CYTHON_INLINE __inline__
5315 #elif defined(_MSC_VER)
5316 #define CYTHON_INLINE __inline
5317 #elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
5318 #define CYTHON_INLINE inline
5320 #define CYTHON_INLINE
5324 /* unused attribute */
5325 #ifndef CYTHON_UNUSED
5326 # if defined(__GNUC__)
5327 # if !(defined(__cplusplus)) || (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4))
5328 # define CYTHON_UNUSED __attribute__ ((__unused__))
5330 # define CYTHON_UNUSED
5332 # elif defined(__ICC) || defined(__INTEL_COMPILER)
5333 # define CYTHON_UNUSED __attribute__ ((__unused__))
5335 # define CYTHON_UNUSED
5339 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*/
5343 if Options.gcc_branch_hints:
5344 branch_prediction_macros = \
5347 /* Test for GCC > 2.95 */
5348 #if __GNUC__ > 2 || (__GNUC__ == 2 && (__GNUC_MINOR__ > 95))
5349 #define likely(x) __builtin_expect(!!(x), 1)
5350 #define unlikely(x) __builtin_expect(!!(x), 0)
5351 #else /* __GNUC__ > 2 ... */
5352 #define likely(x) (x)
5353 #define unlikely(x) (x)
5354 #endif /* __GNUC__ > 2 ... */
5355 #else /* __GNUC__ */
5356 #define likely(x) (x)
5357 #define unlikely(x) (x)
5358 #endif /* __GNUC__ */
5361 branch_prediction_macros = \
5363 #define likely(x) (x)
5364 #define unlikely(x) (x)
5367 #get_name_predeclaration = \
5368 #"static PyObject *__Pyx_GetName(PyObject *dict, char *name); /*proto*/"
5370 #get_name_interned_predeclaration = \
5371 #"static PyObject *__Pyx_GetName(PyObject *dict, PyObject *name); /*proto*/"
5373 #------------------------------------------------------------------------------------
5375 printing_utility_code = UtilityCode(
5377 static int __Pyx_Print(PyObject*, PyObject *, int); /*proto*/
5378 #if PY_MAJOR_VERSION >= 3
5379 static PyObject* %s = 0;
5380 static PyObject* %s = 0;
5382 """ % (Naming.print_function, Naming.print_function_kwargs),
5384 #if PY_MAJOR_VERSION >= 3
5388 """ % (Naming.print_function, Naming.print_function_kwargs),
5390 #if PY_MAJOR_VERSION < 3
5391 static PyObject *__Pyx_GetStdout(void) {
5392 PyObject *f = PySys_GetObject((char *)"stdout");
5394 PyErr_SetString(PyExc_RuntimeError, "lost sys.stdout");
5399 static int __Pyx_Print(PyObject* f, PyObject *arg_tuple, int newline) {
5404 if (!(f = __Pyx_GetStdout()))
5407 for (i=0; i < PyTuple_GET_SIZE(arg_tuple); i++) {
5408 if (PyFile_SoftSpace(f, 1)) {
5409 if (PyFile_WriteString(" ", f) < 0)
5412 v = PyTuple_GET_ITEM(arg_tuple, i);
5413 if (PyFile_WriteObject(v, f, Py_PRINT_RAW) < 0)
5415 if (PyString_Check(v)) {
5416 char *s = PyString_AsString(v);
5417 Py_ssize_t len = PyString_Size(v);
5419 isspace(Py_CHARMASK(s[len-1])) &&
5421 PyFile_SoftSpace(f, 0);
5425 if (PyFile_WriteString("\n", f) < 0)
5427 PyFile_SoftSpace(f, 0);
5432 #else /* Python 3 has a print function */
5434 static int __Pyx_Print(PyObject* stream, PyObject *arg_tuple, int newline) {
5435 PyObject* kwargs = 0;
5436 PyObject* result = 0;
5437 PyObject* end_string;
5438 if (unlikely(!%(PRINT_FUNCTION)s)) {
5439 %(PRINT_FUNCTION)s = __Pyx_GetAttrString(%(BUILTINS)s, "print");
5440 if (!%(PRINT_FUNCTION)s)
5444 kwargs = PyDict_New();
5445 if (unlikely(!kwargs))
5447 if (unlikely(PyDict_SetItemString(kwargs, "file", stream) < 0))
5450 end_string = PyUnicode_FromStringAndSize(" ", 1);
5451 if (unlikely(!end_string))
5453 if (PyDict_SetItemString(kwargs, "end", end_string) < 0) {
5454 Py_DECREF(end_string);
5457 Py_DECREF(end_string);
5459 } else if (!newline) {
5460 if (unlikely(!%(PRINT_KWARGS)s)) {
5461 %(PRINT_KWARGS)s = PyDict_New();
5462 if (unlikely(!%(PRINT_KWARGS)s))
5464 end_string = PyUnicode_FromStringAndSize(" ", 1);
5465 if (unlikely(!end_string))
5467 if (PyDict_SetItemString(%(PRINT_KWARGS)s, "end", end_string) < 0) {
5468 Py_DECREF(end_string);
5471 Py_DECREF(end_string);
5473 kwargs = %(PRINT_KWARGS)s;
5475 result = PyObject_Call(%(PRINT_FUNCTION)s, arg_tuple, kwargs);
5476 if (unlikely(kwargs) && (kwargs != %(PRINT_KWARGS)s))
5483 if (kwargs != %(PRINT_KWARGS)s)
5489 """ % {'BUILTINS' : Naming.builtins_cname,
5490 'PRINT_FUNCTION' : Naming.print_function,
5491 'PRINT_KWARGS' : Naming.print_function_kwargs}
5495 printing_one_utility_code = UtilityCode(
5497 static int __Pyx_PrintOne(PyObject* stream, PyObject *o); /*proto*/
5500 #if PY_MAJOR_VERSION < 3
5502 static int __Pyx_PrintOne(PyObject* f, PyObject *o) {
5504 if (!(f = __Pyx_GetStdout()))
5507 if (PyFile_SoftSpace(f, 0)) {
5508 if (PyFile_WriteString(" ", f) < 0)
5511 if (PyFile_WriteObject(o, f, Py_PRINT_RAW) < 0)
5513 if (PyFile_WriteString("\n", f) < 0)
5516 /* the line below is just to avoid compiler
5517 * compiler warnings about unused functions */
5518 return __Pyx_Print(f, NULL, 0);
5521 #else /* Python 3 has a print function */
5523 static int __Pyx_PrintOne(PyObject* stream, PyObject *o) {
5525 PyObject* arg_tuple = PyTuple_New(1);
5526 if (unlikely(!arg_tuple))
5529 PyTuple_SET_ITEM(arg_tuple, 0, o);
5530 res = __Pyx_Print(stream, arg_tuple, 1);
5531 Py_DECREF(arg_tuple);
5537 requires=[printing_utility_code])
5541 #------------------------------------------------------------------------------------
5543 # Exception raising code
5545 # Exceptions are raised by __Pyx_Raise() and stored as plain
5546 # type/value/tb in PyThreadState->curexc_*. When being caught by an
5547 # 'except' statement, curexc_* is moved over to exc_* by
5548 # __Pyx_GetException()
5550 restore_exception_utility_code = UtilityCode(
5552 static CYTHON_INLINE void __Pyx_ErrRestore(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
5553 static CYTHON_INLINE void __Pyx_ErrFetch(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
5556 static CYTHON_INLINE void __Pyx_ErrRestore(PyObject *type, PyObject *value, PyObject *tb) {
5557 PyObject *tmp_type, *tmp_value, *tmp_tb;
5558 PyThreadState *tstate = PyThreadState_GET();
5560 tmp_type = tstate->curexc_type;
5561 tmp_value = tstate->curexc_value;
5562 tmp_tb = tstate->curexc_traceback;
5563 tstate->curexc_type = type;
5564 tstate->curexc_value = value;
5565 tstate->curexc_traceback = tb;
5566 Py_XDECREF(tmp_type);
5567 Py_XDECREF(tmp_value);
5571 static CYTHON_INLINE void __Pyx_ErrFetch(PyObject **type, PyObject **value, PyObject **tb) {
5572 PyThreadState *tstate = PyThreadState_GET();
5573 *type = tstate->curexc_type;
5574 *value = tstate->curexc_value;
5575 *tb = tstate->curexc_traceback;
5577 tstate->curexc_type = 0;
5578 tstate->curexc_value = 0;
5579 tstate->curexc_traceback = 0;
5584 # The following function is based on do_raise() from ceval.c. There
5585 # are separate versions for Python2 and Python3 as exception handling
5586 # has changed quite a lot between the two versions.
5588 raise_utility_code = UtilityCode(
5590 static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
5593 #if PY_MAJOR_VERSION < 3
5594 static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb) {
5598 /* First, check the traceback argument, replacing None with NULL. */
5599 if (tb == Py_None) {
5603 else if (tb != NULL && !PyTraceBack_Check(tb)) {
5604 PyErr_SetString(PyExc_TypeError,
5605 "raise: arg 3 must be a traceback or None");
5608 /* Next, replace a missing value with None */
5609 if (value == NULL) {
5613 #if PY_VERSION_HEX < 0x02050000
5614 if (!PyClass_Check(type))
5616 if (!PyType_Check(type))
5619 /* Raising an instance. The value should be a dummy. */
5620 if (value != Py_None) {
5621 PyErr_SetString(PyExc_TypeError,
5622 "instance exception may not have a separate value");
5625 /* Normalize to raise <class>, <instance> */
5628 #if PY_VERSION_HEX < 0x02050000
5629 if (PyInstance_Check(type)) {
5630 type = (PyObject*) ((PyInstanceObject*)type)->in_class;
5635 PyErr_SetString(PyExc_TypeError,
5636 "raise: exception must be an old-style class or instance");
5640 type = (PyObject*) Py_TYPE(type);
5642 if (!PyType_IsSubtype((PyTypeObject *)type, (PyTypeObject *)PyExc_BaseException)) {
5643 PyErr_SetString(PyExc_TypeError,
5644 "raise: exception class must be a subclass of BaseException");
5650 __Pyx_ErrRestore(type, value, tb);
5659 #else /* Python 3+ */
5661 static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb) {
5662 if (tb == Py_None) {
5664 } else if (tb && !PyTraceBack_Check(tb)) {
5665 PyErr_SetString(PyExc_TypeError,
5666 "raise: arg 3 must be a traceback or None");
5669 if (value == Py_None)
5672 if (PyExceptionInstance_Check(type)) {
5674 PyErr_SetString(PyExc_TypeError,
5675 "instance exception may not have a separate value");
5679 type = (PyObject*) Py_TYPE(value);
5680 } else if (!PyExceptionClass_Check(type)) {
5681 PyErr_SetString(PyExc_TypeError,
5682 "raise: exception class must be a subclass of BaseException");
5686 PyErr_SetObject(type, value);
5689 PyThreadState *tstate = PyThreadState_GET();
5690 PyObject* tmp_tb = tstate->curexc_traceback;
5693 tstate->curexc_traceback = tb;
5703 requires=[restore_exception_utility_code])
5705 #------------------------------------------------------------------------------------
5707 get_exception_utility_code = UtilityCode(
5709 static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
5712 static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb) {
5713 PyObject *local_type, *local_value, *local_tb;
5714 PyObject *tmp_type, *tmp_value, *tmp_tb;
5715 PyThreadState *tstate = PyThreadState_GET();
5716 local_type = tstate->curexc_type;
5717 local_value = tstate->curexc_value;
5718 local_tb = tstate->curexc_traceback;
5719 tstate->curexc_type = 0;
5720 tstate->curexc_value = 0;
5721 tstate->curexc_traceback = 0;
5722 PyErr_NormalizeException(&local_type, &local_value, &local_tb);
5723 if (unlikely(tstate->curexc_type))
5725 #if PY_MAJOR_VERSION >= 3
5726 if (unlikely(PyException_SetTraceback(local_value, local_tb) < 0))
5730 *value = local_value;
5732 Py_INCREF(local_type);
5733 Py_INCREF(local_value);
5734 Py_INCREF(local_tb);
5735 tmp_type = tstate->exc_type;
5736 tmp_value = tstate->exc_value;
5737 tmp_tb = tstate->exc_traceback;
5738 tstate->exc_type = local_type;
5739 tstate->exc_value = local_value;
5740 tstate->exc_traceback = local_tb;
5741 /* Make sure tstate is in a consistent state when we XDECREF
5742 these objects (XDECREF may run arbitrary code). */
5743 Py_XDECREF(tmp_type);
5744 Py_XDECREF(tmp_value);
5751 Py_XDECREF(local_type);
5752 Py_XDECREF(local_value);
5753 Py_XDECREF(local_tb);
5759 #------------------------------------------------------------------------------------
5761 get_exception_tuple_utility_code = UtilityCode(proto="""
5762 static PyObject *__Pyx_GetExceptionTuple(void); /*proto*/
5764 # I doubt that calling __Pyx_GetException() here is correct as it moves
5765 # the exception from tstate->curexc_* to tstate->exc_*, which prevents
5766 # exception handlers later on from receiving it.
5768 static PyObject *__Pyx_GetExceptionTuple(void) {
5769 PyObject *type = NULL, *value = NULL, *tb = NULL;
5770 if (__Pyx_GetException(&type, &value, &tb) == 0) {
5771 PyObject* exc_info = PyTuple_New(3);
5776 PyTuple_SET_ITEM(exc_info, 0, type);
5777 PyTuple_SET_ITEM(exc_info, 1, value);
5778 PyTuple_SET_ITEM(exc_info, 2, tb);
5785 requires=[get_exception_utility_code])
5787 #------------------------------------------------------------------------------------
5789 reset_exception_utility_code = UtilityCode(
5791 static CYTHON_INLINE void __Pyx_ExceptionSave(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
5792 static void __Pyx_ExceptionReset(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
5795 static CYTHON_INLINE void __Pyx_ExceptionSave(PyObject **type, PyObject **value, PyObject **tb) {
5796 PyThreadState *tstate = PyThreadState_GET();
5797 *type = tstate->exc_type;
5798 *value = tstate->exc_value;
5799 *tb = tstate->exc_traceback;
5805 static void __Pyx_ExceptionReset(PyObject *type, PyObject *value, PyObject *tb) {
5806 PyObject *tmp_type, *tmp_value, *tmp_tb;
5807 PyThreadState *tstate = PyThreadState_GET();
5808 tmp_type = tstate->exc_type;
5809 tmp_value = tstate->exc_value;
5810 tmp_tb = tstate->exc_traceback;
5811 tstate->exc_type = type;
5812 tstate->exc_value = value;
5813 tstate->exc_traceback = tb;
5814 Py_XDECREF(tmp_type);
5815 Py_XDECREF(tmp_value);
5820 #------------------------------------------------------------------------------------
5822 arg_type_test_utility_code = UtilityCode(
5824 static int __Pyx_ArgTypeTest(PyObject *obj, PyTypeObject *type, int none_allowed,
5825 const char *name, int exact); /*proto*/
5828 static int __Pyx_ArgTypeTest(PyObject *obj, PyTypeObject *type, int none_allowed,
5829 const char *name, int exact)
5832 PyErr_Format(PyExc_SystemError, "Missing type object");
5835 if (none_allowed && obj == Py_None) return 1;
5837 if (Py_TYPE(obj) == type) return 1;
5840 if (PyObject_TypeCheck(obj, type)) return 1;
5842 PyErr_Format(PyExc_TypeError,
5843 "Argument '%s' has incorrect type (expected %s, got %s)",
5844 name, type->tp_name, Py_TYPE(obj)->tp_name);
5849 #------------------------------------------------------------------------------------
5851 # __Pyx_RaiseArgtupleInvalid raises the correct exception when too
5852 # many or too few positional arguments were found. This handles
5853 # Py_ssize_t formatting correctly.
5855 raise_argtuple_invalid_utility_code = UtilityCode(
5857 static void __Pyx_RaiseArgtupleInvalid(const char* func_name, int exact,
5858 Py_ssize_t num_min, Py_ssize_t num_max, Py_ssize_t num_found); /*proto*/
5861 static void __Pyx_RaiseArgtupleInvalid(
5862 const char* func_name,
5866 Py_ssize_t num_found)
5868 Py_ssize_t num_expected;
5869 const char *number, *more_or_less;
5871 if (num_found < num_min) {
5872 num_expected = num_min;
5873 more_or_less = "at least";
5875 num_expected = num_max;
5876 more_or_less = "at most";
5879 more_or_less = "exactly";
5881 number = (num_expected == 1) ? "" : "s";
5882 PyErr_Format(PyExc_TypeError,
5883 #if PY_VERSION_HEX < 0x02050000
5884 "%s() takes %s %d positional argument%s (%d given)",
5886 "%s() takes %s %zd positional argument%s (%zd given)",
5888 func_name, more_or_less, num_expected, number, num_found);
5892 raise_keyword_required_utility_code = UtilityCode(
5894 static CYTHON_INLINE void __Pyx_RaiseKeywordRequired(const char* func_name, PyObject* kw_name); /*proto*/
5897 static CYTHON_INLINE void __Pyx_RaiseKeywordRequired(
5898 const char* func_name,
5901 PyErr_Format(PyExc_TypeError,
5902 #if PY_MAJOR_VERSION >= 3
5903 "%s() needs keyword-only argument %U", func_name, kw_name);
5905 "%s() needs keyword-only argument %s", func_name,
5906 PyString_AS_STRING(kw_name));
5911 raise_double_keywords_utility_code = UtilityCode(
5913 static void __Pyx_RaiseDoubleKeywordsError(
5914 const char* func_name, PyObject* kw_name); /*proto*/
5917 static void __Pyx_RaiseDoubleKeywordsError(
5918 const char* func_name,
5921 PyErr_Format(PyExc_TypeError,
5922 #if PY_MAJOR_VERSION >= 3
5923 "%s() got multiple values for keyword argument '%U'", func_name, kw_name);
5925 "%s() got multiple values for keyword argument '%s'", func_name,
5926 PyString_AS_STRING(kw_name));
5931 #------------------------------------------------------------------------------------
5933 # __Pyx_CheckKeywordStrings raises an error if non-string keywords
5934 # were passed to a function, or if any keywords were passed to a
5935 # function that does not accept them.
5937 keyword_string_check_utility_code = UtilityCode(
5939 static CYTHON_INLINE int __Pyx_CheckKeywordStrings(PyObject *kwdict,
5940 const char* function_name, int kw_allowed); /*proto*/
5943 static CYTHON_INLINE int __Pyx_CheckKeywordStrings(
5945 const char* function_name,
5950 while (PyDict_Next(kwdict, &pos, &key, 0)) {
5951 #if PY_MAJOR_VERSION < 3
5952 if (unlikely(!PyString_CheckExact(key)) && unlikely(!PyString_Check(key)))
5954 if (unlikely(!PyUnicode_CheckExact(key)) && unlikely(!PyUnicode_Check(key)))
5956 goto invalid_keyword_type;
5958 if ((!kw_allowed) && unlikely(key))
5959 goto invalid_keyword;
5961 invalid_keyword_type:
5962 PyErr_Format(PyExc_TypeError,
5963 "%s() keywords must be strings", function_name);
5966 PyErr_Format(PyExc_TypeError,
5967 #if PY_MAJOR_VERSION < 3
5968 "%s() got an unexpected keyword argument '%s'",
5969 function_name, PyString_AsString(key));
5971 "%s() got an unexpected keyword argument '%U'",
5972 function_name, key);
5978 #------------------------------------------------------------------------------------
5980 # __Pyx_ParseOptionalKeywords copies the optional/unknown keyword
5981 # arguments from the kwds dict into kwds2. If kwds2 is NULL, unknown
5982 # keywords will raise an invalid keyword error.
5984 # Three kinds of errors are checked: 1) non-string keywords, 2)
5985 # unexpected keywords and 3) overlap with positional arguments.
5987 # If num_posargs is greater 0, it denotes the number of positional
5988 # arguments that were passed and that must therefore not appear
5989 # amongst the keywords as well.
5991 # This method does not check for required keyword arguments.
5994 parse_keywords_utility_code = UtilityCode(
5996 static int __Pyx_ParseOptionalKeywords(PyObject *kwds, PyObject **argnames[], \
5997 PyObject *kwds2, PyObject *values[], Py_ssize_t num_pos_args, \
5998 const char* function_name); /*proto*/
6001 static int __Pyx_ParseOptionalKeywords(
6003 PyObject **argnames[],
6006 Py_ssize_t num_pos_args,
6007 const char* function_name)
6009 PyObject *key = 0, *value = 0;
6012 PyObject*** first_kw_arg = argnames + num_pos_args;
6014 while (PyDict_Next(kwds, &pos, &key, &value)) {
6015 name = first_kw_arg;
6016 while (*name && (**name != key)) name++;
6018 values[name-argnames] = value;
6020 #if PY_MAJOR_VERSION < 3
6021 if (unlikely(!PyString_CheckExact(key)) && unlikely(!PyString_Check(key))) {
6023 if (unlikely(!PyUnicode_CheckExact(key)) && unlikely(!PyUnicode_Check(key))) {
6025 goto invalid_keyword_type;
6027 for (name = first_kw_arg; *name; name++) {
6028 #if PY_MAJOR_VERSION >= 3
6029 if (PyUnicode_GET_SIZE(**name) == PyUnicode_GET_SIZE(key) &&
6030 PyUnicode_Compare(**name, key) == 0) break;
6032 if (PyString_GET_SIZE(**name) == PyString_GET_SIZE(key) &&
6033 _PyString_Eq(**name, key)) break;
6037 values[name-argnames] = value;
6039 /* unexpected keyword found */
6040 for (name=argnames; name != first_kw_arg; name++) {
6041 if (**name == key) goto arg_passed_twice;
6042 #if PY_MAJOR_VERSION >= 3
6043 if (PyUnicode_GET_SIZE(**name) == PyUnicode_GET_SIZE(key) &&
6044 PyUnicode_Compare(**name, key) == 0) goto arg_passed_twice;
6046 if (PyString_GET_SIZE(**name) == PyString_GET_SIZE(key) &&
6047 _PyString_Eq(**name, key)) goto arg_passed_twice;
6051 if (unlikely(PyDict_SetItem(kwds2, key, value))) goto bad;
6053 goto invalid_keyword;
6061 __Pyx_RaiseDoubleKeywordsError(function_name, **name);
6063 invalid_keyword_type:
6064 PyErr_Format(PyExc_TypeError,
6065 "%s() keywords must be strings", function_name);
6068 PyErr_Format(PyExc_TypeError,
6069 #if PY_MAJOR_VERSION < 3
6070 "%s() got an unexpected keyword argument '%s'",
6071 function_name, PyString_AsString(key));
6073 "%s() got an unexpected keyword argument '%U'",
6074 function_name, key);
6081 #------------------------------------------------------------------------------------
6083 traceback_utility_code = UtilityCode(
6085 static void __Pyx_AddTraceback(const char *funcname); /*proto*/
6088 #include "compile.h"
6089 #include "frameobject.h"
6090 #include "traceback.h"
6092 static void __Pyx_AddTraceback(const char *funcname) {
6093 PyObject *py_srcfile = 0;
6094 PyObject *py_funcname = 0;
6095 PyObject *py_globals = 0;
6096 PyCodeObject *py_code = 0;
6097 PyFrameObject *py_frame = 0;
6099 #if PY_MAJOR_VERSION < 3
6100 py_srcfile = PyString_FromString(%(FILENAME)s);
6102 py_srcfile = PyUnicode_FromString(%(FILENAME)s);
6104 if (!py_srcfile) goto bad;
6106 #if PY_MAJOR_VERSION < 3
6107 py_funcname = PyString_FromFormat( "%%s (%%s:%%d)", funcname, %(CFILENAME)s, %(CLINENO)s);
6109 py_funcname = PyUnicode_FromFormat( "%%s (%%s:%%d)", funcname, %(CFILENAME)s, %(CLINENO)s);
6113 #if PY_MAJOR_VERSION < 3
6114 py_funcname = PyString_FromString(funcname);
6116 py_funcname = PyUnicode_FromString(funcname);
6119 if (!py_funcname) goto bad;
6120 py_globals = PyModule_GetDict(%(GLOBALS)s);
6121 if (!py_globals) goto bad;
6122 py_code = PyCode_New(
6123 0, /*int argcount,*/
6124 #if PY_MAJOR_VERSION >= 3
6125 0, /*int kwonlyargcount,*/
6128 0, /*int stacksize,*/
6130 %(EMPTY_BYTES)s, /*PyObject *code,*/
6131 %(EMPTY_TUPLE)s, /*PyObject *consts,*/
6132 %(EMPTY_TUPLE)s, /*PyObject *names,*/
6133 %(EMPTY_TUPLE)s, /*PyObject *varnames,*/
6134 %(EMPTY_TUPLE)s, /*PyObject *freevars,*/
6135 %(EMPTY_TUPLE)s, /*PyObject *cellvars,*/
6136 py_srcfile, /*PyObject *filename,*/
6137 py_funcname, /*PyObject *name,*/
6138 %(LINENO)s, /*int firstlineno,*/
6139 %(EMPTY_BYTES)s /*PyObject *lnotab*/
6141 if (!py_code) goto bad;
6142 py_frame = PyFrame_New(
6143 PyThreadState_GET(), /*PyThreadState *tstate,*/
6144 py_code, /*PyCodeObject *code,*/
6145 py_globals, /*PyObject *globals,*/
6146 0 /*PyObject *locals*/
6148 if (!py_frame) goto bad;
6149 py_frame->f_lineno = %(LINENO)s;
6150 PyTraceBack_Here(py_frame);
6152 Py_XDECREF(py_srcfile);
6153 Py_XDECREF(py_funcname);
6154 Py_XDECREF(py_code);
6155 Py_XDECREF(py_frame);
6158 'FILENAME': Naming.filename_cname,
6159 'LINENO': Naming.lineno_cname,
6160 'CFILENAME': Naming.cfilenm_cname,
6161 'CLINENO': Naming.clineno_cname,
6162 'GLOBALS': Naming.module_cname,
6163 'EMPTY_TUPLE' : Naming.empty_tuple,
6164 'EMPTY_BYTES' : Naming.empty_bytes,
6167 #------------------------------------------------------------------------------------
6169 unraisable_exception_utility_code = UtilityCode(
6171 static void __Pyx_WriteUnraisable(const char *name); /*proto*/
6174 static void __Pyx_WriteUnraisable(const char *name) {
6175 PyObject *old_exc, *old_val, *old_tb;
6177 __Pyx_ErrFetch(&old_exc, &old_val, &old_tb);
6178 #if PY_MAJOR_VERSION < 3
6179 ctx = PyString_FromString(name);
6181 ctx = PyUnicode_FromString(name);
6183 __Pyx_ErrRestore(old_exc, old_val, old_tb);
6185 PyErr_WriteUnraisable(Py_None);
6187 PyErr_WriteUnraisable(ctx);
6192 requires=[restore_exception_utility_code])
6194 #------------------------------------------------------------------------------------
6196 set_vtable_utility_code = UtilityCode(
6198 static int __Pyx_SetVtable(PyObject *dict, void *vtable); /*proto*/
6201 static int __Pyx_SetVtable(PyObject *dict, void *vtable) {
6202 #if PY_VERSION_HEX >= 0x02070000 && !(PY_MAJOR_VERSION==3&&PY_MINOR_VERSION==0)
6203 PyObject *ob = PyCapsule_New(vtable, 0, 0);
6205 PyObject *ob = PyCObject_FromVoidPtr(vtable, 0);
6209 if (PyDict_SetItemString(dict, "__pyx_vtable__", ob) < 0)
6219 #------------------------------------------------------------------------------------
6221 get_vtable_utility_code = UtilityCode(
6223 static int __Pyx_GetVtable(PyObject *dict, void *vtabptr); /*proto*/
6226 static int __Pyx_GetVtable(PyObject *dict, void *vtabptr) {
6227 PyObject *ob = PyMapping_GetItemString(dict, (char *)"__pyx_vtable__");
6230 #if PY_VERSION_HEX >= 0x02070000 && !(PY_MAJOR_VERSION==3&&PY_MINOR_VERSION==0)
6231 *(void **)vtabptr = PyCapsule_GetPointer(ob, 0);
6233 *(void **)vtabptr = PyCObject_AsVoidPtr(ob);
6235 if (!*(void **)vtabptr)
6245 #------------------------------------------------------------------------------------
6247 init_string_tab_utility_code = UtilityCode(
6249 static int __Pyx_InitStrings(__Pyx_StringTabEntry *t); /*proto*/
6252 static int __Pyx_InitStrings(__Pyx_StringTabEntry *t) {
6254 #if PY_MAJOR_VERSION < 3
6255 if (t->is_unicode) {
6256 *t->p = PyUnicode_DecodeUTF8(t->s, t->n - 1, NULL);
6257 } else if (t->intern) {
6258 *t->p = PyString_InternFromString(t->s);
6260 *t->p = PyString_FromStringAndSize(t->s, t->n - 1);
6262 #else /* Python 3+ has unicode identifiers */
6263 if (t->is_unicode | t->is_str) {
6265 *t->p = PyUnicode_InternFromString(t->s);
6266 } else if (t->encoding) {
6267 *t->p = PyUnicode_Decode(t->s, t->n - 1, t->encoding, NULL);
6269 *t->p = PyUnicode_FromStringAndSize(t->s, t->n - 1);
6272 *t->p = PyBytes_FromStringAndSize(t->s, t->n - 1);
6283 #------------------------------------------------------------------------------------
6285 force_init_threads_utility_code = UtilityCode(
6287 #ifndef __PYX_FORCE_INIT_THREADS
6288 #if PY_VERSION_HEX < 0x02040200
6289 #define __PYX_FORCE_INIT_THREADS 1
6291 #define __PYX_FORCE_INIT_THREADS 0
6296 #------------------------------------------------------------------------------------
6298 # Note that cPython ignores PyTrace_EXCEPTION,
6299 # but maybe some other profilers don't.
6301 profile_utility_code = UtilityCode(proto="""
6302 #ifndef CYTHON_PROFILE
6303 #define CYTHON_PROFILE 1
6306 #ifndef CYTHON_PROFILE_REUSE_FRAME
6307 #define CYTHON_PROFILE_REUSE_FRAME 0
6312 #include "compile.h"
6313 #include "frameobject.h"
6314 #include "traceback.h"
6316 #if CYTHON_PROFILE_REUSE_FRAME
6317 #define CYTHON_FRAME_MODIFIER static
6318 #define CYTHON_FRAME_DEL
6320 #define CYTHON_FRAME_MODIFIER
6321 #define CYTHON_FRAME_DEL Py_DECREF(%(FRAME)s)
6324 #define __Pyx_TraceDeclarations \\
6325 static PyCodeObject *%(FRAME_CODE)s = NULL; \\
6326 CYTHON_FRAME_MODIFIER PyFrameObject *%(FRAME)s = NULL; \\
6327 int __Pyx_use_tracing = 0;
6329 #define __Pyx_TraceCall(funcname, srcfile, firstlineno) \\
6330 if (unlikely(PyThreadState_GET()->use_tracing && PyThreadState_GET()->c_profilefunc)) { \\
6331 __Pyx_use_tracing = __Pyx_TraceSetupAndCall(&%(FRAME_CODE)s, &%(FRAME)s, funcname, srcfile, firstlineno); \\
6334 #define __Pyx_TraceException() \\
6335 if (unlikely(__Pyx_use_tracing( && PyThreadState_GET()->use_tracing && PyThreadState_GET()->c_profilefunc) { \\
6336 PyObject *exc_info = __Pyx_GetExceptionTuple(); \\
6338 PyThreadState_GET()->c_profilefunc( \\
6339 PyThreadState_GET()->c_profileobj, %(FRAME)s, PyTrace_EXCEPTION, exc_info); \\
6340 Py_DECREF(exc_info); \\
6344 #define __Pyx_TraceReturn(result) \\
6345 if (unlikely(__Pyx_use_tracing) && PyThreadState_GET()->use_tracing && PyThreadState_GET()->c_profilefunc) { \\
6346 PyThreadState_GET()->c_profilefunc( \\
6347 PyThreadState_GET()->c_profileobj, %(FRAME)s, PyTrace_RETURN, (PyObject*)result); \\
6348 CYTHON_FRAME_DEL; \\
6351 static PyCodeObject *__Pyx_createFrameCodeObject(const char *funcname, const char *srcfile, int firstlineno); /*proto*/
6352 static int __Pyx_TraceSetupAndCall(PyCodeObject** code, PyFrameObject** frame, const char *funcname, const char *srcfile, int firstlineno); /*proto*/
6356 #define __Pyx_TraceDeclarations
6357 #define __Pyx_TraceCall(funcname, srcfile, firstlineno)
6358 #define __Pyx_TraceException()
6359 #define __Pyx_TraceReturn(result)
6361 #endif /* CYTHON_PROFILE */
6364 "FRAME": Naming.frame_cname,
6365 "FRAME_CODE": Naming.frame_code_cname,
6371 static int __Pyx_TraceSetupAndCall(PyCodeObject** code,
6372 PyFrameObject** frame,
6373 const char *funcname,
6374 const char *srcfile,
6376 if (*frame == NULL || !CYTHON_PROFILE_REUSE_FRAME) {
6377 if (*code == NULL) {
6378 *code = __Pyx_createFrameCodeObject(funcname, srcfile, firstlineno);
6379 if (*code == NULL) return 0;
6381 *frame = PyFrame_New(
6382 PyThreadState_GET(), /*PyThreadState *tstate*/
6383 *code, /*PyCodeObject *code*/
6384 PyModule_GetDict(%(MODULE)s), /*PyObject *globals*/
6385 0 /*PyObject *locals*/
6387 if (*frame == NULL) return 0;
6390 (*frame)->f_tstate = PyThreadState_GET();
6392 return PyThreadState_GET()->c_profilefunc(PyThreadState_GET()->c_profileobj, *frame, PyTrace_CALL, NULL) == 0;
6395 static PyCodeObject *__Pyx_createFrameCodeObject(const char *funcname, const char *srcfile, int firstlineno) {
6396 PyObject *py_srcfile = 0;
6397 PyObject *py_funcname = 0;
6398 PyCodeObject *py_code = 0;
6400 #if PY_MAJOR_VERSION < 3
6401 py_funcname = PyString_FromString(funcname);
6402 py_srcfile = PyString_FromString(srcfile);
6404 py_funcname = PyUnicode_FromString(funcname);
6405 py_srcfile = PyUnicode_FromString(srcfile);
6407 if (!py_funcname | !py_srcfile) goto bad;
6409 py_code = PyCode_New(
6410 0, /*int argcount,*/
6411 #if PY_MAJOR_VERSION >= 3
6412 0, /*int kwonlyargcount,*/
6415 0, /*int stacksize,*/
6417 %(EMPTY_BYTES)s, /*PyObject *code,*/
6418 %(EMPTY_TUPLE)s, /*PyObject *consts,*/
6419 %(EMPTY_TUPLE)s, /*PyObject *names,*/
6420 %(EMPTY_TUPLE)s, /*PyObject *varnames,*/
6421 %(EMPTY_TUPLE)s, /*PyObject *freevars,*/
6422 %(EMPTY_TUPLE)s, /*PyObject *cellvars,*/
6423 py_srcfile, /*PyObject *filename,*/
6424 py_funcname, /*PyObject *name,*/
6425 firstlineno, /*int firstlineno,*/
6426 %(EMPTY_BYTES)s /*PyObject *lnotab*/
6430 Py_XDECREF(py_srcfile);
6431 Py_XDECREF(py_funcname);
6436 #endif /* CYTHON_PROFILE */
6438 'EMPTY_TUPLE' : Naming.empty_tuple,
6439 'EMPTY_BYTES' : Naming.empty_bytes,
6440 "MODULE": Naming.module_cname,