3 # Pyrex - Parse tree nodes
6 import sys, os, time, copy
12 from sets import Set as set
16 from Errors import error, warning, InternalError
20 from PyrexTypes import py_object_type, error_type, CFuncType
21 from Symtab import ModuleScope, LocalScope, ClosureScope, \
22 StructOrUnionScope, PyClassScope, CClassScope, CppClassScope
23 from Cython.Utils import open_new_file, replace_suffix
24 from Code import UtilityCode
25 from StringEncoding import EncodedString, escape_byte_string, split_string_literal
30 absolute_path_length = 0
32 def relative_position(pos):
34 We embed the relative filename in the generated C file, since we
35 don't want to have to regnerate and compile all the source code
36 whenever the Python install directory moves (which could happen,
37 e.g,. when distributing binaries.)
40 a position tuple -- (absolute filename, line number column position)
48 global absolute_path_length
49 if absolute_path_length==0:
50 absolute_path_length = len(os.path.abspath(os.getcwd()))
51 return (pos[0].get_filenametable_entry()[absolute_path_length+1:], pos[1])
53 def embed_position(pos, docstring):
54 if not Options.embed_pos_in_docstring:
56 pos_line = u'File: %s (starting at line %s)' % relative_position(pos)
59 return EncodedString(pos_line)
61 # make sure we can encode the filename in the docstring encoding
62 # otherwise make the docstring a unicode string
63 encoding = docstring.encoding
64 if encoding is not None:
66 encoded_bytes = pos_line.encode(encoding)
67 except UnicodeEncodeError:
71 # reuse the string encoding of the original docstring
72 doc = EncodedString(pos_line)
74 doc = EncodedString(pos_line + u'\n' + docstring)
75 doc.encoding = encoding
79 from Code import CCodeWriter
80 from types import FunctionType
82 def write_func_call(func):
84 if len(args) > 1 and isinstance(args[1], CCodeWriter):
85 # here we annotate the code with this function call
86 # but only if new code is generated
88 marker = ' /* %s -> %s.%s %s */' % (
89 ' ' * code.call_level,
90 node.__class__.__name__,
93 pristine = code.buffer.stream.tell()
95 start = code.buffer.stream.tell()
97 res = func(*args, **kwds)
99 if start == code.buffer.stream.tell():
100 code.buffer.stream.seek(pristine)
102 marker = marker.replace('->', '<-')
106 return func(*args, **kwds)
109 class VerboseCodeWriter(type):
110 # Set this as a metaclass to trace function calls in code.
111 # This slows down code generation and makes much larger files.
112 def __new__(cls, name, bases, attrs):
114 for mname, m in attrs.items():
115 if isinstance(m, FunctionType):
116 attrs[mname] = write_func_call(m)
117 return super(VerboseCodeWriter, cls).__new__(cls, name, bases, attrs)
121 # pos (string, int, int) Source file position
122 # is_name boolean Is a NameNode
123 # is_literal boolean Is a ConstNode
125 if DebugFlags.debug_trace_code_generation:
126 __metaclass__ = VerboseCodeWriter
132 # All descandants should set child_attrs to a list of the attributes
133 # containing nodes considered "children" in the tree. Each such attribute
134 # can either contain a single node or a list of nodes. See Visitor.py.
137 def __init__(self, pos, **kw):
139 self.__dict__.update(kw)
141 gil_message = "Operation"
145 def gil_error(self, env=None):
146 error(self.pos, "%s not allowed without gil" % self.gil_message)
148 cpp_message = "Operation"
150 def cpp_check(self, env):
155 error(self.pos, "%s only allowed in c++" % self.cpp_message)
157 def clone_node(self):
158 """Clone the node. This is defined as a shallow copy, except for member lists
159 amongst the child attributes (from get_child_accessors) which are also
160 copied. Lists containing child nodes are thus seen as a way for the node
161 to hold multiple children directly; the list is not treated as a seperate
162 level in the tree."""
163 result = copy.copy(self)
164 for attrname in result.child_attrs:
165 value = getattr(result, attrname)
166 if isinstance(value, list):
167 setattr(result, attrname, [x for x in value])
172 # There are 4 phases of parse tree processing, applied in order to
173 # all the statements in a given scope-block:
175 # (0) analyse_control_flow
176 # Create the control flow tree into which state can be asserted and
179 # (1) analyse_declarations
180 # Make symbol table entries for all declarations at the current
181 # level, both explicit (def, cdef, etc.) and implicit (assignment
182 # to an otherwise undeclared name).
184 # (2) analyse_expressions
185 # Determine the result types of expressions and fill in the
186 # 'type' attribute of each ExprNode. Insert coercion nodes into the
187 # tree where needed to convert to and from Python objects.
188 # Allocate temporary locals for intermediate results. Fill
189 # in the 'result_code' attribute of each ExprNode with a C code
193 # Emit C code for all declarations, statements and expressions.
194 # Recursively applies the 3 processing phases to the bodies of
198 def analyse_control_flow(self, env):
201 def analyse_declarations(self, env):
204 def analyse_expressions(self, env):
205 raise InternalError("analyse_expressions not implemented for %s" % \
206 self.__class__.__name__)
208 def generate_code(self, code):
209 raise InternalError("generate_code not implemented for %s" % \
210 self.__class__.__name__)
212 def annotate(self, code):
213 # mro does the wrong thing
214 if isinstance(self, BlockNode):
215 self.body.annotate(code)
220 except AttributeError:
222 if not self.child_attrs:
225 for attr in self.child_attrs:
226 child = getattr(self, attr)
227 # Sometimes lists, sometimes nodes
230 elif isinstance(child, list):
232 pos = max(pos, c.end_pos())
234 pos = max(pos, child.end_pos())
238 def dump(self, level=0, filter_out=("pos",), cutoff=100, encountered=None):
240 return "<...nesting level cutoff...>"
241 if encountered is None:
243 if id(self) in encountered:
244 return "<%s (%d) -- already output>" % (self.__class__.__name__, id(self))
245 encountered.add(id(self))
247 def dump_child(x, level):
248 if isinstance(x, Node):
249 return x.dump(level, filter_out, cutoff-1, encountered)
250 elif isinstance(x, list):
251 return "[%s]" % ", ".join([dump_child(item, level) for item in x])
256 attrs = [(key, value) for key, value in self.__dict__.iteritems() if key not in filter_out]
258 return "<%s (%d)>" % (self.__class__.__name__, id(self))
261 res = "<%s (%d)\n" % (self.__class__.__name__, id(self))
262 for key, value in attrs:
263 res += "%s %s: %s\n" % (indent, key, dump_child(value, level + 1))
264 res += "%s>" % indent
267 class CompilerDirectivesNode(Node):
269 Sets compiler directives for the children nodes
271 # directives {string:value} A dictionary holding the right value for
272 # *all* possible directives.
274 child_attrs = ["body"]
276 def analyse_control_flow(self, env):
278 env.directives = self.directives
279 self.body.analyse_control_flow(env)
282 def analyse_declarations(self, env):
284 env.directives = self.directives
285 self.body.analyse_declarations(env)
288 def analyse_expressions(self, env):
290 env.directives = self.directives
291 self.body.analyse_expressions(env)
294 def generate_function_definitions(self, env, code):
295 env_old = env.directives
296 code_old = code.globalstate.directives
297 code.globalstate.directives = self.directives
298 self.body.generate_function_definitions(env, code)
299 env.directives = env_old
300 code.globalstate.directives = code_old
302 def generate_execution_code(self, code):
303 old = code.globalstate.directives
304 code.globalstate.directives = self.directives
305 self.body.generate_execution_code(code)
306 code.globalstate.directives = old
308 def annotate(self, code):
309 old = code.globalstate.directives
310 code.globalstate.directives = self.directives
311 self.body.annotate(code)
312 code.globalstate.directives = old
314 class BlockNode(object):
315 # Mixin class for nodes representing a declaration block.
317 def generate_cached_builtins_decls(self, env, code):
318 entries = env.global_scope().undeclared_cached_builtins
319 for entry in entries:
320 code.globalstate.add_cached_builtin_decl(entry)
324 class StatListNode(Node):
325 # stats a list of StatNode
327 child_attrs = ["stats"]
329 def create_analysed(pos, env, *args, **kw):
330 node = StatListNode(pos, *args, **kw)
331 return node # No node-specific analysis necesarry
332 create_analysed = staticmethod(create_analysed)
334 def analyse_control_flow(self, env):
335 for stat in self.stats:
336 stat.analyse_control_flow(env)
338 def analyse_declarations(self, env):
339 #print "StatListNode.analyse_declarations" ###
340 for stat in self.stats:
341 stat.analyse_declarations(env)
343 def analyse_expressions(self, env):
344 #print "StatListNode.analyse_expressions" ###
345 for stat in self.stats:
346 stat.analyse_expressions(env)
348 def generate_function_definitions(self, env, code):
349 #print "StatListNode.generate_function_definitions" ###
350 for stat in self.stats:
351 stat.generate_function_definitions(env, code)
353 def generate_execution_code(self, code):
354 #print "StatListNode.generate_execution_code" ###
355 for stat in self.stats:
356 code.mark_pos(stat.pos)
357 stat.generate_execution_code(code)
359 def annotate(self, code):
360 for stat in self.stats:
364 class StatNode(Node):
366 # Code generation for statements is split into the following subphases:
368 # (1) generate_function_definitions
369 # Emit C code for the definitions of any structs,
370 # unions, enums and functions defined in the current
373 # (2) generate_execution_code
374 # Emit C code for executable statements.
377 def generate_function_definitions(self, env, code):
380 def generate_execution_code(self, code):
381 raise InternalError("generate_execution_code not implemented for %s" % \
382 self.__class__.__name__)
385 class CDefExternNode(StatNode):
386 # include_file string or None
389 child_attrs = ["body"]
391 def analyse_declarations(self, env):
392 if self.include_file:
393 env.add_include_file(self.include_file)
394 old_cinclude_flag = env.in_cinclude
396 self.body.analyse_declarations(env)
397 env.in_cinclude = old_cinclude_flag
399 def analyse_expressions(self, env):
402 def generate_execution_code(self, code):
405 def annotate(self, code):
406 self.body.annotate(code)
409 class CDeclaratorNode(Node):
410 # Part of a C declaration.
412 # Processing during analyse_declarations phase:
415 # Returns (name, type) pair where name is the
416 # CNameDeclaratorNode of the name being declared
417 # and type is the type it is being declared as.
419 # calling_convention string Calling convention of CFuncDeclaratorNode
420 # for which this is a base
424 calling_convention = ""
427 class CNameDeclaratorNode(CDeclaratorNode):
428 # name string The Pyrex name being declared
429 # cname string or None C name, if specified
430 # default ExprNode or None the value assigned on declaration
432 child_attrs = ['default']
436 def analyse(self, base_type, env, nonempty = 0):
437 if nonempty and self.name == '':
438 # May have mistaken the name for the type.
439 if base_type.is_ptr or base_type.is_array or base_type.is_buffer:
440 error(self.pos, "Missing argument name")
441 elif base_type.is_void:
442 error(self.pos, "Use spam() rather than spam(void) to declare a function with no arguments.")
444 self.name = base_type.declaration_code("", for_display=1, pyrex=1)
445 base_type = py_object_type
446 self.type = base_type
447 return self, base_type
449 class CPtrDeclaratorNode(CDeclaratorNode):
450 # base CDeclaratorNode
452 child_attrs = ["base"]
454 def analyse(self, base_type, env, nonempty = 0):
455 if base_type.is_pyobject:
457 "Pointer base type cannot be a Python object")
458 ptr_type = PyrexTypes.c_ptr_type(base_type)
459 return self.base.analyse(ptr_type, env, nonempty = nonempty)
461 class CReferenceDeclaratorNode(CDeclaratorNode):
462 # base CDeclaratorNode
464 child_attrs = ["base"]
466 def analyse(self, base_type, env, nonempty = 0):
467 if base_type.is_pyobject:
469 "Reference base type cannot be a Python object")
470 ref_type = PyrexTypes.c_ref_type(base_type)
471 return self.base.analyse(ref_type, env, nonempty = nonempty)
473 class CArrayDeclaratorNode(CDeclaratorNode):
474 # base CDeclaratorNode
477 child_attrs = ["base", "dimension"]
479 def analyse(self, base_type, env, nonempty = 0):
480 if base_type.is_cpp_class:
481 from ExprNodes import TupleNode
482 if isinstance(self.dimension, TupleNode):
483 args = self.dimension.args
485 args = self.dimension,
486 values = [v.analyse_as_type(env) for v in args]
488 ix = values.index(None)
489 error(args[ix].pos, "Template parameter not a type.")
491 base_type = base_type.specialize_here(self.pos, values)
492 return self.base.analyse(base_type, env, nonempty = nonempty)
494 self.dimension.analyse_const_expression(env)
495 if not self.dimension.type.is_int:
496 error(self.dimension.pos, "Array dimension not integer")
497 size = self.dimension.get_constant_c_result_code()
506 if not base_type.is_complete():
508 "Array element type '%s' is incomplete" % base_type)
509 if base_type.is_pyobject:
511 "Array element cannot be a Python object")
512 if base_type.is_cfunction:
514 "Array element cannot be a function")
515 array_type = PyrexTypes.c_array_type(base_type, size)
516 return self.base.analyse(array_type, env, nonempty = nonempty)
519 class CFuncDeclaratorNode(CDeclaratorNode):
520 # base CDeclaratorNode
521 # args [CArgDeclNode]
522 # has_varargs boolean
523 # exception_value ConstNode
524 # exception_check boolean True if PyErr_Occurred check needed
525 # nogil boolean Can be called without gil
526 # with_gil boolean Acquire gil around function body
528 child_attrs = ["base", "args", "exception_value"]
531 optional_arg_count = 0
533 def analyse(self, return_type, env, nonempty = 0):
537 for i, arg_node in enumerate(self.args):
538 name_declarator, type = arg_node.analyse(env, nonempty = nonempty,
539 is_self_arg = (i == 0 and env.is_c_class_scope))
540 name = name_declarator.name
541 if name_declarator.cname:
543 "Function argument cannot have C name specification")
544 # Turn *[] argument into **
546 type = PyrexTypes.c_ptr_type(type.base_type)
547 # Catch attempted C-style func(void) decl
549 error(arg_node.pos, "Use spam() rather than spam(void) to declare a function with no arguments.")
550 func_type_args.append(
551 PyrexTypes.CFuncTypeArg(name, type, arg_node.pos))
553 self.optional_arg_count += 1
554 elif self.optional_arg_count:
555 error(self.pos, "Non-default argument follows default argument")
557 if self.optional_arg_count:
558 scope = StructOrUnionScope()
559 arg_count_member = '%sn' % Naming.pyrex_prefix
560 scope.declare_var(arg_count_member, PyrexTypes.c_int_type, self.pos)
561 for arg in func_type_args[len(func_type_args)-self.optional_arg_count:]:
562 scope.declare_var(arg.name, arg.type, arg.pos, allow_pyobject = 1)
563 struct_cname = env.mangle(Naming.opt_arg_prefix, self.base.name)
564 self.op_args_struct = env.global_scope().declare_struct_or_union(name = struct_cname,
569 cname = struct_cname)
570 self.op_args_struct.defined_in_pxd = 1
571 self.op_args_struct.used = 1
575 if self.exception_check == '+':
576 env.add_include_file('stdexcept')
577 if return_type.is_pyobject \
578 and (self.exception_value or self.exception_check) \
579 and self.exception_check != '+':
581 "Exception clause not allowed for function returning Python object")
583 if self.exception_value:
584 self.exception_value.analyse_const_expression(env)
585 if self.exception_check == '+':
586 self.exception_value.analyse_types(env)
587 exc_val_type = self.exception_value.type
588 if not exc_val_type.is_error and \
589 not exc_val_type.is_pyobject and \
590 not (exc_val_type.is_cfunction and not exc_val_type.return_type.is_pyobject and len(exc_val_type.args)==0):
591 error(self.exception_value.pos,
592 "Exception value must be a Python exception or cdef function with no arguments.")
593 exc_val = self.exception_value
595 self.exception_value = self.exception_value.coerce_to(return_type, env)
596 if self.exception_value.analyse_const_expression(env):
597 exc_val = self.exception_value.get_constant_c_result_code()
599 raise InternalError("get_constant_c_result_code not implemented for %s" %
600 self.exception_value.__class__.__name__)
601 if not return_type.assignable_from(self.exception_value.type):
602 error(self.exception_value.pos,
603 "Exception value incompatible with function return type")
604 exc_check = self.exception_check
605 if return_type.is_array:
607 "Function cannot return an array")
608 if return_type.is_cfunction:
610 "Function cannot return a function")
611 func_type = PyrexTypes.CFuncType(
612 return_type, func_type_args, self.has_varargs,
613 optional_arg_count = self.optional_arg_count,
614 exception_value = exc_val, exception_check = exc_check,
615 calling_convention = self.base.calling_convention,
616 nogil = self.nogil, with_gil = self.with_gil, is_overridable = self.overridable)
617 if self.optional_arg_count:
618 func_type.op_arg_struct = PyrexTypes.c_ptr_type(self.op_args_struct.type)
619 callspec = env.directives['callspec']
621 current = func_type.calling_convention
622 if current and current != callspec:
623 error(self.pos, "cannot have both '%s' and '%s' "
624 "calling conventions" % (current, callspec))
625 func_type.calling_convention = callspec
626 return self.base.analyse(func_type, env)
629 class CArgDeclNode(Node):
630 # Item in a function declaration argument list.
632 # base_type CBaseTypeNode
633 # declarator CDeclaratorNode
634 # not_none boolean Tagged with 'not None'
635 # or_none boolean Tagged with 'or None'
636 # accept_none boolean Resolved boolean for not_none/or_none
637 # default ExprNode or None
638 # default_value PyObjectConst constant for default value
639 # annotation ExprNode or None Py3 function arg annotation
640 # is_self_arg boolean Is the "self" arg of an extension type method
641 # is_type_arg boolean Is the "class" arg of an extension type classmethod
642 # is_kw_only boolean Is a keyword-only argument
644 child_attrs = ["base_type", "declarator", "default"]
650 name_declarator = None
654 def analyse(self, env, nonempty = 0, is_self_arg = False):
656 self.base_type.is_self_arg = self.is_self_arg = True
657 if self.type is None:
658 # The parser may missinterpret names as types...
660 if isinstance(self.declarator, CNameDeclaratorNode) and self.declarator.name == '':
662 self.declarator.name = self.base_type.name
663 self.base_type.name = None
664 self.base_type.is_basic_c_type = False
667 could_be_name = False
668 base_type = self.base_type.analyse(env, could_be_name = could_be_name)
669 if hasattr(self.base_type, 'arg_name') and self.base_type.arg_name:
670 self.declarator.name = self.base_type.arg_name
671 # The parser is unable to resolve the ambiguity of [] as part of the
672 # type (e.g. in buffers) or empty declarator (as with arrays).
673 # This is only arises for empty multi-dimensional arrays.
674 if (base_type.is_array
675 and isinstance(self.base_type, TemplatedTypeNode)
676 and isinstance(self.declarator, CArrayDeclaratorNode)):
677 declarator = self.declarator
678 while isinstance(declarator.base, CArrayDeclaratorNode):
679 declarator = declarator.base
680 declarator.base = self.base_type.array_declarator
681 base_type = base_type.base_type
682 return self.declarator.analyse(base_type, env, nonempty = nonempty)
684 return self.name_declarator, self.type
686 def calculate_default_value_code(self, code):
687 if self.default_value is None:
689 if self.default.is_literal:
690 # will not output any code, just assign the result_code
691 self.default.generate_evaluation_code(code)
692 return self.type.cast_code(self.default.result())
693 self.default_value = code.get_argument_default_const(self.type)
694 return self.default_value
696 def annotate(self, code):
698 self.default.annotate(code)
701 class CBaseTypeNode(Node):
702 # Abstract base class for C base type nodes.
704 # Processing during analyse_declarations phase:
711 def analyse_as_type(self, env):
712 return self.analyse(env)
714 class CAnalysedBaseTypeNode(Node):
719 def analyse(self, env, could_be_name = False):
722 class CSimpleBaseTypeNode(CBaseTypeNode):
724 # module_path [string] Qualifying name components
725 # is_basic_c_type boolean
729 # is_self_arg boolean Is self argument of C method
730 # ##is_type_arg boolean Is type argument of class method
733 arg_name = None # in case the argument name was interpreted as a type
735 def analyse(self, env, could_be_name = False):
736 # Return type descriptor.
737 #print "CSimpleBaseTypeNode.analyse: is_self_arg =", self.is_self_arg ###
739 if self.is_basic_c_type:
740 type = PyrexTypes.simple_c_type(self.signed, self.longness, self.name)
742 error(self.pos, "Unrecognised type modifier combination")
743 elif self.name == "object" and not self.module_path:
744 type = py_object_type
745 elif self.name is None:
746 if self.is_self_arg and env.is_c_class_scope:
747 #print "CSimpleBaseTypeNode.analyse: defaulting to parent type" ###
748 type = env.parent_type
749 ## elif self.is_type_arg and env.is_c_class_scope:
750 ## type = Builtin.type_type
752 type = py_object_type
755 scope = env.find_imported_module(self.module_path, self.pos)
759 if scope.is_c_class_scope:
760 scope = scope.global_scope()
761 entry = scope.lookup(self.name)
762 if entry and entry.is_type:
765 if self.is_self_arg and env.is_c_class_scope:
766 type = env.parent_type
767 ## elif self.is_type_arg and env.is_c_class_scope:
768 ## type = Builtin.type_type
770 type = py_object_type
771 self.arg_name = self.name
774 if not self.name in self.templates:
775 error(self.pos, "'%s' is not a type identifier" % self.name)
776 type = PyrexTypes.TemplatePlaceholderType(self.name)
778 error(self.pos, "'%s' is not a type identifier" % self.name)
780 if not type.is_numeric or type.is_complex:
781 error(self.pos, "can only complexify c numeric types")
782 type = PyrexTypes.CComplexType(type)
783 type.create_declaration_utility_code(env)
787 return PyrexTypes.error_type
789 class CNestedBaseTypeNode(CBaseTypeNode):
790 # For C++ classes that live inside other C++ classes.
793 # base_type CBaseTypeNode
795 child_attrs = ['base_type']
797 def analyse(self, env, could_be_name = None):
798 base_type = self.base_type.analyse(env)
799 if base_type is PyrexTypes.error_type:
800 return PyrexTypes.error_type
801 if not base_type.is_cpp_class:
802 error(self.pos, "'%s' is not a valid type scope" % base_type)
803 return PyrexTypes.error_type
804 type_entry = base_type.scope.lookup_here(self.name)
805 if not type_entry or not type_entry.is_type:
806 error(self.pos, "'%s.%s' is not a type identifier" % (base_type, self.name))
807 return PyrexTypes.error_type
808 return type_entry.type
810 class TemplatedTypeNode(CBaseTypeNode):
812 # positional_args [ExprNode] List of positional arguments
813 # keyword_args DictNode Keyword arguments
814 # base_type_node CBaseTypeNode
817 # type PyrexTypes.BufferType or PyrexTypes.CppClassType ...containing the right options
820 child_attrs = ["base_type_node", "positional_args",
821 "keyword_args", "dtype_node"]
827 def analyse(self, env, could_be_name = False, base_type = None):
828 if base_type is None:
829 base_type = self.base_type_node.analyse(env)
830 if base_type.is_error: return base_type
832 if base_type.is_cpp_class:
834 if self.keyword_args and self.keyword_args.key_value_pairs:
835 error(self.pos, "c++ templates cannot take keyword arguments");
836 self.type = PyrexTypes.error_type
839 for template_node in self.positional_args:
840 type = template_node.analyse_as_type(env)
842 error(template_node.pos, "unknown type in template argument")
844 template_types.append(type)
845 self.type = base_type.specialize_here(self.pos, template_types)
847 elif base_type.is_pyobject:
851 options = Buffer.analyse_buffer_options(
854 self.positional_args,
856 base_type.buffer_defaults)
858 if sys.version_info[0] < 3:
859 # Py 2.x enforces byte strings as keyword arguments ...
860 options = dict([ (name.encode('ASCII'), value)
861 for name, value in options.iteritems() ])
863 self.type = PyrexTypes.BufferType(base_type, **options)
867 empty_declarator = CNameDeclaratorNode(self.pos, name="", cname=None)
868 if len(self.positional_args) > 1 or self.keyword_args.key_value_pairs:
869 error(self.pos, "invalid array declaration")
870 self.type = PyrexTypes.error_type
872 # It would be nice to merge this class with CArrayDeclaratorNode,
873 # but arrays are part of the declaration, not the type...
874 if not self.positional_args:
877 dimension = self.positional_args[0]
878 self.array_declarator = CArrayDeclaratorNode(self.pos,
879 base = empty_declarator,
880 dimension = dimension)
881 self.type = self.array_declarator.analyse(base_type, env)[1]
885 class CComplexBaseTypeNode(CBaseTypeNode):
886 # base_type CBaseTypeNode
887 # declarator CDeclaratorNode
889 child_attrs = ["base_type", "declarator"]
891 def analyse(self, env, could_be_name = False):
892 base = self.base_type.analyse(env, could_be_name)
893 _, type = self.declarator.analyse(base, env)
897 class CVarDefNode(StatNode):
898 # C variable definition or forward/extern function declaration.
900 # visibility 'private' or 'public' or 'extern'
901 # base_type CBaseTypeNode
902 # declarators [CDeclaratorNode]
906 # decorators [cython.locals(...)] or None
907 # directive_locals { string : NameNode } locals defined by cython.locals(...)
909 child_attrs = ["base_type", "declarators"]
912 directive_locals = {}
914 def analyse_declarations(self, env, dest_scope = None):
917 self.dest_scope = dest_scope
918 base_type = self.base_type.analyse(env)
920 # If the field is an external typedef, we cannot be sure about the type,
921 # so do conversion ourself rather than rely on the CPython mechanism (through
922 # a property; made in AnalyseDeclarationsTransform).
923 if (dest_scope.is_c_class_scope
924 and self.visibility in ('public', 'readonly')):
927 need_property = False
928 visibility = self.visibility
930 for declarator in self.declarators:
931 name_declarator, type = declarator.analyse(base_type, env)
932 if not type.is_complete():
933 if not (self.visibility == 'extern' and type.is_array):
934 error(declarator.pos,
935 "Variable type '%s' is incomplete" % type)
936 if self.visibility == 'extern' and type.is_pyobject:
937 error(declarator.pos,
938 "Python object cannot be declared extern")
939 name = name_declarator.name
940 cname = name_declarator.cname
942 error(declarator.pos, "Missing name in declaration.")
944 if type.is_cfunction:
945 entry = dest_scope.declare_cfunction(name, type, declarator.pos,
946 cname = cname, visibility = self.visibility, in_pxd = self.in_pxd,
948 if entry is not None:
949 entry.directive_locals = self.directive_locals
951 if self.directive_locals:
952 s.error("Decorators can only be followed by functions")
953 if self.in_pxd and self.visibility != 'extern':
955 "Only 'extern' C variable declaration allowed in .pxd file")
956 entry = dest_scope.declare_var(name, type, declarator.pos,
957 cname = cname, visibility = visibility, is_cdef = 1)
958 entry.needs_property = need_property
961 class CStructOrUnionDefNode(StatNode):
963 # cname string or None
964 # kind "struct" or "union"
965 # typedef_flag boolean
966 # visibility "public" or "private"
968 # attributes [CVarDefNode] or None
972 child_attrs = ["attributes"]
974 def analyse_declarations(self, env):
976 if self.visibility == 'extern' and self.packed:
977 error(self.pos, "Cannot declare extern struct as 'packed'")
978 if self.attributes is not None:
979 scope = StructOrUnionScope(self.name)
980 self.entry = env.declare_struct_or_union(
981 self.name, self.kind, scope, self.typedef_flag, self.pos,
982 self.cname, visibility = self.visibility, packed = self.packed)
983 if self.attributes is not None:
984 if self.in_pxd and not env.in_cinclude:
985 self.entry.defined_in_pxd = 1
986 for attr in self.attributes:
987 attr.analyse_declarations(env, scope)
988 if self.visibility != 'extern':
989 need_typedef_indirection = False
990 for attr in scope.var_entries:
993 type = type.base_type
994 if type == self.entry.type:
995 error(attr.pos, "Struct cannot contain itself as a member.")
996 if self.typedef_flag:
998 type = type.base_type
999 if type == self.entry.type:
1000 need_typedef_indirection = True
1001 if need_typedef_indirection:
1002 # C can't handle typedef structs that refer to themselves.
1003 struct_entry = self.entry
1004 self.entry = env.declare_typedef(
1005 self.name, struct_entry.type, self.pos,
1006 cname = self.cname, visibility='ignore')
1007 struct_entry.type.typedef_flag = False
1008 # FIXME: this might be considered a hack ;-)
1009 struct_entry.cname = struct_entry.type.cname = \
1010 '_' + self.entry.type.typedef_cname
1012 def analyse_expressions(self, env):
1015 def generate_execution_code(self, code):
1019 class CppClassNode(CStructOrUnionDefNode):
1022 # cname string or None
1023 # visibility "extern"
1025 # attributes [CVarDefNode] or None
1027 # base_classes [string]
1028 # templates [string] or None
1030 def analyse_declarations(self, env):
1032 if self.attributes is not None:
1033 scope = CppClassScope(self.name, env)
1034 base_class_types = []
1035 for base_class_name in self.base_classes:
1036 base_class_entry = env.lookup(base_class_name)
1037 if base_class_entry is None:
1038 error(self.pos, "'%s' not found" % base_class_name)
1039 elif not base_class_entry.is_type or not base_class_entry.type.is_cpp_class:
1040 error(self.pos, "'%s' is not a cpp class type" % base_class_name)
1042 base_class_types.append(base_class_entry.type)
1043 if self.templates is None:
1044 template_types = None
1046 template_types = [PyrexTypes.TemplatePlaceholderType(template_name) for template_name in self.templates]
1047 self.entry = env.declare_cpp_class(
1048 self.name, scope, self.pos,
1049 self.cname, base_class_types, visibility = self.visibility, templates = template_types)
1050 self.entry.is_cpp_class = 1
1051 if self.attributes is not None:
1052 if self.in_pxd and not env.in_cinclude:
1053 self.entry.defined_in_pxd = 1
1054 for attr in self.attributes:
1055 attr.analyse_declarations(scope)
1057 class CEnumDefNode(StatNode):
1058 # name string or None
1059 # cname string or None
1060 # items [CEnumDefItemNode]
1061 # typedef_flag boolean
1062 # visibility "public" or "private"
1066 child_attrs = ["items"]
1068 def analyse_declarations(self, env):
1069 self.entry = env.declare_enum(self.name, self.pos,
1070 cname = self.cname, typedef_flag = self.typedef_flag,
1071 visibility = self.visibility)
1072 if self.items is not None:
1073 if self.in_pxd and not env.in_cinclude:
1074 self.entry.defined_in_pxd = 1
1075 for item in self.items:
1076 item.analyse_declarations(env, self.entry)
1078 def analyse_expressions(self, env):
1081 def generate_execution_code(self, code):
1082 if self.visibility == 'public':
1083 temp = code.funcstate.allocate_temp(PyrexTypes.py_object_type, manage_ref=True)
1084 for item in self.entry.enum_values:
1085 code.putln("%s = PyInt_FromLong(%s); %s" % (
1088 code.error_goto_if_null(temp, item.pos)))
1089 code.put_gotref(temp)
1090 code.putln('if (__Pyx_SetAttrString(%s, "%s", %s) < 0) %s' % (
1091 Naming.module_cname,
1094 code.error_goto(item.pos)))
1095 code.put_decref_clear(temp, PyrexTypes.py_object_type)
1096 code.funcstate.release_temp(temp)
1099 class CEnumDefItemNode(StatNode):
1101 # cname string or None
1102 # value ExprNode or None
1104 child_attrs = ["value"]
1106 def analyse_declarations(self, env, enum_entry):
1108 self.value.analyse_const_expression(env)
1109 if not self.value.type.is_int:
1110 self.value = self.value.coerce_to(PyrexTypes.c_int_type, env)
1111 self.value.analyse_const_expression(env)
1112 entry = env.declare_const(self.name, enum_entry.type,
1113 self.value, self.pos, cname = self.cname,
1114 visibility = enum_entry.visibility)
1115 enum_entry.enum_values.append(entry)
1118 class CTypeDefNode(StatNode):
1119 # base_type CBaseTypeNode
1120 # declarator CDeclaratorNode
1121 # visibility "public" or "private"
1124 child_attrs = ["base_type", "declarator"]
1126 def analyse_declarations(self, env):
1127 base = self.base_type.analyse(env)
1128 name_declarator, type = self.declarator.analyse(base, env)
1129 name = name_declarator.name
1130 cname = name_declarator.cname
1131 entry = env.declare_typedef(name, type, self.pos,
1132 cname = cname, visibility = self.visibility)
1133 if self.in_pxd and not env.in_cinclude:
1134 entry.defined_in_pxd = 1
1136 def analyse_expressions(self, env):
1138 def generate_execution_code(self, code):
1142 class FuncDefNode(StatNode, BlockNode):
1143 # Base class for function definition nodes.
1145 # return_type PyrexType
1146 # #filename string C name of filename string const
1147 # entry Symtab.Entry
1148 # needs_closure boolean Whether or not this function has inner functions/classes/yield
1149 # directive_locals { string : NameNode } locals defined by cython.locals(...)
1153 needs_closure = False
1156 def analyse_default_values(self, env):
1157 genv = env.global_scope()
1159 for arg in self.args:
1163 arg.default.analyse_types(env)
1164 arg.default = arg.default.coerce_to(arg.type, genv)
1167 "This argument cannot have a default value")
1172 error(arg.pos, "Non-default argument following default argument")
1174 def need_gil_acquisition(self, lenv):
1177 def create_local_scope(self, env):
1179 while genv.is_py_class_scope or genv.is_c_class_scope:
1180 genv = env.outer_scope
1181 if self.needs_closure:
1182 lenv = ClosureScope(name=self.entry.name,
1184 scope_name=self.entry.cname)
1186 lenv = LocalScope(name=self.entry.name,
1189 lenv.return_type = self.return_type
1190 type = self.entry.type
1191 if type.is_cfunction:
1192 lenv.nogil = type.nogil and not type.with_gil
1193 self.local_scope = lenv
1194 lenv.directives = env.directives
1197 def generate_function_definitions(self, env, code):
1200 lenv = self.local_scope
1201 if lenv.is_closure_scope:
1202 outer_scope_cname = "%s->%s" % (Naming.cur_scope_cname,
1203 Naming.outer_scope_cname)
1205 outer_scope_cname = Naming.outer_scope_cname
1206 lenv.mangle_closure_cnames(outer_scope_cname)
1207 # Generate closure function definitions
1208 self.body.generate_function_definitions(lenv, code)
1209 # generate lambda function definitions
1210 for node in lenv.lambda_defs:
1211 node.generate_function_definitions(lenv, code)
1213 is_getbuffer_slot = (self.entry.name == "__getbuffer__" and
1214 self.entry.scope.is_c_class_scope)
1215 is_releasebuffer_slot = (self.entry.name == "__releasebuffer__" and
1216 self.entry.scope.is_c_class_scope)
1217 is_buffer_slot = is_getbuffer_slot or is_releasebuffer_slot
1219 if 'cython_unused' not in self.modifiers:
1220 self.modifiers = self.modifiers + ['cython_unused']
1222 preprocessor_guard = None
1223 if self.entry.is_special and not is_buffer_slot:
1224 slot = TypeSlots.method_name_to_slot.get(self.entry.name)
1226 preprocessor_guard = slot.preprocessor_guard_code()
1227 if (self.entry.name == '__long__' and
1228 not self.entry.scope.lookup_here('__int__')):
1229 preprocessor_guard = None
1231 profile = code.globalstate.directives['profile']
1234 error(self.pos, "Cannot profile nogil function.")
1235 code.globalstate.use_utility_code(profile_utility_code)
1237 # Generate C code for header and body of function
1238 code.enter_cfunc_scope()
1239 code.return_from_error_cleanup_label = code.new_label()
1241 # ----- Top-level constants used by this function
1242 code.mark_pos(self.pos)
1243 self.generate_cached_builtins_decls(lenv, code)
1244 # ----- Function header
1247 if preprocessor_guard:
1248 code.putln(preprocessor_guard)
1250 with_pymethdef = self.needs_assignment_synthesis(env, code)
1252 self.py_func.generate_function_header(code,
1253 with_pymethdef = with_pymethdef,
1255 self.generate_function_header(code,
1256 with_pymethdef = with_pymethdef)
1257 # ----- Local variable declarations
1258 if lenv.is_closure_scope:
1259 code.put(lenv.scope_class.type.declaration_code(Naming.cur_scope_cname))
1261 elif env.is_closure_scope:
1262 code.put(env.scope_class.type.declaration_code(Naming.outer_scope_cname))
1264 self.generate_argument_declarations(lenv, code)
1265 for entry in lenv.var_entries:
1266 if not entry.in_closure:
1267 code.put_var_declaration(entry)
1269 if not self.return_type.is_void:
1270 if self.return_type.is_pyobject:
1274 (self.return_type.declaration_code(Naming.retval_cname),
1276 tempvardecl_code = code.insertion_point()
1277 self.generate_keyword_list(code)
1279 code.put_trace_declarations()
1280 # ----- Extern library function declarations
1281 lenv.generate_library_function_declarations(code)
1282 # ----- GIL acquisition
1283 acquire_gil = self.acquire_gil
1285 env.use_utility_code(force_init_threads_utility_code)
1286 code.putln("#ifdef WITH_THREAD")
1287 code.putln("PyGILState_STATE _save = PyGILState_Ensure();")
1288 code.putln("#endif")
1289 # ----- set up refnanny
1291 code.put_setup_refcount_context(self.entry.name)
1292 # ----- Automatic lead-ins for certain special functions
1293 if is_getbuffer_slot:
1294 self.getbuffer_init(code)
1295 # ----- Create closure scope object
1296 if self.needs_closure:
1297 code.putln("%s = (%s)%s->tp_new(%s, %s, NULL);" % (
1298 Naming.cur_scope_cname,
1299 lenv.scope_class.type.declaration_code(''),
1300 lenv.scope_class.type.typeptr_cname,
1301 lenv.scope_class.type.typeptr_cname,
1302 Naming.empty_tuple))
1303 code.putln("if (unlikely(!%s)) {" % Naming.cur_scope_cname)
1304 if is_getbuffer_slot:
1305 self.getbuffer_error_cleanup(code)
1307 code.put_finish_refcount_context()
1308 # FIXME: what if the error return value is a Python value?
1309 code.putln("return %s;" % self.error_value())
1311 code.put_gotref(Naming.cur_scope_cname)
1312 # Note that it is unsafe to decref the scope at this point.
1313 if env.is_closure_scope:
1314 code.putln("%s = (%s)%s;" % (
1316 env.scope_class.type.declaration_code(''),
1318 if self.needs_closure:
1319 # inner closures own a reference to their outer parent
1320 code.put_incref(outer_scope_cname, env.scope_class.type)
1321 code.put_giveref(outer_scope_cname)
1322 # ----- Trace function call
1324 # this looks a bit late, but if we don't get here due to a
1325 # fatal error before hand, it's not really worth tracing
1326 code.put_trace_call(self.entry.name, self.pos)
1327 # ----- Fetch arguments
1328 self.generate_argument_parsing_code(env, code)
1329 # If an argument is assigned to in the body, we must
1330 # incref it to properly keep track of refcounts.
1331 for entry in lenv.arg_entries:
1332 if entry.type.is_pyobject:
1333 if entry.assignments and not entry.in_closure:
1334 code.put_var_incref(entry)
1335 # ----- Initialise local variables
1336 for entry in lenv.var_entries:
1337 if entry.type.is_pyobject and entry.init_to_none and entry.used:
1338 code.put_init_var_to_py_none(entry)
1339 # ----- Initialise local buffer auxiliary variables
1340 for entry in lenv.var_entries + lenv.arg_entries:
1341 if entry.type.is_buffer and entry.buffer_aux.buffer_info_var.used:
1342 code.putln("%s.buf = NULL;" %
1343 entry.buffer_aux.buffer_info_var.cname)
1344 # ----- Check and convert arguments
1345 self.generate_argument_type_tests(code)
1346 # ----- Acquire buffer arguments
1347 for entry in lenv.arg_entries:
1348 if entry.type.is_buffer:
1349 Buffer.put_acquire_arg_buffer(entry, code, self.pos)
1351 # -------------------------
1352 # ----- Function body -----
1353 # -------------------------
1354 self.body.generate_execution_code(code)
1356 # ----- Default return value
1358 if self.return_type.is_pyobject:
1359 #if self.return_type.is_extension_type:
1360 # lhs = "(PyObject *)%s" % Naming.retval_cname
1362 lhs = Naming.retval_cname
1363 code.put_init_to_py_none(lhs, self.return_type)
1365 val = self.return_type.default_value
1367 code.putln("%s = %s;" % (Naming.retval_cname, val))
1368 # ----- Error cleanup
1369 if code.error_label in code.labels_used:
1370 code.put_goto(code.return_label)
1371 code.put_label(code.error_label)
1372 for cname, type in code.funcstate.all_managed_temps():
1373 code.put_xdecref(cname, type)
1375 # Clean up buffers -- this calls a Python function
1376 # so need to save and restore error state
1377 buffers_present = len(lenv.buffer_entries) > 0
1379 code.globalstate.use_utility_code(restore_exception_utility_code)
1380 code.putln("{ PyObject *__pyx_type, *__pyx_value, *__pyx_tb;")
1381 code.putln("__Pyx_ErrFetch(&__pyx_type, &__pyx_value, &__pyx_tb);")
1382 for entry in lenv.buffer_entries:
1383 Buffer.put_release_buffer_code(code, entry)
1384 #code.putln("%s = 0;" % entry.cname)
1385 code.putln("__Pyx_ErrRestore(__pyx_type, __pyx_value, __pyx_tb);}")
1387 err_val = self.error_value()
1388 exc_check = self.caller_will_check_exceptions()
1389 if err_val is not None or exc_check:
1390 # TODO: Fix exception tracing (though currently unused by cProfile).
1391 # code.globalstate.use_utility_code(get_exception_tuple_utility_code)
1392 # code.put_trace_exception()
1393 code.putln('__Pyx_AddTraceback("%s");' % self.entry.qualified_name)
1395 warning(self.entry.pos, "Unraisable exception in function '%s'." \
1396 % self.entry.qualified_name, 0)
1398 '__Pyx_WriteUnraisable("%s");' %
1399 self.entry.qualified_name)
1400 env.use_utility_code(unraisable_exception_utility_code)
1401 env.use_utility_code(restore_exception_utility_code)
1402 default_retval = self.return_type.default_value
1403 if err_val is None and default_retval:
1404 err_val = default_retval
1405 if err_val is not None:
1406 code.putln("%s = %s;" % (Naming.retval_cname, err_val))
1408 if is_getbuffer_slot:
1409 self.getbuffer_error_cleanup(code)
1411 # If we are using the non-error cleanup section we should
1412 # jump past it if we have an error. The if-test below determine
1413 # whether this section is used.
1414 if buffers_present or is_getbuffer_slot:
1415 code.put_goto(code.return_from_error_cleanup_label)
1418 # ----- Non-error return cleanup
1419 code.put_label(code.return_label)
1420 for entry in lenv.buffer_entries:
1422 Buffer.put_release_buffer_code(code, entry)
1423 if is_getbuffer_slot:
1424 self.getbuffer_normal_cleanup(code)
1425 # ----- Return cleanup for both error and no-error return
1426 code.put_label(code.return_from_error_cleanup_label)
1427 if not Options.init_local_none:
1428 for entry in lenv.var_entries:
1429 if lenv.control_flow.get_state((entry.name, 'initialized')) is not True:
1430 entry.xdecref_cleanup = 1
1432 for entry in lenv.var_entries:
1433 if entry.type.is_pyobject:
1434 if entry.used and not entry.in_closure:
1435 code.put_var_decref(entry)
1436 elif entry.in_closure and self.needs_closure:
1437 code.put_giveref(entry.cname)
1438 # Decref any increfed args
1439 for entry in lenv.arg_entries:
1440 if entry.type.is_pyobject:
1441 if entry.in_closure:
1442 code.put_var_giveref(entry)
1443 elif entry.assignments:
1444 code.put_var_decref(entry)
1445 if self.needs_closure:
1446 code.put_decref(Naming.cur_scope_cname, lenv.scope_class.type)
1449 # This code is duplicated in ModuleNode.generate_module_init_func
1451 default_retval = self.return_type.default_value
1452 err_val = self.error_value()
1453 if err_val is None and default_retval:
1454 err_val = default_retval
1455 if self.return_type.is_pyobject:
1456 code.put_xgiveref(self.return_type.as_pyobject(Naming.retval_cname))
1458 if self.entry.is_special and self.entry.name == "__hash__":
1459 # Returning -1 for __hash__ is supposed to signal an error
1460 # We do as Python instances and coerce -1 into -2.
1461 code.putln("if (unlikely(%s == -1) && !PyErr_Occurred()) %s = -2;" % (
1462 Naming.retval_cname, Naming.retval_cname))
1465 if self.return_type.is_pyobject:
1466 code.put_trace_return(Naming.retval_cname)
1468 code.put_trace_return("Py_None")
1470 code.put_finish_refcount_context()
1473 code.putln("#ifdef WITH_THREAD")
1474 code.putln("PyGILState_Release(_save);")
1475 code.putln("#endif")
1477 if not self.return_type.is_void:
1478 code.putln("return %s;" % Naming.retval_cname)
1482 if preprocessor_guard:
1483 code.putln("#endif /*!(%s)*/" % preprocessor_guard)
1485 # ----- Go back and insert temp variable declarations
1486 tempvardecl_code.put_temp_declarations(code.funcstate)
1487 # ----- Python version
1488 code.exit_cfunc_scope()
1490 self.py_func.generate_function_definitions(env, code)
1491 self.generate_wrapper_functions(code)
1493 def declare_argument(self, env, arg):
1494 if arg.type.is_void:
1495 error(arg.pos, "Invalid use of 'void'")
1496 elif not arg.type.is_complete() and not arg.type.is_array:
1498 "Argument type '%s' is incomplete" % arg.type)
1499 return env.declare_arg(arg.name, arg.type, arg.pos)
1501 def generate_arg_type_test(self, arg, code):
1502 # Generate type test for one argument.
1503 if arg.type.typeobj_is_available():
1504 code.globalstate.use_utility_code(arg_type_test_utility_code)
1505 typeptr_cname = arg.type.typeptr_cname
1506 arg_code = "((PyObject *)%s)" % arg.entry.cname
1508 'if (unlikely(!__Pyx_ArgTypeTest(%s, %s, %d, "%s", %s))) %s' % (
1513 arg.type.is_builtin_type,
1514 code.error_goto(arg.pos)))
1516 error(arg.pos, "Cannot test type of extern C class "
1517 "without type object name specification")
1519 def generate_arg_none_check(self, arg, code):
1520 # Generate None check for one argument.
1521 code.globalstate.use_utility_code(arg_type_test_utility_code)
1522 code.putln('if (unlikely(((PyObject *)%s) == Py_None)) {' % arg.entry.cname)
1523 code.putln('''PyErr_Format(PyExc_TypeError, "Argument '%s' must not be None"); %s''' % (
1525 code.error_goto(arg.pos)))
1528 def generate_wrapper_functions(self, code):
1531 def generate_execution_code(self, code):
1532 # Evaluate and store argument default values
1533 for arg in self.args:
1534 default = arg.default
1536 if not default.is_literal:
1537 default.generate_evaluation_code(code)
1538 default.make_owned_reference(code)
1539 result = default.result_as(arg.type)
1542 arg.calculate_default_value_code(code),
1544 if arg.type.is_pyobject:
1545 code.put_giveref(default.result())
1546 default.generate_post_assignment_code(code)
1547 default.free_temps(code)
1548 # For Python class methods, create and store function object
1550 self.assmt.generate_execution_code(code)
1553 # Special code for the __getbuffer__ function
1555 def getbuffer_init(self, code):
1556 info = self.local_scope.arg_entries[1].cname
1557 # Python 3.0 betas have a bug in memoryview which makes it call
1558 # getbuffer with a NULL parameter. For now we work around this;
1559 # the following line should be removed when this bug is fixed.
1560 code.putln("if (%s == NULL) return 0;" % info)
1561 code.putln("%s->obj = Py_None; __Pyx_INCREF(Py_None);" % info)
1562 code.put_giveref("%s->obj" % info) # Do not refnanny object within structs
1564 def getbuffer_error_cleanup(self, code):
1565 info = self.local_scope.arg_entries[1].cname
1566 code.put_gotref("%s->obj" % info)
1567 code.putln("__Pyx_DECREF(%s->obj); %s->obj = NULL;" %
1570 def getbuffer_normal_cleanup(self, code):
1571 info = self.local_scope.arg_entries[1].cname
1572 code.putln("if (%s->obj == Py_None) {" % info)
1573 code.put_gotref("Py_None")
1574 code.putln("__Pyx_DECREF(Py_None); %s->obj = NULL;" % info)
1577 class CFuncDefNode(FuncDefNode):
1578 # C function definition.
1580 # modifiers ['inline']
1581 # visibility 'private' or 'public' or 'extern'
1582 # base_type CBaseTypeNode
1583 # declarator CDeclaratorNode
1586 # decorators [DecoratorNode] list of decorators
1588 # with_gil boolean Acquire GIL around body
1590 # py_func wrapper for calling from Python
1591 # overridable whether or not this is a cpdef function
1592 # inline_in_pxd whether this is an inline function in a pxd file
1594 child_attrs = ["base_type", "declarator", "body", "py_func"]
1596 inline_in_pxd = False
1598 directive_locals = {}
1600 def unqualified_name(self):
1601 return self.entry.name
1603 def analyse_declarations(self, env):
1604 self.directive_locals.update(env.directives['locals'])
1605 base_type = self.base_type.analyse(env)
1606 # The 2 here is because we need both function and argument names.
1607 name_declarator, type = self.declarator.analyse(base_type, env, nonempty = 2 * (self.body is not None))
1608 if not type.is_cfunction:
1610 "Suite attached to non-function declaration")
1611 # Remember the actual type according to the function header
1612 # written here, because the type in the symbol table entry
1613 # may be different if we're overriding a C method inherited
1614 # from the base type of an extension type.
1616 type.is_overridable = self.overridable
1617 declarator = self.declarator
1618 while not hasattr(declarator, 'args'):
1619 declarator = declarator.base
1620 self.args = declarator.args
1621 for formal_arg, type_arg in zip(self.args, type.args):
1622 formal_arg.type = type_arg.type
1623 formal_arg.name = type_arg.name
1624 formal_arg.cname = type_arg.cname
1625 name = name_declarator.name
1626 cname = name_declarator.cname
1627 self.entry = env.declare_cfunction(
1628 name, type, self.pos,
1629 cname = cname, visibility = self.visibility,
1630 defining = self.body is not None,
1631 api = self.api, modifiers = self.modifiers)
1632 self.entry.inline_func_in_pxd = self.inline_in_pxd
1633 self.return_type = type.return_type
1635 if self.overridable and not env.is_module_scope:
1636 if len(self.args) < 1 or not self.args[0].type.is_pyobject:
1637 # An error will be produced in the cdef function
1638 self.overridable = False
1640 if self.overridable:
1642 py_func_body = self.call_self_node(is_module_scope = env.is_module_scope)
1643 self.py_func = DefNode(pos = self.pos,
1644 name = self.entry.name,
1647 starstar_arg = None,
1649 body = py_func_body,
1651 self.py_func.is_module_scope = env.is_module_scope
1652 self.py_func.analyse_declarations(env)
1653 self.entry.as_variable = self.py_func.entry
1654 # Reset scope entry the above cfunction
1655 env.entries[name] = self.entry
1656 if not env.is_module_scope or Options.lookup_module_cpdef:
1657 self.override = OverrideCheckNode(self.pos, py_func = self.py_func)
1658 self.body = StatListNode(self.pos, stats=[self.override, self.body])
1659 self.create_local_scope(env)
1661 def call_self_node(self, omit_optional_args=0, is_module_scope=0):
1663 args = self.type.args
1664 if omit_optional_args:
1665 args = args[:len(args) - self.type.optional_arg_count]
1666 arg_names = [arg.name for arg in args]
1668 cfunc = ExprNodes.NameNode(self.pos, name=self.entry.name)
1670 self_arg = ExprNodes.NameNode(self.pos, name=arg_names[0])
1671 cfunc = ExprNodes.AttributeNode(self.pos, obj=self_arg, attribute=self.entry.name)
1672 skip_dispatch = not is_module_scope or Options.lookup_module_cpdef
1673 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)
1674 return ReturnStatNode(pos=self.pos, return_type=PyrexTypes.py_object_type, value=c_call)
1676 def declare_arguments(self, env):
1677 for arg in self.type.args:
1679 error(arg.pos, "Missing argument name")
1680 self.declare_argument(env, arg)
1682 def need_gil_acquisition(self, lenv):
1683 return self.type.with_gil
1685 def nogil_check(self, env):
1687 with_gil = type.with_gil
1688 if type.nogil and not with_gil:
1689 if type.return_type.is_pyobject:
1691 "Function with Python return type cannot be declared nogil")
1692 for entry in self.local_scope.var_entries:
1693 if entry.type.is_pyobject:
1694 error(self.pos, "Function declared nogil has Python locals or temporaries")
1696 def analyse_expressions(self, env):
1697 self.local_scope.directives = env.directives
1698 if self.py_func is not None:
1699 # this will also analyse the default values
1700 self.py_func.analyse_expressions(env)
1702 self.analyse_default_values(env)
1703 self.acquire_gil = self.need_gil_acquisition(self.local_scope)
1705 def needs_assignment_synthesis(self, env, code=None):
1708 def generate_function_header(self, code, with_pymethdef, with_opt_args = 1, with_dispatch = 1, cname = None):
1711 visibility = self.entry.visibility
1712 for arg in type.args[:len(type.args)-type.optional_arg_count]:
1713 arg_decls.append(arg.declaration_code())
1714 if with_dispatch and self.overridable:
1715 arg_decls.append(PyrexTypes.c_int_type.declaration_code(Naming.skip_dispatch_cname))
1716 if type.optional_arg_count and with_opt_args:
1717 arg_decls.append(type.op_arg_struct.declaration_code(Naming.optional_args_cname))
1718 if type.has_varargs:
1719 arg_decls.append("...")
1721 arg_decls = ["void"]
1723 cname = self.entry.func_cname
1724 entity = type.function_header_code(cname, ', '.join(arg_decls))
1725 if visibility == 'public':
1726 dll_linkage = "DL_EXPORT"
1729 header = self.return_type.declaration_code(entity,
1730 dll_linkage = dll_linkage)
1731 if visibility == 'extern':
1732 storage_class = "%s " % Naming.extern_c_macro
1733 elif visibility == 'public':
1736 storage_class = "static "
1737 if 'inline' in self.modifiers:
1738 self.modifiers[self.modifiers.index('inline')] = 'cython_inline'
1739 code.putln("%s%s %s {" % (
1741 ' '.join(self.modifiers).upper(), # macro forms
1744 def generate_argument_declarations(self, env, code):
1745 for arg in self.args:
1747 result = arg.calculate_default_value_code(code)
1748 code.putln('%s = %s;' % (
1749 arg.type.declaration_code(arg.cname), result))
1751 def generate_keyword_list(self, code):
1754 def generate_argument_parsing_code(self, env, code):
1756 if self.type.optional_arg_count:
1757 code.putln('if (%s) {' % Naming.optional_args_cname)
1758 for arg in self.args:
1760 code.putln('if (%s->%sn > %s) {' % (Naming.optional_args_cname, Naming.pyrex_prefix, i))
1761 declarator = arg.declarator
1762 while not hasattr(declarator, 'name'):
1763 declarator = declarator.base
1764 code.putln('%s = %s->%s;' % (arg.cname, Naming.optional_args_cname, self.type.opt_arg_cname(declarator.name)))
1766 for _ in range(self.type.optional_arg_count):
1770 def generate_argument_conversion_code(self, code):
1773 def generate_argument_type_tests(self, code):
1774 # Generate type tests for args whose type in a parent
1775 # class is a supertype of the declared type.
1776 for arg in self.type.args:
1777 if arg.needs_type_test:
1778 self.generate_arg_type_test(arg, code)
1779 elif arg.type.is_pyobject and not arg.accept_none:
1780 self.generate_arg_none_check(arg, code)
1782 def error_value(self):
1783 if self.return_type.is_pyobject:
1787 return self.entry.type.exception_value
1789 def caller_will_check_exceptions(self):
1790 return self.entry.type.exception_check
1792 def generate_wrapper_functions(self, code):
1793 # If the C signature of a function has changed, we need to generate
1794 # wrappers to put in the slots here.
1797 func_type = entry.type
1798 while entry.prev_entry is not None:
1800 entry = entry.prev_entry
1801 entry.func_cname = "%s%swrap_%s" % (self.entry.func_cname, Naming.pyrex_prefix, k)
1803 self.generate_function_header(code,
1805 with_dispatch = entry.type.is_overridable,
1806 with_opt_args = entry.type.optional_arg_count,
1807 cname = entry.func_cname)
1808 if not self.return_type.is_void:
1810 args = self.type.args
1811 arglist = [arg.cname for arg in args[:len(args)-self.type.optional_arg_count]]
1812 if entry.type.is_overridable:
1813 arglist.append(Naming.skip_dispatch_cname)
1814 elif func_type.is_overridable:
1816 if entry.type.optional_arg_count:
1817 arglist.append(Naming.optional_args_cname)
1818 elif func_type.optional_arg_count:
1819 arglist.append('NULL')
1820 code.putln('%s(%s);' % (self.entry.func_cname, ', '.join(arglist)))
1824 class PyArgDeclNode(Node):
1825 # Argument which must be a Python object (used
1826 # for * and ** arguments).
1829 # entry Symtab.Entry
1830 # annotation ExprNode or None Py3 argument annotation
1833 def generate_function_definitions(self, env, code):
1834 self.entry.generate_function_definitions(env, code)
1836 class DecoratorNode(Node):
1839 # decorator NameNode or CallNode or AttributeNode
1840 child_attrs = ['decorator']
1843 class DefNode(FuncDefNode):
1844 # A Python function definition.
1846 # name string the Python name of the function
1847 # lambda_name string the internal name of a lambda 'function'
1848 # decorators [DecoratorNode] list of decorators
1849 # args [CArgDeclNode] formal arguments
1850 # star_arg PyArgDeclNode or None * argument
1851 # starstar_arg PyArgDeclNode or None ** argument
1852 # doc EncodedString or None
1854 # return_type_annotation
1855 # ExprNode or None the Py3 return type annotation
1857 # The following subnode is constructed internally
1858 # when the def statement is inside a Python class definition.
1860 # assmt AssignmentNode Function construction/assignment
1862 child_attrs = ["args", "star_arg", "starstar_arg", "body", "decorators"]
1867 num_required_kw_args = 0
1868 reqd_kw_flags_cname = "0"
1871 return_type_annotation = None
1876 def __init__(self, pos, **kwds):
1877 FuncDefNode.__init__(self, pos, **kwds)
1879 for arg in self.args:
1886 self.num_kwonly_args = k
1887 self.num_required_kw_args = rk
1888 self.num_required_args = r
1890 def as_cfunction(self, cfunc=None, scope=None):
1892 error(self.star_arg.pos, "cdef function cannot have star argument")
1893 if self.starstar_arg:
1894 error(self.starstar_arg.pos, "cdef function cannot have starstar argument")
1897 for formal_arg in self.args:
1898 name_declarator, type = formal_arg.analyse(scope, nonempty=1)
1899 cfunc_args.append(PyrexTypes.CFuncTypeArg(name = name_declarator.name,
1901 type = py_object_type,
1902 pos = formal_arg.pos))
1903 cfunc_type = PyrexTypes.CFuncType(return_type = py_object_type,
1905 has_varargs = False,
1906 exception_value = None,
1907 exception_check = False,
1910 is_overridable = True)
1911 cfunc = CVarDefNode(self.pos, type=cfunc_type)
1915 cfunc_type = cfunc.type
1916 if len(self.args) != len(cfunc_type.args) or cfunc_type.has_varargs:
1917 error(self.pos, "wrong number of arguments")
1918 error(cfunc.pos, "previous declaration here")
1919 for i, (formal_arg, type_arg) in enumerate(zip(self.args, cfunc_type.args)):
1920 name_declarator, type = formal_arg.analyse(scope, nonempty=1,
1921 is_self_arg = (i == 0 and scope.is_c_class_scope))
1922 if type is None or type is PyrexTypes.py_object_type:
1923 formal_arg.type = type_arg.type
1924 formal_arg.name_declarator = name_declarator
1926 if cfunc_type.exception_value is None:
1927 exception_value = None
1929 exception_value = ExprNodes.ConstNode(self.pos, value=cfunc_type.exception_value, type=cfunc_type.return_type)
1930 declarator = CFuncDeclaratorNode(self.pos,
1931 base = CNameDeclaratorNode(self.pos, name=self.name, cname=None),
1933 has_varargs = False,
1934 exception_check = cfunc_type.exception_check,
1935 exception_value = exception_value,
1936 with_gil = cfunc_type.with_gil,
1937 nogil = cfunc_type.nogil)
1938 return CFuncDefNode(self.pos,
1940 base_type = CAnalysedBaseTypeNode(self.pos, type=cfunc_type.return_type),
1941 declarator = declarator,
1944 overridable = cfunc_type.is_overridable,
1946 with_gil = cfunc_type.with_gil,
1947 nogil = cfunc_type.nogil,
1948 visibility = 'private',
1950 directive_locals = getattr(cfunc, 'directive_locals', {}))
1952 def analyse_declarations(self, env):
1953 self.is_classmethod = self.is_staticmethod = False
1955 for decorator in self.decorators:
1956 func = decorator.decorator
1958 self.is_classmethod |= func.name == 'classmethod'
1959 self.is_staticmethod |= func.name == 'staticmethod'
1961 if self.is_classmethod and env.lookup_here('classmethod'):
1962 # classmethod() was overridden - not much we can do here ...
1963 self.is_classmethod = False
1964 if self.is_staticmethod and env.lookup_here('staticmethod'):
1965 # staticmethod() was overridden - not much we can do here ...
1966 self.is_staticmethod = False
1968 if self.name == '__new__':
1969 self.is_staticmethod = 1
1971 self.analyse_argument_types(env)
1972 if self.name == '<lambda>':
1973 self.declare_lambda_function(env)
1975 self.declare_pyfunction(env)
1976 self.analyse_signature(env)
1977 self.return_type = self.entry.signature.return_type()
1978 self.create_local_scope(env)
1980 def analyse_argument_types(self, env):
1981 directive_locals = self.directive_locals = env.directives['locals']
1982 allow_none_for_extension_args = env.directives['allow_none_for_extension_args']
1983 for arg in self.args:
1984 if hasattr(arg, 'name'):
1986 name_declarator = None
1988 base_type = arg.base_type.analyse(env)
1989 name_declarator, type = \
1990 arg.declarator.analyse(base_type, env)
1991 arg.name = name_declarator.name
1992 if arg.name in directive_locals:
1993 type_node = directive_locals[arg.name]
1994 other_type = type_node.analyse_as_type(env)
1995 if other_type is None:
1996 error(type_node.pos, "Not a type")
1997 elif (type is not PyrexTypes.py_object_type
1998 and not type.same_as(other_type)):
1999 error(arg.base_type.pos, "Signature does not agree with previous declaration")
2000 error(type_node.pos, "Previous declaration here")
2003 if name_declarator and name_declarator.cname:
2005 "Python function argument cannot have C name specification")
2006 arg.type = type.as_argument_type()
2008 arg.needs_conversion = 0
2009 arg.needs_type_test = 0
2011 if arg.type.is_pyobject:
2013 arg.accept_none = True
2015 arg.accept_none = False
2016 elif arg.type.is_extension_type or arg.type.is_builtin_type:
2017 if arg.default and arg.default.constant_result is None:
2018 # special case: def func(MyType obj = None)
2019 arg.accept_none = True
2021 # default depends on compiler directive
2022 arg.accept_none = allow_none_for_extension_args
2024 # probably just a plain 'object'
2025 arg.accept_none = True
2027 arg.accept_none = True # won't be used, but must be there
2029 error(arg.pos, "Only Python type arguments can have 'not None'")
2031 error(arg.pos, "Only Python type arguments can have 'or None'")
2033 def analyse_signature(self, env):
2034 if self.entry.is_special:
2035 self.entry.trivial_signature = len(self.args) == 1 and not (self.star_arg or self.starstar_arg)
2036 elif not env.directives['always_allow_keywords'] and not (self.star_arg or self.starstar_arg):
2037 # Use the simpler calling signature for zero- and one-argument functions.
2038 if self.entry.signature is TypeSlots.pyfunction_signature:
2039 if len(self.args) == 0:
2040 self.entry.signature = TypeSlots.pyfunction_noargs
2041 elif len(self.args) == 1:
2042 if self.args[0].default is None and not self.args[0].kw_only:
2043 self.entry.signature = TypeSlots.pyfunction_onearg
2044 elif self.entry.signature is TypeSlots.pymethod_signature:
2045 if len(self.args) == 1:
2046 self.entry.signature = TypeSlots.unaryfunc
2047 elif len(self.args) == 2:
2048 if self.args[1].default is None and not self.args[1].kw_only:
2049 self.entry.signature = TypeSlots.ibinaryfunc
2051 sig = self.entry.signature
2052 nfixed = sig.num_fixed_args()
2053 if sig is TypeSlots.pymethod_signature and nfixed == 1 \
2054 and len(self.args) == 0 and self.star_arg:
2055 # this is the only case where a diverging number of
2056 # arguments is not an error - when we have no explicit
2057 # 'self' parameter as in method(*args)
2058 sig = self.entry.signature = TypeSlots.pyfunction_signature # self is not 'really' used
2059 self.self_in_stararg = 1
2062 for i in range(min(nfixed, len(self.args))):
2065 if sig.is_self_arg(i) and not self.is_staticmethod:
2066 if self.is_classmethod:
2068 arg.hdr_type = arg.type = Builtin.type_type
2071 arg.hdr_type = arg.type = env.parent_type
2072 arg.needs_conversion = 0
2074 arg.hdr_type = sig.fixed_arg_type(i)
2075 if not arg.type.same_as(arg.hdr_type):
2076 if arg.hdr_type.is_pyobject and arg.type.is_pyobject:
2077 arg.needs_type_test = 1
2079 arg.needs_conversion = 1
2080 if arg.needs_conversion:
2081 arg.hdr_cname = Naming.arg_prefix + arg.name
2083 arg.hdr_cname = Naming.var_prefix + arg.name
2085 if nfixed > len(self.args):
2086 self.bad_signature()
2088 elif nfixed < len(self.args):
2089 if not sig.has_generic_args:
2090 self.bad_signature()
2091 for arg in self.args:
2092 if arg.is_generic and \
2093 (arg.type.is_extension_type or arg.type.is_builtin_type):
2094 arg.needs_type_test = 1
2096 def bad_signature(self):
2097 sig = self.entry.signature
2098 expected_str = "%d" % sig.num_fixed_args()
2099 if sig.has_generic_args:
2100 expected_str = expected_str + " or more"
2102 if name.startswith("__") and name.endswith("__"):
2103 desc = "Special method"
2107 "%s %s has wrong number of arguments "
2108 "(%d declared, %s expected)" % (
2109 desc, self.name, len(self.args), expected_str))
2111 def signature_has_nongeneric_args(self):
2112 argcount = len(self.args)
2113 if argcount == 0 or (
2114 argcount == 1 and (self.args[0].is_self_arg or
2115 self.args[0].is_type_arg)):
2119 def signature_has_generic_args(self):
2120 return self.entry.signature.has_generic_args
2122 def declare_pyfunction(self, env):
2123 #print "DefNode.declare_pyfunction:", self.name, "in", env ###
2125 entry = env.lookup_here(name)
2126 if entry and entry.type.is_cfunction and not self.is_wrapper:
2127 warning(self.pos, "Overriding cdef method with def method.", 5)
2128 entry = env.declare_pyfunction(name, self.pos)
2130 prefix = env.scope_prefix
2131 entry.func_cname = \
2132 Naming.pyfunc_prefix + prefix + name
2133 entry.pymethdef_cname = \
2134 Naming.pymethdef_prefix + prefix + name
2135 if Options.docstrings:
2136 entry.doc = embed_position(self.pos, self.doc)
2138 Naming.funcdoc_prefix + prefix + name
2139 if entry.is_special:
2140 if entry.name in TypeSlots.invisible or not entry.doc or (entry.name in '__getattr__' and env.directives['fast_getattr']):
2141 entry.wrapperbase_cname = None
2143 entry.wrapperbase_cname = Naming.wrapperbase_prefix + prefix + name
2147 def declare_lambda_function(self, env):
2149 prefix = env.scope_prefix
2151 Naming.lambda_func_prefix + u'funcdef' + prefix + self.lambda_name
2152 entry = env.declare_lambda_function(func_cname, self.pos)
2153 entry.pymethdef_cname = \
2154 Naming.lambda_func_prefix + u'methdef' + prefix + self.lambda_name
2155 entry.qualified_name = env.qualify_name(self.lambda_name)
2159 def declare_arguments(self, env):
2160 for arg in self.args:
2162 error(arg.pos, "Missing argument name")
2164 env.control_flow.set_state((), (arg.name, 'source'), 'arg')
2165 env.control_flow.set_state((), (arg.name, 'initialized'), True)
2166 if arg.needs_conversion:
2167 arg.entry = env.declare_var(arg.name, arg.type, arg.pos)
2168 if arg.type.is_pyobject:
2169 arg.entry.init = "0"
2170 arg.entry.init_to_none = 0
2172 arg.entry = self.declare_argument(env, arg)
2174 arg.entry.is_self_arg = arg.is_self_arg
2176 if arg.is_self_arg or arg.is_type_arg or \
2177 (arg.type.is_extension_type and not arg.hdr_type.is_extension_type):
2178 arg.entry.is_declared_generic = 1
2179 self.declare_python_arg(env, self.star_arg)
2180 self.declare_python_arg(env, self.starstar_arg)
2182 def declare_python_arg(self, env, arg):
2184 if env.directives['infer_types'] != False:
2185 type = PyrexTypes.unspecified_type
2187 type = py_object_type
2188 entry = env.declare_var(arg.name, type, arg.pos)
2191 entry.init_to_none = 0
2192 entry.xdecref_cleanup = 1
2194 env.control_flow.set_state((), (arg.name, 'initialized'), True)
2196 def analyse_expressions(self, env):
2197 self.local_scope.directives = env.directives
2198 self.analyse_default_values(env)
2199 if self.needs_assignment_synthesis(env):
2200 # Shouldn't we be doing this at the module level too?
2201 self.synthesize_assignment_node(env)
2203 def needs_assignment_synthesis(self, env, code=None):
2204 # Should enable for module level as well, that will require more testing...
2205 if env.is_module_scope:
2207 return env.directives['binding']
2209 return code.globalstate.directives['binding']
2210 return env.is_py_class_scope or env.is_closure_scope
2212 def synthesize_assignment_node(self, env):
2214 if env.is_py_class_scope:
2215 rhs = ExprNodes.PyCFunctionNode(self.pos,
2216 pymethdef_cname = self.entry.pymethdef_cname)
2217 if not self.is_staticmethod and not self.is_classmethod:
2220 elif env.is_closure_scope:
2221 rhs = ExprNodes.InnerFunctionNode(
2222 self.pos, pymethdef_cname = self.entry.pymethdef_cname)
2224 rhs = ExprNodes.PyCFunctionNode(
2225 self.pos, pymethdef_cname = self.entry.pymethdef_cname, binding = env.directives['binding'])
2226 self.assmt = SingleAssignmentNode(self.pos,
2227 lhs = ExprNodes.NameNode(self.pos, name = self.name),
2229 self.assmt.analyse_declarations(env)
2230 self.assmt.analyse_expressions(env)
2232 def generate_function_header(self, code, with_pymethdef, proto_only=0):
2234 sig = self.entry.signature
2235 if sig.has_dummy_arg or self.self_in_stararg:
2236 arg_code_list.append(
2237 "PyObject *%s" % Naming.self_cname)
2238 for arg in self.args:
2239 if not arg.is_generic:
2240 if arg.is_self_arg or arg.is_type_arg:
2241 arg_code_list.append("PyObject *%s" % arg.hdr_cname)
2243 arg_code_list.append(
2244 arg.hdr_type.declaration_code(arg.hdr_cname))
2245 if not self.entry.is_special and sig.method_flags() == [TypeSlots.method_noargs]:
2246 arg_code_list.append("CYTHON_UNUSED PyObject *unused")
2247 if sig.has_generic_args:
2248 arg_code_list.append(
2249 "PyObject *%s, PyObject *%s"
2250 % (Naming.args_cname, Naming.kwds_cname))
2251 arg_code = ", ".join(arg_code_list)
2252 dc = self.return_type.declaration_code(self.entry.func_cname)
2253 mf = " ".join(self.modifiers).upper()
2255 header = "static %s%s(%s)" % (mf, dc, arg_code)
2256 code.putln("%s; /*proto*/" % header)
2259 if (Options.docstrings and self.entry.doc and
2260 not self.entry.scope.is_property_scope and
2261 (not self.entry.is_special or self.entry.wrapperbase_cname)):
2262 docstr = self.entry.doc
2263 if docstr.is_unicode:
2264 docstr = docstr.utf8encode()
2266 'static char %s[] = "%s";' % (
2267 self.entry.doc_cname,
2268 split_string_literal(escape_byte_string(docstr))))
2269 if self.entry.is_special:
2271 "struct wrapperbase %s;" % self.entry.wrapperbase_cname)
2274 "static PyMethodDef %s = " %
2275 self.entry.pymethdef_cname)
2276 code.put_pymethoddef(self.entry, ";", allow_skip=False)
2277 code.putln("%s {" % header)
2279 def generate_argument_declarations(self, env, code):
2280 for arg in self.args:
2281 if arg.is_generic: # or arg.needs_conversion:
2282 if arg.needs_conversion:
2283 code.putln("PyObject *%s = 0;" % arg.hdr_cname)
2284 elif not arg.entry.in_closure:
2285 code.put_var_declaration(arg.entry)
2287 def generate_keyword_list(self, code):
2288 if self.signature_has_generic_args() and \
2289 self.signature_has_nongeneric_args():
2291 "static PyObject **%s[] = {" %
2292 Naming.pykwdlist_cname)
2293 for arg in self.args:
2295 pystring_cname = code.intern_identifier(arg.name)
2296 code.put('&%s,' % pystring_cname)
2299 def generate_argument_parsing_code(self, env, code):
2300 # Generate PyArg_ParseTuple call for generic
2301 # arguments, if any.
2302 if self.entry.signature.has_dummy_arg and not self.self_in_stararg:
2303 # get rid of unused argument warning
2304 code.putln("%s = %s;" % (Naming.self_cname, Naming.self_cname))
2306 old_error_label = code.new_error_label()
2307 our_error_label = code.error_label
2308 end_label = code.new_label("argument_unpacking_done")
2310 has_kwonly_args = self.num_kwonly_args > 0
2311 has_star_or_kw_args = self.star_arg is not None \
2312 or self.starstar_arg is not None or has_kwonly_args
2314 for arg in self.args:
2315 if not arg.type.is_pyobject:
2316 done = arg.type.create_from_py_utility_code(env)
2317 if not done: pass # will fail later
2319 if not self.signature_has_generic_args():
2320 if has_star_or_kw_args:
2321 error(self.pos, "This method cannot have * or keyword arguments")
2322 self.generate_argument_conversion_code(code)
2324 elif not self.signature_has_nongeneric_args():
2325 # func(*args) or func(**kw) or func(*args, **kw)
2326 self.generate_stararg_copy_code(code)
2329 positional_args = []
2331 for arg in self.args:
2332 arg_entry = arg.entry
2335 if not arg.is_self_arg and not arg.is_type_arg:
2337 kw_only_args.append(arg)
2339 positional_args.append(arg)
2341 kw_only_args.append(arg)
2342 elif not arg.is_self_arg and not arg.is_type_arg:
2343 positional_args.append(arg)
2345 self.generate_tuple_and_keyword_parsing_code(
2346 positional_args, kw_only_args, end_label, code)
2348 code.error_label = old_error_label
2349 if code.label_used(our_error_label):
2350 if not code.label_used(end_label):
2351 code.put_goto(end_label)
2352 code.put_label(our_error_label)
2353 if has_star_or_kw_args:
2354 self.generate_arg_decref(self.star_arg, code)
2355 if self.starstar_arg:
2356 if self.starstar_arg.entry.xdecref_cleanup:
2357 code.put_var_xdecref(self.starstar_arg.entry)
2359 code.put_var_decref(self.starstar_arg.entry)
2360 code.putln('__Pyx_AddTraceback("%s");' % self.entry.qualified_name)
2361 # The arguments are put into the closure one after the
2362 # other, so when type errors are found, all references in
2363 # the closure instance must be properly ref-counted to
2364 # facilitate generic closure instance deallocation. In
2365 # the case of an argument type error, it's best to just
2366 # DECREF+clear the already handled references, as this
2367 # frees their references as early as possible.
2368 for arg in self.args:
2369 if arg.type.is_pyobject and arg.entry.in_closure:
2370 code.put_var_xdecref_clear(arg.entry)
2371 if self.needs_closure:
2372 code.put_decref(Naming.cur_scope_cname, self.local_scope.scope_class.type)
2373 code.put_finish_refcount_context()
2374 code.putln("return %s;" % self.error_value())
2375 if code.label_used(end_label):
2376 code.put_label(end_label)
2378 def generate_arg_assignment(self, arg, item, code):
2379 if arg.type.is_pyobject:
2381 item = PyrexTypes.typecast(arg.type, PyrexTypes.py_object_type, item)
2383 code.putln("%s = %s;" % (entry.cname, item))
2384 if entry.in_closure:
2385 code.put_var_incref(entry)
2387 func = arg.type.from_py_function
2389 code.putln("%s = %s(%s); %s" % (
2393 code.error_goto_if(arg.type.error_condition(arg.entry.cname), arg.pos)))
2395 error(arg.pos, "Cannot convert Python object argument to type '%s'" % arg.type)
2397 def generate_arg_xdecref(self, arg, code):
2399 code.put_var_xdecref(arg.entry)
2401 def generate_arg_decref(self, arg, code):
2403 code.put_var_decref(arg.entry)
2405 def generate_stararg_copy_code(self, code):
2406 if not self.star_arg:
2407 code.globalstate.use_utility_code(raise_argtuple_invalid_utility_code)
2408 code.putln("if (unlikely(PyTuple_GET_SIZE(%s) > 0)) {" %
2410 code.put('__Pyx_RaiseArgtupleInvalid("%s", 1, 0, 0, PyTuple_GET_SIZE(%s)); return %s;' % (
2411 self.name, Naming.args_cname, self.error_value()))
2414 code.globalstate.use_utility_code(keyword_string_check_utility_code)
2416 if self.starstar_arg:
2418 kwarg_check = "unlikely(%s)" % Naming.kwds_cname
2420 kwarg_check = "%s" % Naming.kwds_cname
2422 kwarg_check = "unlikely(%s) && unlikely(PyDict_Size(%s) > 0)" % (
2423 Naming.kwds_cname, Naming.kwds_cname)
2425 "if (%s && unlikely(!__Pyx_CheckKeywordStrings(%s, \"%s\", %d))) return %s;" % (
2426 kwarg_check, Naming.kwds_cname, self.name,
2427 bool(self.starstar_arg), self.error_value()))
2429 if self.starstar_arg:
2430 code.putln("%s = (%s) ? PyDict_Copy(%s) : PyDict_New();" % (
2431 self.starstar_arg.entry.cname,
2434 code.putln("if (unlikely(!%s)) return %s;" % (
2435 self.starstar_arg.entry.cname, self.error_value()))
2436 self.starstar_arg.entry.xdecref_cleanup = 0
2437 code.put_gotref(self.starstar_arg.entry.cname)
2439 if self.self_in_stararg:
2440 # need to create a new tuple with 'self' inserted as first item
2441 code.put("%s = PyTuple_New(PyTuple_GET_SIZE(%s)+1); if (unlikely(!%s)) " % (
2442 self.star_arg.entry.cname,
2444 self.star_arg.entry.cname))
2445 if self.starstar_arg:
2447 code.put_decref_clear(self.starstar_arg.entry.cname, py_object_type)
2448 code.putln("return %s;" % self.error_value())
2451 code.putln("return %s;" % self.error_value())
2452 code.put_gotref(self.star_arg.entry.cname)
2453 code.put_incref(Naming.self_cname, py_object_type)
2454 code.put_giveref(Naming.self_cname)
2455 code.putln("PyTuple_SET_ITEM(%s, 0, %s);" % (
2456 self.star_arg.entry.cname, Naming.self_cname))
2457 temp = code.funcstate.allocate_temp(PyrexTypes.c_py_ssize_t_type, manage_ref=False)
2458 code.putln("for (%s=0; %s < PyTuple_GET_SIZE(%s); %s++) {" % (
2459 temp, temp, Naming.args_cname, temp))
2460 code.putln("PyObject* item = PyTuple_GET_ITEM(%s, %s);" % (
2461 Naming.args_cname, temp))
2462 code.put_incref("item", py_object_type)
2463 code.put_giveref("item")
2464 code.putln("PyTuple_SET_ITEM(%s, %s+1, item);" % (
2465 self.star_arg.entry.cname, temp))
2467 code.funcstate.release_temp(temp)
2468 self.star_arg.entry.xdecref_cleanup = 0
2470 code.put_incref(Naming.args_cname, py_object_type)
2471 code.putln("%s = %s;" % (
2472 self.star_arg.entry.cname,
2474 self.star_arg.entry.xdecref_cleanup = 0
2476 def generate_tuple_and_keyword_parsing_code(self, positional_args,
2477 kw_only_args, success_label, code):
2478 argtuple_error_label = code.new_label("argtuple_error")
2480 min_positional_args = self.num_required_args - self.num_required_kw_args
2481 if len(self.args) > 0 and (self.args[0].is_self_arg or self.args[0].is_type_arg):
2482 min_positional_args -= 1
2483 max_positional_args = len(positional_args)
2484 has_fixed_positional_count = not self.star_arg and \
2485 min_positional_args == max_positional_args
2487 code.globalstate.use_utility_code(raise_double_keywords_utility_code)
2488 code.globalstate.use_utility_code(raise_argtuple_invalid_utility_code)
2489 if self.num_required_kw_args:
2490 code.globalstate.use_utility_code(raise_keyword_required_utility_code)
2492 if self.starstar_arg or self.star_arg:
2493 self.generate_stararg_init_code(max_positional_args, code)
2495 # --- optimised code when we receive keyword arguments
2496 if self.num_required_kw_args:
2497 likely_hint = "likely"
2499 likely_hint = "unlikely"
2500 code.putln("if (%s(%s)) {" % (likely_hint, Naming.kwds_cname))
2501 self.generate_keyword_unpacking_code(
2502 min_positional_args, max_positional_args,
2503 has_fixed_positional_count,
2504 positional_args, kw_only_args, argtuple_error_label, code)
2506 # --- optimised code when we do not receive any keyword arguments
2507 if (self.num_required_kw_args and min_positional_args > 0) or min_positional_args == max_positional_args:
2508 # Python raises arg tuple related errors first, so we must
2509 # check the length here
2510 if min_positional_args == max_positional_args and not self.star_arg:
2514 code.putln('} else if (PyTuple_GET_SIZE(%s) %s %d) {' % (
2515 Naming.args_cname, compare, min_positional_args))
2516 code.put_goto(argtuple_error_label)
2518 if self.num_required_kw_args:
2519 # pure error case: keywords required but not passed
2520 if max_positional_args > min_positional_args and not self.star_arg:
2521 code.putln('} else if (PyTuple_GET_SIZE(%s) > %d) {' % (
2522 Naming.args_cname, max_positional_args))
2523 code.put_goto(argtuple_error_label)
2524 code.putln('} else {')
2525 for i, arg in enumerate(kw_only_args):
2527 pystring_cname = code.intern_identifier(arg.name)
2528 # required keyword-only argument missing
2529 code.put('__Pyx_RaiseKeywordRequired("%s", %s); ' % (
2532 code.putln(code.error_goto(self.pos))
2535 elif min_positional_args == max_positional_args:
2536 # parse the exact number of positional arguments from the
2538 code.putln('} else {')
2539 for i, arg in enumerate(positional_args):
2540 item = "PyTuple_GET_ITEM(%s, %d)" % (Naming.args_cname, i)
2541 self.generate_arg_assignment(arg, item, code)
2542 self.generate_arg_default_assignments(code)
2545 # parse the positional arguments from the variable length
2547 code.putln('} else {')
2548 self.generate_arg_default_assignments(code)
2549 code.putln('switch (PyTuple_GET_SIZE(%s)) {' % Naming.args_cname)
2551 code.putln('default:')
2552 reversed_args = list(enumerate(positional_args))[::-1]
2553 for i, arg in reversed_args:
2554 if i >= min_positional_args-1:
2555 if min_positional_args > 1:
2556 code.putln('case %2d:' % (i+1)) # pure code beautification
2558 code.put('case %2d: ' % (i+1))
2559 item = "PyTuple_GET_ITEM(%s, %d)" % (Naming.args_cname, i)
2560 self.generate_arg_assignment(arg, item, code)
2561 if min_positional_args == 0:
2562 code.put('case 0: ')
2563 code.putln('break;')
2565 if min_positional_args:
2566 for i in range(min_positional_args-1, -1, -1):
2567 code.putln('case %2d:' % i)
2568 code.put_goto(argtuple_error_label)
2570 code.put('default: ')
2571 code.put_goto(argtuple_error_label)
2576 if code.label_used(argtuple_error_label):
2577 code.put_goto(success_label)
2578 code.put_label(argtuple_error_label)
2579 code.put('__Pyx_RaiseArgtupleInvalid("%s", %d, %d, %d, PyTuple_GET_SIZE(%s)); ' % (
2580 self.name, has_fixed_positional_count,
2581 min_positional_args, max_positional_args,
2583 code.putln(code.error_goto(self.pos))
2585 def generate_arg_default_assignments(self, code):
2586 for arg in self.args:
2587 if arg.is_generic and arg.default:
2591 arg.calculate_default_value_code(code)))
2593 def generate_stararg_init_code(self, max_positional_args, code):
2594 if self.starstar_arg:
2595 self.starstar_arg.entry.xdecref_cleanup = 0
2596 code.putln('%s = PyDict_New(); if (unlikely(!%s)) return %s;' % (
2597 self.starstar_arg.entry.cname,
2598 self.starstar_arg.entry.cname,
2599 self.error_value()))
2600 code.put_gotref(self.starstar_arg.entry.cname)
2602 self.star_arg.entry.xdecref_cleanup = 0
2603 code.putln('if (PyTuple_GET_SIZE(%s) > %d) {' % (
2605 max_positional_args))
2606 code.put('%s = PyTuple_GetSlice(%s, %d, PyTuple_GET_SIZE(%s)); ' % (
2607 self.star_arg.entry.cname, Naming.args_cname,
2608 max_positional_args, Naming.args_cname))
2609 code.put_gotref(self.star_arg.entry.cname)
2610 if self.starstar_arg:
2612 code.putln("if (unlikely(!%s)) {" % self.star_arg.entry.cname)
2613 code.put_decref(self.starstar_arg.entry.cname, py_object_type)
2614 code.putln('return %s;' % self.error_value())
2617 code.putln("if (unlikely(!%s)) return %s;" % (
2618 self.star_arg.entry.cname, self.error_value()))
2619 code.putln('} else {')
2620 code.put("%s = %s; " % (self.star_arg.entry.cname, Naming.empty_tuple))
2621 code.put_incref(Naming.empty_tuple, py_object_type)
2624 def generate_keyword_unpacking_code(self, min_positional_args, max_positional_args,
2625 has_fixed_positional_count, positional_args,
2626 kw_only_args, argtuple_error_label, code):
2627 all_args = tuple(positional_args) + tuple(kw_only_args)
2628 max_args = len(all_args)
2630 code.putln("Py_ssize_t kw_args = PyDict_Size(%s);" %
2632 # the 'values' array collects borrowed references to arguments
2633 # before doing any type coercion etc.
2634 code.putln("PyObject* values[%d] = {%s};" % (
2635 max_args, ','.join('0'*max_args)))
2637 # assign borrowed Python default values to the values array,
2638 # so that they can be overwritten by received arguments below
2639 for i, arg in enumerate(all_args):
2640 if arg.default and arg.type.is_pyobject:
2641 default_value = arg.calculate_default_value_code(code)
2642 code.putln('values[%d] = %s;' % (i, arg.type.as_pyobject(default_value)))
2644 # parse the args tuple and check that it's not too long
2645 code.putln('switch (PyTuple_GET_SIZE(%s)) {' % Naming.args_cname)
2647 code.putln('default:')
2648 for i in range(max_positional_args-1, -1, -1):
2649 code.put('case %2d: ' % (i+1))
2650 code.putln("values[%d] = PyTuple_GET_ITEM(%s, %d);" % (
2651 i, Naming.args_cname, i))
2652 code.putln('case 0: break;')
2653 if not self.star_arg:
2654 code.put('default: ') # more arguments than allowed
2655 code.put_goto(argtuple_error_label)
2658 # now fill up the positional/required arguments with values
2660 if self.num_required_args or max_positional_args > 0:
2661 last_required_arg = -1
2662 for i, arg in enumerate(all_args):
2664 last_required_arg = i
2665 if last_required_arg < max_positional_args:
2666 last_required_arg = max_positional_args-1
2667 num_required_args = self.num_required_args
2668 if max_positional_args > 0:
2669 code.putln('switch (PyTuple_GET_SIZE(%s)) {' % Naming.args_cname)
2670 for i, arg in enumerate(all_args[:last_required_arg+1]):
2671 if max_positional_args > 0 and i <= max_positional_args:
2672 if self.star_arg and i == max_positional_args:
2673 code.putln('default:')
2675 code.putln('case %2d:' % i)
2676 pystring_cname = code.intern_identifier(arg.name)
2679 # handled separately below
2681 code.putln('if (kw_args > 0) {')
2682 code.putln('PyObject* value = PyDict_GetItem(%s, %s);' % (
2683 Naming.kwds_cname, pystring_cname))
2684 code.putln('if (value) { values[%d] = value; kw_args--; }' % i)
2687 num_required_args -= 1
2688 code.putln('values[%d] = PyDict_GetItem(%s, %s);' % (
2689 i, Naming.kwds_cname, pystring_cname))
2690 code.putln('if (likely(values[%d])) kw_args--;' % i);
2691 if i < min_positional_args:
2693 # special case: we know arg 0 is missing
2695 code.put_goto(argtuple_error_label)
2697 # print the correct number of values (args or
2698 # kwargs) that were passed into positional
2699 # arguments up to this point
2700 code.putln('else {')
2701 code.put('__Pyx_RaiseArgtupleInvalid("%s", %d, %d, %d, %d); ' % (
2702 self.name, has_fixed_positional_count,
2703 min_positional_args, max_positional_args, i))
2704 code.putln(code.error_goto(self.pos))
2707 code.putln('else {')
2708 code.put('__Pyx_RaiseKeywordRequired("%s", %s); ' %(
2709 self.name, pystring_cname))
2710 code.putln(code.error_goto(self.pos))
2712 if max_positional_args > 0:
2715 if kw_only_args and not self.starstar_arg:
2716 # unpack optional keyword-only arguments
2717 # checking for interned strings in a dict is faster than iterating
2718 # but it's too likely that we must iterate if we expect **kwargs
2720 for i, arg in enumerate(all_args[max_positional_args:]):
2721 if not arg.kw_only or not arg.default:
2723 optional_args.append((i+max_positional_args, arg))
2725 # this mimics an unrolled loop so that we can "break" out of it
2726 code.putln('while (kw_args > 0) {')
2727 code.putln('PyObject* value;')
2728 for i, arg in optional_args:
2729 pystring_cname = code.intern_identifier(arg.name)
2731 'value = PyDict_GetItem(%s, %s);' % (
2732 Naming.kwds_cname, pystring_cname))
2734 'if (value) { values[%d] = value; if (!(--kw_args)) break; }' % i)
2735 code.putln('break;')
2738 code.putln('if (unlikely(kw_args > 0)) {')
2739 # non-positional/-required kw args left in dict: default args,
2740 # kw-only args, **kwargs or error
2742 # This is sort of a catch-all: except for checking required
2743 # arguments, this will always do the right thing for unpacking
2744 # keyword arguments, so that we can concentrate on optimising
2745 # common cases above.
2746 if max_positional_args == 0:
2749 code.putln("const Py_ssize_t used_pos_args = (PyTuple_GET_SIZE(%s) < %d) ? PyTuple_GET_SIZE(%s) : %d;" % (
2750 Naming.args_cname, max_positional_args,
2751 Naming.args_cname, max_positional_args))
2752 pos_arg_count = "used_pos_args"
2754 pos_arg_count = "PyTuple_GET_SIZE(%s)" % Naming.args_cname
2755 code.globalstate.use_utility_code(parse_keywords_utility_code)
2757 'if (unlikely(__Pyx_ParseOptionalKeywords(%s, %s, %s, values, %s, "%s") < 0)) ' % (
2759 Naming.pykwdlist_cname,
2760 self.starstar_arg and self.starstar_arg.entry.cname or '0',
2763 code.putln(code.error_goto(self.pos))
2766 # convert arg values to their final type and assign them
2767 for i, arg in enumerate(all_args):
2768 if arg.default and not arg.type.is_pyobject:
2769 code.putln("if (values[%d]) {" % i)
2770 self.generate_arg_assignment(arg, "values[%d]" % i, code)
2771 if arg.default and not arg.type.is_pyobject:
2772 code.putln('} else {')
2776 arg.calculate_default_value_code(code)))
2779 def generate_argument_conversion_code(self, code):
2780 # Generate code to convert arguments from signature type to
2781 # declared type, if needed. Also copies signature arguments
2782 # into closure fields.
2783 for arg in self.args:
2784 if arg.needs_conversion:
2785 self.generate_arg_conversion(arg, code)
2786 elif arg.entry.in_closure:
2787 code.putln('%s = %s;' % (arg.entry.cname, arg.hdr_cname))
2788 if arg.type.is_pyobject:
2789 code.put_var_incref(arg.entry)
2791 def generate_arg_conversion(self, arg, code):
2792 # Generate conversion code for one argument.
2793 old_type = arg.hdr_type
2795 if old_type.is_pyobject:
2797 code.putln("if (%s) {" % arg.hdr_cname)
2799 code.putln("assert(%s); {" % arg.hdr_cname)
2800 self.generate_arg_conversion_from_pyobject(arg, code)
2802 elif new_type.is_pyobject:
2803 self.generate_arg_conversion_to_pyobject(arg, code)
2805 if new_type.assignable_from(old_type):
2807 "%s = %s;" % (arg.entry.cname, arg.hdr_cname))
2810 "Cannot convert 1 argument from '%s' to '%s'" %
2811 (old_type, new_type))
2813 def generate_arg_conversion_from_pyobject(self, arg, code):
2815 func = new_type.from_py_function
2816 # copied from CoerceFromPyTypeNode
2818 lhs = arg.entry.cname
2819 rhs = "%s(%s)" % (func, arg.hdr_cname)
2820 if new_type.is_enum:
2821 rhs = PyrexTypes.typecast(new_type, PyrexTypes.c_long_type, rhs)
2822 code.putln("%s = %s; %s" % (
2825 code.error_goto_if(new_type.error_condition(arg.entry.cname), arg.pos)))
2828 "Cannot convert Python object argument to type '%s'"
2831 def generate_arg_conversion_to_pyobject(self, arg, code):
2832 old_type = arg.hdr_type
2833 func = old_type.to_py_function
2835 code.putln("%s = %s(%s); %s" % (
2839 code.error_goto_if_null(arg.entry.cname, arg.pos)))
2840 code.put_var_gotref(arg.entry)
2843 "Cannot convert argument of type '%s' to Python object"
2846 def generate_argument_type_tests(self, code):
2847 # Generate type tests for args whose signature
2848 # type is PyObject * and whose declared type is
2849 # a subtype thereof.
2850 for arg in self.args:
2851 if arg.needs_type_test:
2852 self.generate_arg_type_test(arg, code)
2853 elif not arg.accept_none and arg.type.is_pyobject:
2854 self.generate_arg_none_check(arg, code)
2856 def error_value(self):
2857 return self.entry.signature.error_value
2859 def caller_will_check_exceptions(self):
2862 class OverrideCheckNode(StatNode):
2863 # A Node for dispatching to the def method if it
2872 child_attrs = ['body']
2876 def analyse_expressions(self, env):
2877 self.args = env.arg_entries
2878 if self.py_func.is_module_scope:
2883 self.func_node = ExprNodes.RawCNameExprNode(self.pos, py_object_type)
2884 call_tuple = ExprNodes.TupleNode(self.pos, args=[ExprNodes.NameNode(self.pos, name=arg.name) for arg in self.args[first_arg:]])
2885 call_node = ExprNodes.SimpleCallNode(self.pos,
2886 function=self.func_node,
2887 args=[ExprNodes.NameNode(self.pos, name=arg.name) for arg in self.args[first_arg:]])
2888 self.body = ReturnStatNode(self.pos, value=call_node)
2889 self.body.analyse_expressions(env)
2891 def generate_execution_code(self, code):
2892 interned_attr_cname = code.intern_identifier(self.py_func.entry.name)
2893 # Check to see if we are an extension type
2894 if self.py_func.is_module_scope:
2895 self_arg = "((PyObject *)%s)" % Naming.module_cname
2897 self_arg = "((PyObject *)%s)" % self.args[0].cname
2898 code.putln("/* Check if called by wrapper */")
2899 code.putln("if (unlikely(%s)) ;" % Naming.skip_dispatch_cname)
2900 code.putln("/* Check if overriden in Python */")
2901 if self.py_func.is_module_scope:
2902 code.putln("else {")
2904 code.putln("else if (unlikely(Py_TYPE(%s)->tp_dictoffset != 0)) {" % self_arg)
2905 func_node_temp = code.funcstate.allocate_temp(py_object_type, manage_ref=True)
2906 self.func_node.set_cname(func_node_temp)
2907 # need to get attribute manually--scope would return cdef method
2908 err = code.error_goto_if_null(func_node_temp, self.pos)
2909 code.putln("%s = PyObject_GetAttr(%s, %s); %s" % (
2910 func_node_temp, self_arg, interned_attr_cname, err))
2911 code.put_gotref(func_node_temp)
2912 is_builtin_function_or_method = "PyCFunction_Check(%s)" % func_node_temp
2913 is_overridden = "(PyCFunction_GET_FUNCTION(%s) != (void *)&%s)" % (
2914 func_node_temp, self.py_func.entry.func_cname)
2915 code.putln("if (!%s || %s) {" % (is_builtin_function_or_method, is_overridden))
2916 self.body.generate_execution_code(code)
2918 code.put_decref_clear(func_node_temp, PyrexTypes.py_object_type)
2919 code.funcstate.release_temp(func_node_temp)
2922 class ClassDefNode(StatNode, BlockNode):
2925 class PyClassDefNode(ClassDefNode):
2926 # A Python class definition.
2928 # name EncodedString Name of the class
2929 # doc string or None
2930 # body StatNode Attribute definition code
2931 # entry Symtab.Entry
2932 # scope PyClassScope
2933 # decorators [DecoratorNode] list of decorators or None
2935 # The following subnodes are constructed internally:
2937 # dict DictNode Class dictionary or Py3 namespace
2938 # classobj ClassNode Class object
2939 # target NameNode Variable to assign class object to
2941 child_attrs = ["body", "dict", "metaclass", "mkw", "bases", "classobj", "target"]
2943 py3_style_class = False # Python3 style class
2945 def __init__(self, pos, name, bases, doc, body, decorators = None,
2946 keyword_args = None, starstar_arg = None):
2947 StatNode.__init__(self, pos)
2951 self.decorators = decorators
2953 if self.doc and Options.docstrings:
2954 doc = embed_position(self.pos, self.doc)
2955 doc_node = ExprNodes.StringNode(pos, value = doc)
2958 if keyword_args or starstar_arg:
2959 self.py3_style_class = True
2961 self.metaclass = None
2962 if keyword_args and not starstar_arg and len(keyword_args.key_value_pairs) == 1:
2963 item = keyword_args.key_value_pairs[0]
2964 if item.key.value == 'metaclass':
2965 # special case: we already know the metaclass and
2966 # it's the only kwarg, so we don't need to do the
2967 # "build kwargs, find metaclass" dance at runtime
2968 self.metaclass = item.value
2969 self.mkw = ExprNodes.NullNode(pos)
2970 if self.metaclass is None:
2971 self.mkw = ExprNodes.KeywordArgsNode(
2972 pos, keyword_args = keyword_args, starstar_arg = starstar_arg)
2973 self.metaclass = ExprNodes.PyClassMetaclassNode(
2974 pos, mkw = self.mkw, bases = self.bases)
2975 self.dict = ExprNodes.PyClassNamespaceNode(pos, name = name,
2976 doc = doc_node, metaclass = self.metaclass, bases = self.bases,
2978 self.classobj = ExprNodes.Py3ClassNode(pos, name = name,
2979 bases = self.bases, dict = self.dict, doc = doc_node,
2980 metaclass = self.metaclass, mkw = self.mkw)
2982 self.dict = ExprNodes.DictNode(pos, key_value_pairs = [])
2983 self.metaclass = None
2986 self.classobj = ExprNodes.ClassNode(pos, name = name,
2987 bases = bases, dict = self.dict, doc = doc_node)
2988 self.target = ExprNodes.NameNode(pos, name = name)
2990 def as_cclass(self):
2992 Return this node as if it were declared as an extension class
2994 if self.py3_style_class:
2995 error(self.classobj.pos, "Python3 style class could not be represented as C class")
2997 bases = self.classobj.bases.args
2999 base_class_name = None
3000 base_class_module = None
3001 elif len(bases) == 1:
3004 from ExprNodes import AttributeNode, NameNode
3005 while isinstance(base, AttributeNode):
3006 path.insert(0, base.attribute)
3008 if isinstance(base, NameNode):
3009 path.insert(0, base.name)
3010 base_class_name = path[-1]
3012 base_class_module = u'.'.join(path[:-1])
3014 base_class_module = None
3016 error(self.classobj.bases.args.pos, "Invalid base class")
3018 error(self.classobj.bases.args.pos, "C class may only have one base class")
3021 return CClassDefNode(self.pos,
3022 visibility = 'private',
3024 class_name = self.name,
3025 base_class_module = base_class_module,
3026 base_class_name = base_class_name,
3027 decorators = self.decorators,
3032 def create_scope(self, env):
3034 while env.is_py_class_scope or env.is_c_class_scope:
3035 env = env.outer_scope
3036 cenv = self.scope = PyClassScope(name = self.name, outer_scope = genv)
3039 def analyse_declarations(self, env):
3040 self.target.analyse_target_declaration(env)
3041 cenv = self.create_scope(env)
3042 cenv.directives = env.directives
3043 cenv.class_obj_cname = self.target.entry.cname
3044 self.body.analyse_declarations(cenv)
3046 def analyse_expressions(self, env):
3047 if self.py3_style_class:
3048 self.bases.analyse_expressions(env)
3049 self.metaclass.analyse_expressions(env)
3050 self.mkw.analyse_expressions(env)
3051 self.dict.analyse_expressions(env)
3052 self.classobj.analyse_expressions(env)
3053 genv = env.global_scope()
3055 self.body.analyse_expressions(cenv)
3056 self.target.analyse_target_expression(env, self.classobj)
3058 def generate_function_definitions(self, env, code):
3059 self.body.generate_function_definitions(self.scope, code)
3061 def generate_execution_code(self, code):
3062 code.pyclass_stack.append(self)
3064 if self.py3_style_class:
3065 self.bases.generate_evaluation_code(code)
3066 self.mkw.generate_evaluation_code(code)
3067 self.metaclass.generate_evaluation_code(code)
3068 self.dict.generate_evaluation_code(code)
3069 cenv.namespace_cname = cenv.class_obj_cname = self.dict.result()
3070 self.body.generate_execution_code(code)
3071 self.classobj.generate_evaluation_code(code)
3072 cenv.namespace_cname = cenv.class_obj_cname = self.classobj.result()
3073 self.target.generate_assignment_code(self.classobj, code)
3074 self.dict.generate_disposal_code(code)
3075 self.dict.free_temps(code)
3076 if self.py3_style_class:
3077 self.mkw.generate_disposal_code(code)
3078 self.mkw.free_temps(code)
3079 self.metaclass.generate_disposal_code(code)
3080 self.metaclass.free_temps(code)
3081 self.bases.generate_disposal_code(code)
3082 self.bases.free_temps(code)
3083 code.pyclass_stack.pop()
3085 class CClassDefNode(ClassDefNode):
3086 # An extension type definition.
3088 # visibility 'private' or 'public' or 'extern'
3089 # typedef_flag boolean
3091 # module_name string or None For import of extern type objects
3092 # class_name string Unqualified name of class
3093 # as_name string or None Name to declare as in this scope
3094 # base_class_module string or None Module containing the base class
3095 # base_class_name string or None Name of the base class
3096 # objstruct_name string or None Specified C name of object struct
3097 # typeobj_name string or None Specified C name of type object
3098 # in_pxd boolean Is in a .pxd file
3099 # decorators [DecoratorNode] list of decorators or None
3100 # doc string or None
3101 # body StatNode or None
3102 # entry Symtab.Entry
3103 # base_type PyExtensionType or None
3104 # buffer_defaults_node DictNode or None Declares defaults for a buffer
3105 # buffer_defaults_pos
3107 child_attrs = ["body"]
3108 buffer_defaults_node = None
3109 buffer_defaults_pos = None
3110 typedef_flag = False
3112 objstruct_name = None
3116 def analyse_declarations(self, env):
3117 #print "CClassDefNode.analyse_declarations:", self.class_name
3118 #print "...visibility =", self.visibility
3119 #print "...module_name =", self.module_name
3122 if self.buffer_defaults_node:
3123 buffer_defaults = Buffer.analyse_buffer_options(self.buffer_defaults_pos,
3124 env, [], self.buffer_defaults_node,
3125 need_complete=False)
3127 buffer_defaults = None
3129 if env.in_cinclude and not self.objstruct_name:
3130 error(self.pos, "Object struct name specification required for "
3131 "C class defined in 'extern from' block")
3132 self.base_type = None
3133 # Now that module imports are cached, we need to
3134 # import the modules for extern classes.
3135 if self.module_name:
3137 for module in env.cimported_modules:
3138 if module.name == self.module_name:
3139 self.module = module
3140 if self.module is None:
3141 self.module = ModuleScope(self.module_name, None, env.context)
3142 self.module.has_extern_class = 1
3143 env.add_imported_module(self.module)
3145 if self.base_class_name:
3146 if self.base_class_module:
3147 base_class_scope = env.find_module(self.base_class_module, self.pos)
3149 base_class_scope = env
3150 if self.base_class_name == 'object':
3151 # extension classes are special and don't need to inherit from object
3152 if base_class_scope is None or base_class_scope.lookup('object') is None:
3153 self.base_class_name = None
3154 self.base_class_module = None
3155 base_class_scope = None
3156 if base_class_scope:
3157 base_class_entry = base_class_scope.find(self.base_class_name, self.pos)
3158 if base_class_entry:
3159 if not base_class_entry.is_type:
3160 error(self.pos, "'%s' is not a type name" % self.base_class_name)
3161 elif not base_class_entry.type.is_extension_type:
3162 error(self.pos, "'%s' is not an extension type" % self.base_class_name)
3163 elif not base_class_entry.type.is_complete():
3164 error(self.pos, "Base class '%s' of type '%s' is incomplete" % (
3165 self.base_class_name, self.class_name))
3166 elif base_class_entry.type.scope and base_class_entry.type.scope.directives and \
3167 base_class_entry.type.scope.directives['final']:
3168 error(self.pos, "Base class '%s' of type '%s' is final" % (
3169 self.base_class_name, self.class_name))
3171 self.base_type = base_class_entry.type
3172 has_body = self.body is not None
3173 if self.module_name and self.visibility != 'extern':
3174 module_path = self.module_name.split(".")
3175 home_scope = env.find_imported_module(module_path, self.pos)
3181 if self.visibility == 'extern':
3182 if self.module_name == '__builtin__' and self.class_name in Builtin.builtin_types:
3183 warning(self.pos, "%s already a builtin Cython type" % self.class_name, 1)
3185 self.entry = home_scope.declare_c_class(
3186 name = self.class_name,
3188 defining = has_body and self.in_pxd,
3189 implementing = has_body and not self.in_pxd,
3190 module_name = self.module_name,
3191 base_type = self.base_type,
3192 objstruct_cname = self.objstruct_name,
3193 typeobj_cname = self.typeobj_name,
3194 visibility = self.visibility,
3195 typedef_flag = self.typedef_flag,
3197 buffer_defaults = buffer_defaults)
3198 if home_scope is not env and self.visibility == 'extern':
3199 env.add_imported_entry(self.class_name, self.entry, pos)
3200 self.scope = scope = self.entry.type.scope
3201 if scope is not None:
3202 scope.directives = env.directives
3204 if self.doc and Options.docstrings:
3205 scope.doc = embed_position(self.pos, self.doc)
3208 self.body.analyse_declarations(scope)
3212 scope.implemented = 1
3213 env.allocate_vtable_names(self.entry)
3215 def analyse_expressions(self, env):
3217 scope = self.entry.type.scope
3218 self.body.analyse_expressions(scope)
3220 def generate_function_definitions(self, env, code):
3222 self.body.generate_function_definitions(
3223 self.entry.type.scope, code)
3225 def generate_execution_code(self, code):
3226 # This is needed to generate evaluation code for
3227 # default values of method arguments.
3229 self.body.generate_execution_code(code)
3231 def annotate(self, code):
3233 self.body.annotate(code)
3236 class PropertyNode(StatNode):
3237 # Definition of a property in an extension type.
3240 # doc EncodedString or None Doc string
3243 child_attrs = ["body"]
3245 def analyse_declarations(self, env):
3246 entry = env.declare_property(self.name, self.doc, self.pos)
3248 entry.scope.directives = env.directives
3249 self.body.analyse_declarations(entry.scope)
3251 def analyse_expressions(self, env):
3252 self.body.analyse_expressions(env)
3254 def generate_function_definitions(self, env, code):
3255 self.body.generate_function_definitions(env, code)
3257 def generate_execution_code(self, code):
3260 def annotate(self, code):
3261 self.body.annotate(code)
3264 class GlobalNode(StatNode):
3265 # Global variable declaration.
3271 def analyse_declarations(self, env):
3272 for name in self.names:
3273 env.declare_global(name, self.pos)
3275 def analyse_expressions(self, env):
3278 def generate_execution_code(self, code):
3282 class ExprStatNode(StatNode):
3283 # Expression used as a statement.
3287 child_attrs = ["expr"]
3289 def analyse_declarations(self, env):
3291 if isinstance(self.expr, ExprNodes.GeneralCallNode):
3292 func = self.expr.function.as_cython_attribute()
3293 if func == u'declare':
3294 args, kwds = self.expr.explicit_args_kwds()
3296 error(self.expr.pos, "Variable names must be specified.")
3297 for var, type_node in kwds.key_value_pairs:
3298 type = type_node.analyse_as_type(env)
3300 error(type_node.pos, "Unknown type")
3302 env.declare_var(var.value, type, var.pos, is_cdef = True)
3303 self.__class__ = PassStatNode
3305 def analyse_expressions(self, env):
3306 self.expr.analyse_expressions(env)
3308 def generate_execution_code(self, code):
3309 self.expr.generate_evaluation_code(code)
3310 if not self.expr.is_temp and self.expr.result():
3311 code.putln("%s;" % self.expr.result())
3312 self.expr.generate_disposal_code(code)
3313 self.expr.free_temps(code)
3315 def generate_function_definitions(self, env, code):
3316 self.expr.generate_function_definitions(env, code)
3318 def annotate(self, code):
3319 self.expr.annotate(code)
3322 class AssignmentNode(StatNode):
3323 # Abstract base class for assignment nodes.
3325 # The analyse_expressions and generate_execution_code
3326 # phases of assignments are split into two sub-phases
3327 # each, to enable all the right hand sides of a
3328 # parallel assignment to be evaluated before assigning
3329 # to any of the left hand sides.
3331 def analyse_expressions(self, env):
3332 self.analyse_types(env)
3334 # def analyse_expressions(self, env):
3335 # self.analyse_expressions_1(env)
3336 # self.analyse_expressions_2(env)
3338 def generate_execution_code(self, code):
3339 self.generate_rhs_evaluation_code(code)
3340 self.generate_assignment_code(code)
3343 class SingleAssignmentNode(AssignmentNode):
3344 # The simplest case:
3348 # lhs ExprNode Left hand side
3349 # rhs ExprNode Right hand side
3350 # first bool Is this guaranteed the first assignment to lhs?
3352 child_attrs = ["lhs", "rhs"]
3354 declaration_only = False
3356 def analyse_declarations(self, env):
3359 # handle declarations of the form x = cython.foo()
3360 if isinstance(self.rhs, ExprNodes.CallNode):
3361 func_name = self.rhs.function.as_cython_attribute()
3363 args, kwds = self.rhs.explicit_args_kwds()
3365 if func_name in ['declare', 'typedef']:
3366 if len(args) > 2 or kwds is not None:
3367 error(rhs.pos, "Can only declare one type at a time.")
3369 type = args[0].analyse_as_type(env)
3371 error(args[0].pos, "Unknown type")
3374 if func_name == 'declare':
3375 if isinstance(lhs, ExprNodes.NameNode):
3376 vars = [(lhs.name, lhs.pos)]
3377 elif isinstance(lhs, ExprNodes.TupleNode):
3378 vars = [(var.name, var.pos) for var in lhs.args]
3380 error(lhs.pos, "Invalid declaration")
3382 for var, pos in vars:
3383 env.declare_var(var, type, pos, is_cdef = True)
3388 self.declaration_only = True
3390 self.declaration_only = True
3391 if not isinstance(lhs, ExprNodes.NameNode):
3392 error(lhs.pos, "Invalid declaration.")
3393 env.declare_typedef(lhs.name, type, self.pos, visibility='private')
3395 elif func_name in ['struct', 'union']:
3396 self.declaration_only = True
3397 if len(args) > 0 or kwds is None:
3398 error(rhs.pos, "Struct or union members must be given by name.")
3401 for member, type_node in kwds.key_value_pairs:
3402 type = type_node.analyse_as_type(env)
3404 error(type_node.pos, "Unknown type")
3406 members.append((member.value, type, member.pos))
3407 if len(members) < len(kwds.key_value_pairs):
3409 if not isinstance(self.lhs, ExprNodes.NameNode):
3410 error(self.lhs.pos, "Invalid declaration.")
3411 name = self.lhs.name
3412 scope = StructOrUnionScope(name)
3413 env.declare_struct_or_union(name, func_name, scope, False, self.rhs.pos)
3414 for member, type, pos in members:
3415 scope.declare_var(member, type, pos)
3417 if self.declaration_only:
3420 self.lhs.analyse_target_declaration(env)
3422 def analyse_types(self, env, use_temp = 0):
3423 self.rhs.analyse_types(env)
3424 self.lhs.analyse_target_types(env)
3425 self.lhs.gil_assignment_check(env)
3426 self.rhs = self.rhs.coerce_to(self.lhs.type, env)
3428 self.rhs = self.rhs.coerce_to_temp(env)
3430 def generate_rhs_evaluation_code(self, code):
3431 self.rhs.generate_evaluation_code(code)
3433 def generate_assignment_code(self, code):
3434 self.lhs.generate_assignment_code(self.rhs, code)
3436 def generate_function_definitions(self, env, code):
3437 self.rhs.generate_function_definitions(env, code)
3439 def annotate(self, code):
3440 self.lhs.annotate(code)
3441 self.rhs.annotate(code)
3444 class CascadedAssignmentNode(AssignmentNode):
3445 # An assignment with multiple left hand sides:
3449 # lhs_list [ExprNode] Left hand sides
3450 # rhs ExprNode Right hand sides
3454 # coerced_rhs_list [ExprNode] RHS coerced to type of each LHS
3456 child_attrs = ["lhs_list", "rhs", "coerced_rhs_list"]
3457 coerced_rhs_list = None
3459 def analyse_declarations(self, env):
3460 for lhs in self.lhs_list:
3461 lhs.analyse_target_declaration(env)
3463 def analyse_types(self, env, use_temp = 0):
3464 self.rhs.analyse_types(env)
3465 if not self.rhs.is_simple():
3467 self.rhs = self.rhs.coerce_to_temp(env)
3469 self.rhs = self.rhs.coerce_to_simple(env)
3470 from ExprNodes import CloneNode
3471 self.coerced_rhs_list = []
3472 for lhs in self.lhs_list:
3473 lhs.analyse_target_types(env)
3474 lhs.gil_assignment_check(env)
3475 rhs = CloneNode(self.rhs)
3476 rhs = rhs.coerce_to(lhs.type, env)
3477 self.coerced_rhs_list.append(rhs)
3479 def generate_rhs_evaluation_code(self, code):
3480 self.rhs.generate_evaluation_code(code)
3482 def generate_assignment_code(self, code):
3483 for i in range(len(self.lhs_list)):
3484 lhs = self.lhs_list[i]
3485 rhs = self.coerced_rhs_list[i]
3486 rhs.generate_evaluation_code(code)
3487 lhs.generate_assignment_code(rhs, code)
3488 # Assignment has disposed of the cloned RHS
3489 self.rhs.generate_disposal_code(code)
3490 self.rhs.free_temps(code)
3492 def generate_function_definitions(self, env, code):
3493 self.rhs.generate_function_definitions(env, code)
3495 def annotate(self, code):
3496 for i in range(len(self.lhs_list)):
3497 lhs = self.lhs_list[i].annotate(code)
3498 rhs = self.coerced_rhs_list[i].annotate(code)
3499 self.rhs.annotate(code)
3502 class ParallelAssignmentNode(AssignmentNode):
3503 # A combined packing/unpacking assignment:
3507 # This has been rearranged by the parser into
3509 # a = d ; b = e ; c = f
3511 # but we must evaluate all the right hand sides
3512 # before assigning to any of the left hand sides.
3514 # stats [AssignmentNode] The constituent assignments
3516 child_attrs = ["stats"]
3518 def analyse_declarations(self, env):
3519 for stat in self.stats:
3520 stat.analyse_declarations(env)
3522 def analyse_expressions(self, env):
3523 for stat in self.stats:
3524 stat.analyse_types(env, use_temp = 1)
3526 # def analyse_expressions(self, env):
3527 # for stat in self.stats:
3528 # stat.analyse_expressions_1(env, use_temp = 1)
3529 # for stat in self.stats:
3530 # stat.analyse_expressions_2(env)
3532 def generate_execution_code(self, code):
3533 for stat in self.stats:
3534 stat.generate_rhs_evaluation_code(code)
3535 for stat in self.stats:
3536 stat.generate_assignment_code(code)
3538 def generate_function_definitions(self, env, code):
3539 for stat in self.stats:
3540 stat.generate_function_definitions(env, code)
3542 def annotate(self, code):
3543 for stat in self.stats:
3547 class InPlaceAssignmentNode(AssignmentNode):
3548 # An in place arithmetic operand:
3554 # lhs ExprNode Left hand side
3555 # rhs ExprNode Right hand side
3556 # op char one of "+-*/%^&|"
3557 # dup (ExprNode) copy of lhs used for operation (auto-generated)
3559 # This code is a bit tricky because in order to obey Python
3560 # semantics the sub-expressions (e.g. indices) of the lhs must
3561 # not be evaluated twice. So we must re-use the values calculated
3562 # in evaluation phase for the assignment phase as well.
3563 # Fortunately, the type of the lhs node is fairly constrained
3564 # (it must be a NameNode, AttributeNode, or IndexNode).
3566 child_attrs = ["lhs", "rhs"]
3568 def analyse_declarations(self, env):
3569 self.lhs.analyse_target_declaration(env)
3571 def analyse_types(self, env):
3572 self.rhs.analyse_types(env)
3573 self.lhs.analyse_target_types(env)
3575 def generate_execution_code(self, code):
3577 self.rhs.generate_evaluation_code(code)
3578 self.lhs.generate_subexpr_evaluation_code(code)
3579 c_op = self.operator
3583 error(self.pos, "No C inplace power operator")
3584 if isinstance(self.lhs, ExprNodes.IndexNode) and self.lhs.is_buffer_access:
3585 if self.lhs.type.is_pyobject:
3586 error(self.pos, "In-place operators not allowed on object buffers in this release.")
3587 if c_op in ('/', '%') and self.lhs.type.is_int and not code.directives['cdivision']:
3588 error(self.pos, "In-place non-c divide operators not allowed on int buffers.")
3589 self.lhs.generate_buffer_setitem_code(self.rhs, code, c_op)
3592 # TODO: make sure overload is declared
3593 code.putln("%s %s= %s;" % (self.lhs.result(), c_op, self.rhs.result()))
3594 self.lhs.generate_subexpr_disposal_code(code)
3595 self.lhs.free_subexpr_temps(code)
3596 self.rhs.generate_disposal_code(code)
3597 self.rhs.free_temps(code)
3599 def annotate(self, code):
3600 self.lhs.annotate(code)
3601 self.rhs.annotate(code)
3603 def create_binop_node(self):
3605 return ExprNodes.binop_node(self.pos, self.operator, self.lhs, self.rhs)
3608 class PrintStatNode(StatNode):
3611 # arg_tuple TupleNode
3612 # stream ExprNode or None (stdout)
3613 # append_newline boolean
3615 child_attrs = ["arg_tuple", "stream"]
3617 def analyse_expressions(self, env):
3619 self.stream.analyse_expressions(env)
3620 self.stream = self.stream.coerce_to_pyobject(env)
3621 self.arg_tuple.analyse_expressions(env)
3622 self.arg_tuple = self.arg_tuple.coerce_to_pyobject(env)
3623 env.use_utility_code(printing_utility_code)
3624 if len(self.arg_tuple.args) == 1 and self.append_newline:
3625 env.use_utility_code(printing_one_utility_code)
3627 nogil_check = Node.gil_error
3628 gil_message = "Python print statement"
3630 def generate_execution_code(self, code):
3632 self.stream.generate_evaluation_code(code)
3633 stream_result = self.stream.py_result()
3636 if len(self.arg_tuple.args) == 1 and self.append_newline:
3637 arg = self.arg_tuple.args[0]
3638 arg.generate_evaluation_code(code)
3641 "if (__Pyx_PrintOne(%s, %s) < 0) %s" % (
3644 code.error_goto(self.pos)))
3645 arg.generate_disposal_code(code)
3646 arg.free_temps(code)
3648 self.arg_tuple.generate_evaluation_code(code)
3650 "if (__Pyx_Print(%s, %s, %d) < 0) %s" % (
3652 self.arg_tuple.py_result(),
3653 self.append_newline,
3654 code.error_goto(self.pos)))
3655 self.arg_tuple.generate_disposal_code(code)
3656 self.arg_tuple.free_temps(code)
3659 self.stream.generate_disposal_code(code)
3660 self.stream.free_temps(code)
3662 def generate_function_definitions(self, env, code):
3664 self.stream.generate_function_definitions(env, code)
3665 self.arg_tuple.generate_function_definitions(env, code)
3667 def annotate(self, code):
3669 self.stream.annotate(code)
3670 self.arg_tuple.annotate(code)
3673 class ExecStatNode(StatNode):
3678 child_attrs = ["args"]
3680 def analyse_expressions(self, env):
3681 for i, arg in enumerate(self.args):
3682 arg.analyse_expressions(env)
3683 arg = arg.coerce_to_pyobject(env)
3685 env.use_utility_code(Builtin.pyexec_utility_code)
3687 nogil_check = Node.gil_error
3688 gil_message = "Python exec statement"
3690 def generate_execution_code(self, code):
3692 for arg in self.args:
3693 arg.generate_evaluation_code(code)
3694 args.append( arg.py_result() )
3695 args = tuple(args + ['0', '0'][:3-len(args)])
3696 temp_result = code.funcstate.allocate_temp(PyrexTypes.py_object_type, manage_ref=True)
3697 code.putln("%s = __Pyx_PyRun(%s, %s, %s);" % (
3698 (temp_result,) + args))
3699 for arg in self.args:
3700 arg.generate_disposal_code(code)
3701 arg.free_temps(code)
3703 code.error_goto_if_null(temp_result, self.pos))
3704 code.put_gotref(temp_result)
3705 code.put_decref_clear(temp_result, py_object_type)
3706 code.funcstate.release_temp(temp_result)
3708 def annotate(self, code):
3709 for arg in self.args:
3713 class DelStatNode(StatNode):
3718 child_attrs = ["args"]
3720 def analyse_declarations(self, env):
3721 for arg in self.args:
3722 arg.analyse_target_declaration(env)
3724 def analyse_expressions(self, env):
3725 for arg in self.args:
3726 arg.analyse_target_expression(env, None)
3727 if arg.type.is_pyobject:
3729 elif arg.type.is_ptr and arg.type.base_type.is_cpp_class:
3731 elif arg.type.is_cpp_class:
3732 error(arg.pos, "Deletion of non-heap C++ object")
3734 error(arg.pos, "Deletion of non-Python, non-C++ object")
3735 #arg.release_target_temp(env)
3737 def nogil_check(self, env):
3738 for arg in self.args:
3739 if arg.type.is_pyobject:
3742 gil_message = "Deleting Python object"
3744 def generate_execution_code(self, code):
3745 for arg in self.args:
3746 if arg.type.is_pyobject:
3747 arg.generate_deletion_code(code)
3748 elif arg.type.is_ptr and arg.type.base_type.is_cpp_class:
3749 arg.generate_result_code(code)
3750 code.putln("delete %s;" % arg.result())
3751 # else error reported earlier
3753 def annotate(self, code):
3754 for arg in self.args:
3758 class PassStatNode(StatNode):
3763 def analyse_expressions(self, env):
3766 def generate_execution_code(self, code):
3770 class BreakStatNode(StatNode):
3774 def analyse_expressions(self, env):
3777 def generate_execution_code(self, code):
3778 if not code.break_label:
3779 error(self.pos, "break statement not inside loop")
3781 code.put_goto(code.break_label)
3784 class ContinueStatNode(StatNode):
3788 def analyse_expressions(self, env):
3791 def generate_execution_code(self, code):
3792 if code.funcstate.in_try_finally:
3793 error(self.pos, "continue statement inside try of try...finally")
3794 elif not code.continue_label:
3795 error(self.pos, "continue statement not inside loop")
3797 code.put_goto(code.continue_label)
3800 class ReturnStatNode(StatNode):
3803 # value ExprNode or None
3804 # return_type PyrexType
3806 child_attrs = ["value"]
3808 def analyse_expressions(self, env):
3809 return_type = env.return_type
3810 self.return_type = return_type
3812 error(self.pos, "Return not inside a function body")
3815 self.value.analyse_types(env)
3816 if return_type.is_void or return_type.is_returncode:
3817 error(self.value.pos,
3818 "Return with value in void function")
3820 self.value = self.value.coerce_to(env.return_type, env)
3822 if (not return_type.is_void
3823 and not return_type.is_pyobject
3824 and not return_type.is_returncode):
3825 error(self.pos, "Return value required")
3827 def nogil_check(self, env):
3828 if self.return_type.is_pyobject:
3831 gil_message = "Returning Python object"
3833 def generate_execution_code(self, code):
3834 code.mark_pos(self.pos)
3835 if not self.return_type:
3836 # error reported earlier
3838 if self.return_type.is_pyobject:
3839 code.put_xdecref(Naming.retval_cname,
3842 self.value.generate_evaluation_code(code)
3843 self.value.make_owned_reference(code)
3846 Naming.retval_cname,
3847 self.value.result_as(self.return_type)))
3848 self.value.generate_post_assignment_code(code)
3849 self.value.free_temps(code)
3851 if self.return_type.is_pyobject:
3852 code.put_init_to_py_none(Naming.retval_cname, self.return_type)
3853 elif self.return_type.is_returncode:
3856 Naming.retval_cname,
3857 self.return_type.default_value))
3858 for cname, type in code.funcstate.temps_holding_reference():
3859 code.put_decref_clear(cname, type)
3860 code.put_goto(code.return_label)
3862 def generate_function_definitions(self, env, code):
3863 if self.value is not None:
3864 self.value.generate_function_definitions(env, code)
3866 def annotate(self, code):
3868 self.value.annotate(code)
3871 class RaiseStatNode(StatNode):
3874 # exc_type ExprNode or None
3875 # exc_value ExprNode or None
3876 # exc_tb ExprNode or None
3878 child_attrs = ["exc_type", "exc_value", "exc_tb"]
3880 def analyse_expressions(self, env):
3882 self.exc_type.analyse_types(env)
3883 self.exc_type = self.exc_type.coerce_to_pyobject(env)
3885 self.exc_value.analyse_types(env)
3886 self.exc_value = self.exc_value.coerce_to_pyobject(env)
3888 self.exc_tb.analyse_types(env)
3889 self.exc_tb = self.exc_tb.coerce_to_pyobject(env)
3890 env.use_utility_code(raise_utility_code)
3892 nogil_check = Node.gil_error
3893 gil_message = "Raising exception"
3895 def generate_execution_code(self, code):
3897 self.exc_type.generate_evaluation_code(code)
3898 type_code = self.exc_type.py_result()
3902 self.exc_value.generate_evaluation_code(code)
3903 value_code = self.exc_value.py_result()
3907 self.exc_tb.generate_evaluation_code(code)
3908 tb_code = self.exc_tb.py_result()
3912 "__Pyx_Raise(%s, %s, %s);" % (
3916 for obj in (self.exc_type, self.exc_value, self.exc_tb):
3918 obj.generate_disposal_code(code)
3919 obj.free_temps(code)
3921 code.error_goto(self.pos))
3923 def generate_function_definitions(self, env, code):
3924 if self.exc_type is not None:
3925 self.exc_type.generate_function_definitions(env, code)
3926 if self.exc_value is not None:
3927 self.exc_value.generate_function_definitions(env, code)
3928 if self.exc_tb is not None:
3929 self.exc_tb.generate_function_definitions(env, code)
3931 def annotate(self, code):
3933 self.exc_type.annotate(code)
3935 self.exc_value.annotate(code)
3937 self.exc_tb.annotate(code)
3940 class ReraiseStatNode(StatNode):
3944 def analyse_expressions(self, env):
3945 env.use_utility_code(restore_exception_utility_code)
3947 nogil_check = Node.gil_error
3948 gil_message = "Raising exception"
3950 def generate_execution_code(self, code):
3951 vars = code.funcstate.exc_vars
3953 for varname in vars:
3954 code.put_giveref(varname)
3955 code.putln("__Pyx_ErrRestore(%s, %s, %s);" % tuple(vars))
3956 for varname in vars:
3957 code.put("%s = 0; " % varname)
3959 code.putln(code.error_goto(self.pos))
3961 error(self.pos, "Reraise not inside except clause")
3964 class AssertStatNode(StatNode):
3968 # value ExprNode or None
3970 child_attrs = ["cond", "value"]
3972 def analyse_expressions(self, env):
3973 self.cond = self.cond.analyse_boolean_expression(env)
3975 self.value.analyse_types(env)
3976 self.value = self.value.coerce_to_pyobject(env)
3978 nogil_check = Node.gil_error
3979 gil_message = "Raising exception"
3981 def generate_execution_code(self, code):
3982 code.putln("#ifndef PYREX_WITHOUT_ASSERTIONS")
3983 self.cond.generate_evaluation_code(code)
3985 "if (unlikely(!%s)) {" %
3988 self.value.generate_evaluation_code(code)
3990 "PyErr_SetObject(PyExc_AssertionError, %s);" %
3991 self.value.py_result())
3992 self.value.generate_disposal_code(code)
3993 self.value.free_temps(code)
3996 "PyErr_SetNone(PyExc_AssertionError);")
3998 code.error_goto(self.pos))
4001 self.cond.generate_disposal_code(code)
4002 self.cond.free_temps(code)
4003 code.putln("#endif")
4005 def generate_function_definitions(self, env, code):
4006 self.cond.generate_function_definitions(env, code)
4007 if self.value is not None:
4008 self.value.generate_function_definitions(env, code)
4010 def annotate(self, code):
4011 self.cond.annotate(code)
4013 self.value.annotate(code)
4016 class IfStatNode(StatNode):
4019 # if_clauses [IfClauseNode]
4020 # else_clause StatNode or None
4022 child_attrs = ["if_clauses", "else_clause"]
4024 def analyse_control_flow(self, env):
4025 env.start_branching(self.pos)
4026 for if_clause in self.if_clauses:
4027 if_clause.analyse_control_flow(env)
4028 env.next_branch(if_clause.end_pos())
4029 if self.else_clause:
4030 self.else_clause.analyse_control_flow(env)
4031 env.finish_branching(self.end_pos())
4033 def analyse_declarations(self, env):
4034 for if_clause in self.if_clauses:
4035 if_clause.analyse_declarations(env)
4036 if self.else_clause:
4037 self.else_clause.analyse_declarations(env)
4039 def analyse_expressions(self, env):
4040 for if_clause in self.if_clauses:
4041 if_clause.analyse_expressions(env)
4042 if self.else_clause:
4043 self.else_clause.analyse_expressions(env)
4045 def generate_execution_code(self, code):
4046 code.mark_pos(self.pos)
4047 end_label = code.new_label()
4048 for if_clause in self.if_clauses:
4049 if_clause.generate_execution_code(code, end_label)
4050 if self.else_clause:
4051 code.putln("/*else*/ {")
4052 self.else_clause.generate_execution_code(code)
4054 code.put_label(end_label)
4056 def generate_function_definitions(self, env, code):
4057 for clause in self.if_clauses:
4058 clause.generate_function_definitions(env, code)
4059 if self.else_clause is not None:
4060 self.else_clause.generate_function_definitions(env, code)
4062 def annotate(self, code):
4063 for if_clause in self.if_clauses:
4064 if_clause.annotate(code)
4065 if self.else_clause:
4066 self.else_clause.annotate(code)
4069 class IfClauseNode(Node):
4070 # if or elif clause in an if statement
4072 # condition ExprNode
4075 child_attrs = ["condition", "body"]
4077 def analyse_control_flow(self, env):
4078 self.body.analyse_control_flow(env)
4080 def analyse_declarations(self, env):
4081 self.body.analyse_declarations(env)
4083 def analyse_expressions(self, env):
4085 self.condition.analyse_temp_boolean_expression(env)
4086 self.body.analyse_expressions(env)
4088 def get_constant_condition_result(self):
4089 if self.condition.has_constant_result():
4090 return bool(self.condition.constant_result)
4094 def generate_execution_code(self, code, end_label):
4095 self.condition.generate_evaluation_code(code)
4098 self.condition.result())
4099 self.condition.generate_disposal_code(code)
4100 self.condition.free_temps(code)
4101 self.body.generate_execution_code(code)
4102 code.put_goto(end_label)
4105 def generate_function_definitions(self, env, code):
4106 self.condition.generate_function_definitions(env, code)
4107 self.body.generate_function_definitions(env, code)
4109 def annotate(self, code):
4110 self.condition.annotate(code)
4111 self.body.annotate(code)
4114 class SwitchCaseNode(StatNode):
4115 # Generated in the optimization of an if-elif-else node
4117 # conditions [ExprNode]
4120 child_attrs = ['conditions', 'body']
4122 def generate_execution_code(self, code):
4123 for cond in self.conditions:
4124 code.mark_pos(cond.pos)
4125 cond.generate_evaluation_code(code)
4126 code.putln("case %s:" % cond.result())
4127 self.body.generate_execution_code(code)
4128 code.putln("break;")
4130 def generate_function_definitions(self, env, code):
4131 for cond in self.conditions:
4132 cond.generate_function_definitions(env, code)
4133 self.body.generate_function_definitions(env, code)
4135 def annotate(self, code):
4136 for cond in self.conditions:
4138 self.body.annotate(code)
4140 class SwitchStatNode(StatNode):
4141 # Generated in the optimization of an if-elif-else node
4144 # cases [SwitchCaseNode]
4145 # else_clause StatNode or None
4147 child_attrs = ['test', 'cases', 'else_clause']
4149 def generate_execution_code(self, code):
4150 self.test.generate_evaluation_code(code)
4151 code.putln("switch (%s) {" % self.test.result())
4152 for case in self.cases:
4153 case.generate_execution_code(code)
4154 if self.else_clause is not None:
4155 code.putln("default:")
4156 self.else_clause.generate_execution_code(code)
4157 code.putln("break;")
4160 def generate_function_definitions(self, env, code):
4161 self.test.generate_function_definitions(env, code)
4162 for case in self.cases:
4163 case.generate_function_definitions(env, code)
4164 if self.else_clause is not None:
4165 self.else_clause.generate_function_definitions(env, code)
4167 def annotate(self, code):
4168 self.test.annotate(code)
4169 for case in self.cases:
4171 if self.else_clause is not None:
4172 self.else_clause.annotate(code)
4174 class LoopNode(object):
4176 def analyse_control_flow(self, env):
4177 env.start_branching(self.pos)
4178 self.body.analyse_control_flow(env)
4179 env.next_branch(self.body.end_pos())
4180 if self.else_clause:
4181 self.else_clause.analyse_control_flow(env)
4182 env.finish_branching(self.end_pos())
4185 class WhileStatNode(LoopNode, StatNode):
4188 # condition ExprNode
4190 # else_clause StatNode
4192 child_attrs = ["condition", "body", "else_clause"]
4194 def analyse_declarations(self, env):
4195 self.body.analyse_declarations(env)
4196 if self.else_clause:
4197 self.else_clause.analyse_declarations(env)
4199 def analyse_expressions(self, env):
4201 self.condition.analyse_temp_boolean_expression(env)
4202 self.body.analyse_expressions(env)
4203 if self.else_clause:
4204 self.else_clause.analyse_expressions(env)
4206 def generate_execution_code(self, code):
4207 old_loop_labels = code.new_loop_labels()
4210 self.condition.generate_evaluation_code(code)
4211 self.condition.generate_disposal_code(code)
4214 self.condition.result())
4215 self.condition.free_temps(code)
4216 self.body.generate_execution_code(code)
4217 code.put_label(code.continue_label)
4219 break_label = code.break_label
4220 code.set_loop_labels(old_loop_labels)
4221 if self.else_clause:
4222 code.putln("/*else*/ {")
4223 self.else_clause.generate_execution_code(code)
4225 code.put_label(break_label)
4227 def generate_function_definitions(self, env, code):
4228 self.condition.generate_function_definitions(env, code)
4229 self.body.generate_function_definitions(env, code)
4230 if self.else_clause is not None:
4231 self.else_clause.generate_function_definitions(env, code)
4233 def annotate(self, code):
4234 self.condition.annotate(code)
4235 self.body.annotate(code)
4236 if self.else_clause:
4237 self.else_clause.annotate(code)
4240 def ForStatNode(pos, **kw):
4241 if 'iterator' in kw:
4242 return ForInStatNode(pos, **kw)
4244 return ForFromStatNode(pos, **kw)
4246 class ForInStatNode(LoopNode, StatNode):
4250 # iterator IteratorNode
4252 # else_clause StatNode
4253 # item NextNode used internally
4255 child_attrs = ["target", "iterator", "body", "else_clause"]
4258 def analyse_declarations(self, env):
4259 self.target.analyse_target_declaration(env)
4260 self.body.analyse_declarations(env)
4261 if self.else_clause:
4262 self.else_clause.analyse_declarations(env)
4264 def analyse_expressions(self, env):
4266 self.target.analyse_target_types(env)
4267 self.iterator.analyse_expressions(env)
4268 self.item = ExprNodes.NextNode(self.iterator, env)
4269 self.item = self.item.coerce_to(self.target.type, env)
4270 self.body.analyse_expressions(env)
4271 if self.else_clause:
4272 self.else_clause.analyse_expressions(env)
4274 def generate_execution_code(self, code):
4275 old_loop_labels = code.new_loop_labels()
4276 self.iterator.allocate_counter_temp(code)
4277 self.iterator.generate_evaluation_code(code)
4280 self.item.generate_evaluation_code(code)
4281 self.target.generate_assignment_code(self.item, code)
4282 self.body.generate_execution_code(code)
4283 code.put_label(code.continue_label)
4286 break_label = code.break_label
4287 code.set_loop_labels(old_loop_labels)
4289 if self.else_clause:
4290 # in nested loops, the 'else' block can contain a
4291 # 'continue' statement for the outer loop, but we may need
4292 # to generate cleanup code before taking that path, so we
4294 orig_continue_label = code.continue_label
4295 code.continue_label = code.new_label('outer_continue')
4297 code.putln("/*else*/ {")
4298 self.else_clause.generate_execution_code(code)
4301 if code.label_used(code.continue_label):
4302 code.put_goto(break_label)
4303 code.put_label(code.continue_label)
4304 self.iterator.generate_disposal_code(code)
4305 code.put_goto(orig_continue_label)
4306 code.set_loop_labels(old_loop_labels)
4308 if code.label_used(break_label):
4309 code.put_label(break_label)
4310 self.iterator.release_counter_temp(code)
4311 self.iterator.generate_disposal_code(code)
4312 self.iterator.free_temps(code)
4314 def generate_function_definitions(self, env, code):
4315 self.target.generate_function_definitions(env, code)
4316 self.iterator.generate_function_definitions(env, code)
4317 self.body.generate_function_definitions(env, code)
4318 if self.else_clause is not None:
4319 self.else_clause.generate_function_definitions(env, code)
4321 def annotate(self, code):
4322 self.target.annotate(code)
4323 self.iterator.annotate(code)
4324 self.body.annotate(code)
4325 if self.else_clause:
4326 self.else_clause.annotate(code)
4327 self.item.annotate(code)
4330 class ForFromStatNode(LoopNode, StatNode):
4331 # for name from expr rel name rel expr
4338 # step ExprNode or None
4340 # else_clause StatNode or None
4346 # loopvar_node ExprNode (usually a NameNode or temp node)
4347 # py_loopvar_node PyTempNode or None
4348 child_attrs = ["target", "bound1", "bound2", "step", "body", "else_clause"]
4350 is_py_target = False
4352 py_loopvar_node = None
4355 gil_message = "For-loop using object bounds or target"
4357 def nogil_check(self, env):
4358 for x in (self.target, self.bound1, self.bound2):
4359 if x.type.is_pyobject:
4362 def analyse_declarations(self, env):
4363 self.target.analyse_target_declaration(env)
4364 self.body.analyse_declarations(env)
4365 if self.else_clause:
4366 self.else_clause.analyse_declarations(env)
4368 def analyse_expressions(self, env):
4370 self.target.analyse_target_types(env)
4371 self.bound1.analyse_types(env)
4372 self.bound2.analyse_types(env)
4373 if self.step is not None:
4374 if isinstance(self.step, ExprNodes.UnaryMinusNode):
4375 warning(self.step.pos, "Probable infinite loop in for-from-by statment. Consider switching the directions of the relations.", 2)
4376 self.step.analyse_types(env)
4378 target_type = self.target.type
4379 if self.target.type.is_numeric:
4380 loop_type = self.target.type
4382 loop_type = PyrexTypes.c_int_type
4383 if not self.bound1.type.is_pyobject:
4384 loop_type = PyrexTypes.widest_numeric_type(loop_type, self.bound1.type)
4385 if not self.bound2.type.is_pyobject:
4386 loop_type = PyrexTypes.widest_numeric_type(loop_type, self.bound2.type)
4387 if self.step is not None and not self.step.type.is_pyobject:
4388 loop_type = PyrexTypes.widest_numeric_type(loop_type, self.step.type)
4389 self.bound1 = self.bound1.coerce_to(loop_type, env)
4390 self.bound2 = self.bound2.coerce_to(loop_type, env)
4391 if not self.bound2.is_literal:
4392 self.bound2 = self.bound2.coerce_to_temp(env)
4393 if self.step is not None:
4394 self.step = self.step.coerce_to(loop_type, env)
4395 if not self.step.is_literal:
4396 self.step = self.step.coerce_to_temp(env)
4398 target_type = self.target.type
4399 if not (target_type.is_pyobject or target_type.is_numeric):
4400 error(self.target.pos,
4401 "for-from loop variable must be c numeric type or Python object")
4402 if target_type.is_numeric:
4403 self.is_py_target = False
4404 if isinstance(self.target, ExprNodes.IndexNode) and self.target.is_buffer_access:
4405 raise error(self.pos, "Buffer indexing not allowed as for loop target.")
4406 self.loopvar_node = self.target
4407 self.py_loopvar_node = None
4409 self.is_py_target = True
4410 c_loopvar_node = ExprNodes.TempNode(self.pos, loop_type, env)
4411 self.loopvar_node = c_loopvar_node
4412 self.py_loopvar_node = \
4413 ExprNodes.CloneNode(c_loopvar_node).coerce_to_pyobject(env)
4414 self.body.analyse_expressions(env)
4415 if self.else_clause:
4416 self.else_clause.analyse_expressions(env)
4418 def generate_execution_code(self, code):
4419 old_loop_labels = code.new_loop_labels()
4420 from_range = self.from_range
4421 self.bound1.generate_evaluation_code(code)
4422 self.bound2.generate_evaluation_code(code)
4423 offset, incop = self.relation_table[self.relation1]
4424 if self.step is not None:
4425 self.step.generate_evaluation_code(code)
4426 step = self.step.result()
4427 incop = "%s=%s" % (incop[0], step)
4429 if isinstance(self.loopvar_node, ExprNodes.TempNode):
4430 self.loopvar_node.allocate(code)
4431 if isinstance(self.py_loopvar_node, ExprNodes.TempNode):
4432 self.py_loopvar_node.allocate(code)
4434 loopvar_name = code.funcstate.allocate_temp(self.target.type, False)
4436 loopvar_name = self.loopvar_node.result()
4438 "for (%s = %s%s; %s %s %s; %s%s) {" % (
4440 self.bound1.result(), offset,
4441 loopvar_name, self.relation2, self.bound2.result(),
4442 loopvar_name, incop))
4443 if self.py_loopvar_node:
4444 self.py_loopvar_node.generate_evaluation_code(code)
4445 self.target.generate_assignment_code(self.py_loopvar_node, code)
4447 code.putln("%s = %s;" % (
4448 self.target.result(), loopvar_name))
4449 self.body.generate_execution_code(code)
4450 code.put_label(code.continue_label)
4451 if self.py_loopvar_node:
4452 # This mess is to make for..from loops with python targets behave
4453 # exactly like those with C targets with regards to re-assignment
4454 # of the loop variable.
4456 if self.target.entry.is_pyglobal:
4457 # We know target is a NameNode, this is the only ugly case.
4458 target_node = ExprNodes.PyTempNode(self.target.pos, None)
4459 target_node.allocate(code)
4460 interned_cname = code.intern_identifier(self.target.entry.name)
4461 code.globalstate.use_utility_code(ExprNodes.get_name_interned_utility_code)
4462 code.putln("%s = __Pyx_GetName(%s, %s); %s" % (
4463 target_node.result(),
4464 Naming.module_cname,
4466 code.error_goto_if_null(target_node.result(), self.target.pos)))
4467 code.put_gotref(target_node.result())
4469 target_node = self.target
4470 from_py_node = ExprNodes.CoerceFromPyTypeNode(self.loopvar_node.type, target_node, None)
4471 from_py_node.temp_code = loopvar_name
4472 from_py_node.generate_result_code(code)
4473 if self.target.entry.is_pyglobal:
4474 code.put_decref(target_node.result(), target_node.type)
4475 target_node.release(code)
4477 if self.py_loopvar_node:
4478 # This is potentially wasteful, but we don't want the semantics to
4479 # depend on whether or not the loop is a python type.
4480 self.py_loopvar_node.generate_evaluation_code(code)
4481 self.target.generate_assignment_code(self.py_loopvar_node, code)
4483 code.funcstate.release_temp(loopvar_name)
4484 break_label = code.break_label
4485 code.set_loop_labels(old_loop_labels)
4486 if self.else_clause:
4487 code.putln("/*else*/ {")
4488 self.else_clause.generate_execution_code(code)
4490 code.put_label(break_label)
4491 self.bound1.generate_disposal_code(code)
4492 self.bound1.free_temps(code)
4493 self.bound2.generate_disposal_code(code)
4494 self.bound2.free_temps(code)
4495 if isinstance(self.loopvar_node, ExprNodes.TempNode):
4496 self.loopvar_node.release(code)
4497 if isinstance(self.py_loopvar_node, ExprNodes.TempNode):
4498 self.py_loopvar_node.release(code)
4499 if self.step is not None:
4500 self.step.generate_disposal_code(code)
4501 self.step.free_temps(code)
4504 # {relop : (initial offset, increment op)}
4511 def generate_function_definitions(self, env, code):
4512 self.target.generate_function_definitions(env, code)
4513 self.bound1.generate_function_definitions(env, code)
4514 self.bound2.generate_function_definitions(env, code)
4515 if self.step is not None:
4516 self.step.generate_function_definitions(env, code)
4517 self.body.generate_function_definitions(env, code)
4518 if self.else_clause is not None:
4519 self.else_clause.generate_function_definitions(env, code)
4521 def annotate(self, code):
4522 self.target.annotate(code)
4523 self.bound1.annotate(code)
4524 self.bound2.annotate(code)
4526 self.step.annotate(code)
4527 self.body.annotate(code)
4528 if self.else_clause:
4529 self.else_clause.annotate(code)
4532 class WithStatNode(StatNode):
4534 Represents a Python with statement.
4536 This is only used at parse tree level; and is not present in
4537 analysis or generation phases.
4539 # manager The with statement manager object
4540 # target Node (lhs expression)
4542 child_attrs = ["manager", "target", "body"]
4544 class TryExceptStatNode(StatNode):
4545 # try .. except statement
4548 # except_clauses [ExceptClauseNode]
4549 # else_clause StatNode or None
4551 child_attrs = ["body", "except_clauses", "else_clause"]
4553 def analyse_control_flow(self, env):
4554 env.start_branching(self.pos)
4555 self.body.analyse_control_flow(env)
4556 successful_try = env.control_flow # grab this for later
4557 env.next_branch(self.body.end_pos())
4558 env.finish_branching(self.body.end_pos())
4560 env.start_branching(self.except_clauses[0].pos)
4561 for except_clause in self.except_clauses:
4562 except_clause.analyse_control_flow(env)
4563 env.next_branch(except_clause.end_pos())
4565 # the else cause it executed only when the try clause finishes
4566 env.control_flow.incoming = successful_try
4567 if self.else_clause:
4568 self.else_clause.analyse_control_flow(env)
4569 env.finish_branching(self.end_pos())
4571 def analyse_declarations(self, env):
4572 self.body.analyse_declarations(env)
4573 for except_clause in self.except_clauses:
4574 except_clause.analyse_declarations(env)
4575 if self.else_clause:
4576 self.else_clause.analyse_declarations(env)
4577 env.use_utility_code(reset_exception_utility_code)
4579 def analyse_expressions(self, env):
4580 self.body.analyse_expressions(env)
4581 default_clause_seen = 0
4582 for except_clause in self.except_clauses:
4583 except_clause.analyse_expressions(env)
4584 if default_clause_seen:
4585 error(except_clause.pos, "default 'except:' must be last")
4586 if not except_clause.pattern:
4587 default_clause_seen = 1
4588 self.has_default_clause = default_clause_seen
4589 if self.else_clause:
4590 self.else_clause.analyse_expressions(env)
4592 nogil_check = Node.gil_error
4593 gil_message = "Try-except statement"
4595 def generate_execution_code(self, code):
4596 old_return_label = code.return_label
4597 old_break_label = code.break_label
4598 old_continue_label = code.continue_label
4599 old_error_label = code.new_error_label()
4600 our_error_label = code.error_label
4601 except_end_label = code.new_label('exception_handled')
4602 except_error_label = code.new_label('except_error')
4603 except_return_label = code.new_label('except_return')
4604 try_return_label = code.new_label('try_return')
4605 try_break_label = code.new_label('try_break')
4606 try_continue_label = code.new_label('try_continue')
4607 try_end_label = code.new_label('try_end')
4610 code.putln("PyObject %s;" %
4611 ', '.join(['*%s' % var for var in Naming.exc_save_vars]))
4612 code.putln("__Pyx_ExceptionSave(%s);" %
4613 ', '.join(['&%s' % var for var in Naming.exc_save_vars]))
4614 for var in Naming.exc_save_vars:
4615 code.put_xgotref(var)
4618 code.return_label = try_return_label
4619 code.break_label = try_break_label
4620 code.continue_label = try_continue_label
4621 self.body.generate_execution_code(code)
4624 temps_to_clean_up = code.funcstate.all_free_managed_temps()
4625 code.error_label = except_error_label
4626 code.return_label = except_return_label
4627 if self.else_clause:
4630 self.else_clause.generate_execution_code(code)
4633 for var in Naming.exc_save_vars:
4634 code.put_xdecref_clear(var, py_object_type)
4635 code.put_goto(try_end_label)
4636 if code.label_used(try_return_label):
4637 code.put_label(try_return_label)
4638 for var in Naming.exc_save_vars: code.put_xgiveref(var)
4639 code.putln("__Pyx_ExceptionReset(%s);" %
4640 ', '.join(Naming.exc_save_vars))
4641 code.put_goto(old_return_label)
4642 code.put_label(our_error_label)
4643 for temp_name, type in temps_to_clean_up:
4644 code.put_xdecref_clear(temp_name, type)
4645 for except_clause in self.except_clauses:
4646 except_clause.generate_handling_code(code, except_end_label)
4648 error_label_used = code.label_used(except_error_label)
4649 if error_label_used or not self.has_default_clause:
4650 if error_label_used:
4651 code.put_label(except_error_label)
4652 for var in Naming.exc_save_vars: code.put_xgiveref(var)
4653 code.putln("__Pyx_ExceptionReset(%s);" %
4654 ', '.join(Naming.exc_save_vars))
4655 code.put_goto(old_error_label)
4657 for exit_label, old_label in zip(
4658 [try_break_label, try_continue_label, except_return_label],
4659 [old_break_label, old_continue_label, old_return_label]):
4661 if code.label_used(exit_label):
4662 code.put_label(exit_label)
4663 for var in Naming.exc_save_vars: code.put_xgiveref(var)
4664 code.putln("__Pyx_ExceptionReset(%s);" %
4665 ', '.join(Naming.exc_save_vars))
4666 code.put_goto(old_label)
4668 if code.label_used(except_end_label):
4669 code.put_label(except_end_label)
4670 for var in Naming.exc_save_vars: code.put_xgiveref(var)
4671 code.putln("__Pyx_ExceptionReset(%s);" %
4672 ', '.join(Naming.exc_save_vars))
4673 code.put_label(try_end_label)
4676 code.return_label = old_return_label
4677 code.break_label = old_break_label
4678 code.continue_label = old_continue_label
4679 code.error_label = old_error_label
4681 def generate_function_definitions(self, env, code):
4682 self.body.generate_function_definitions(env, code)
4683 for except_clause in self.except_clauses:
4684 except_clause.generate_function_definitions(env, code)
4685 if self.else_clause is not None:
4686 self.else_clause.generate_function_definitions(env, code)
4688 def annotate(self, code):
4689 self.body.annotate(code)
4690 for except_node in self.except_clauses:
4691 except_node.annotate(code)
4692 if self.else_clause:
4693 self.else_clause.annotate(code)
4696 class ExceptClauseNode(Node):
4697 # Part of try ... except statement.
4699 # pattern [ExprNode]
4700 # target ExprNode or None
4702 # excinfo_target NameNode or None optional target for exception info
4703 # match_flag string result of exception match
4704 # exc_value ExcValueNode used internally
4705 # function_name string qualified name of enclosing function
4706 # exc_vars (string * 3) local exception variables
4708 # excinfo_target is never set by the parser, but can be set by a transform
4709 # in order to extract more extensive information about the exception as a
4710 # sys.exc_info()-style tuple into a target variable
4712 child_attrs = ["pattern", "target", "body", "exc_value", "excinfo_target"]
4715 excinfo_target = None
4717 def analyse_declarations(self, env):
4719 self.target.analyse_target_declaration(env)
4720 if self.excinfo_target is not None:
4721 self.excinfo_target.analyse_target_declaration(env)
4722 self.body.analyse_declarations(env)
4724 def analyse_expressions(self, env):
4726 genv = env.global_scope()
4727 self.function_name = env.qualified_name
4729 # normalise/unpack self.pattern into a list
4730 for i, pattern in enumerate(self.pattern):
4731 pattern.analyse_expressions(env)
4732 self.pattern[i] = pattern.coerce_to_pyobject(env)
4735 self.exc_value = ExprNodes.ExcValueNode(self.pos, env)
4736 self.target.analyse_target_expression(env, self.exc_value)
4737 if self.excinfo_target is not None:
4739 self.excinfo_tuple = ExprNodes.TupleNode(pos=self.pos, args=[
4740 ExprNodes.ExcValueNode(pos=self.pos, env=env) for x in range(3)])
4741 self.excinfo_tuple.analyse_expressions(env)
4742 self.excinfo_target.analyse_target_expression(env, self.excinfo_tuple)
4744 self.body.analyse_expressions(env)
4746 def generate_handling_code(self, code, end_label):
4747 code.mark_pos(self.pos)
4750 for pattern in self.pattern:
4751 pattern.generate_evaluation_code(code)
4752 exc_tests.append("PyErr_ExceptionMatches(%s)" % pattern.py_result())
4754 match_flag = code.funcstate.allocate_temp(PyrexTypes.c_int_type, False)
4756 "%s = %s;" % (match_flag, ' || '.join(exc_tests)))
4757 for pattern in self.pattern:
4758 pattern.generate_disposal_code(code)
4759 pattern.free_temps(code)
4763 code.funcstate.release_temp(match_flag)
4765 code.putln("/*except:*/ {")
4767 if not getattr(self.body, 'stats', True) and \
4768 self.excinfo_target is None and self.target is None:
4769 # most simple case: no exception variable, empty body (pass)
4770 # => reset the exception state, done
4771 code.putln("PyErr_Restore(0,0,0);")
4772 code.put_goto(end_label)
4776 exc_vars = [code.funcstate.allocate_temp(py_object_type,
4779 code.putln('__Pyx_AddTraceback("%s");' % self.function_name)
4780 # We always have to fetch the exception value even if
4781 # there is no target, because this also normalises the
4782 # exception and stores it in the thread state.
4783 code.globalstate.use_utility_code(get_exception_utility_code)
4784 exc_args = "&%s, &%s, &%s" % tuple(exc_vars)
4785 code.putln("if (__Pyx_GetException(%s) < 0) %s" % (exc_args,
4786 code.error_goto(self.pos)))
4790 self.exc_value.set_var(exc_vars[1])
4791 self.exc_value.generate_evaluation_code(code)
4792 self.target.generate_assignment_code(self.exc_value, code)
4793 if self.excinfo_target is not None:
4794 for tempvar, node in zip(exc_vars, self.excinfo_tuple.args):
4795 node.set_var(tempvar)
4796 self.excinfo_tuple.generate_evaluation_code(code)
4797 self.excinfo_target.generate_assignment_code(self.excinfo_tuple, code)
4799 old_break_label, old_continue_label = code.break_label, code.continue_label
4800 code.break_label = code.new_label('except_break')
4801 code.continue_label = code.new_label('except_continue')
4803 old_exc_vars = code.funcstate.exc_vars
4804 code.funcstate.exc_vars = exc_vars
4805 self.body.generate_execution_code(code)
4806 code.funcstate.exc_vars = old_exc_vars
4807 for var in exc_vars:
4808 code.putln("__Pyx_DECREF(%s); %s = 0;" % (var, var))
4809 code.put_goto(end_label)
4811 if code.label_used(code.break_label):
4812 code.put_label(code.break_label)
4813 for var in exc_vars:
4814 code.putln("__Pyx_DECREF(%s); %s = 0;" % (var, var))
4815 code.put_goto(old_break_label)
4816 code.break_label = old_break_label
4818 if code.label_used(code.continue_label):
4819 code.put_label(code.continue_label)
4820 for var in exc_vars:
4821 code.putln("__Pyx_DECREF(%s); %s = 0;" % (var, var))
4822 code.put_goto(old_continue_label)
4823 code.continue_label = old_continue_label
4825 for temp in exc_vars:
4826 code.funcstate.release_temp(temp)
4831 def generate_function_definitions(self, env, code):
4832 if self.target is not None:
4833 self.target.generate_function_definitions(env, code)
4834 self.body.generate_function_definitions(env, code)
4836 def annotate(self, code):
4838 for pattern in self.pattern:
4839 pattern.annotate(code)
4841 self.target.annotate(code)
4842 self.body.annotate(code)
4845 class TryFinallyStatNode(StatNode):
4846 # try ... finally statement
4849 # finally_clause StatNode
4851 # The plan is that we funnel all continue, break
4852 # return and error gotos into the beginning of the
4853 # finally block, setting a variable to remember which
4854 # one we're doing. At the end of the finally block, we
4855 # switch on the variable to figure out where to go.
4856 # In addition, if we're doing an error, we save the
4857 # exception on entry to the finally block and restore
4860 child_attrs = ["body", "finally_clause"]
4862 preserve_exception = 1
4864 disallow_continue_in_try_finally = 0
4865 # There doesn't seem to be any point in disallowing
4866 # continue in the try block, since we have no problem
4869 def create_analysed(pos, env, body, finally_clause):
4870 node = TryFinallyStatNode(pos, body=body, finally_clause=finally_clause)
4872 create_analysed = staticmethod(create_analysed)
4874 def analyse_control_flow(self, env):
4875 env.start_branching(self.pos)
4876 self.body.analyse_control_flow(env)
4877 env.next_branch(self.body.end_pos())
4878 env.finish_branching(self.body.end_pos())
4879 self.finally_clause.analyse_control_flow(env)
4881 def analyse_declarations(self, env):
4882 self.body.analyse_declarations(env)
4883 self.finally_clause.analyse_declarations(env)
4885 def analyse_expressions(self, env):
4886 self.body.analyse_expressions(env)
4887 self.finally_clause.analyse_expressions(env)
4889 nogil_check = Node.gil_error
4890 gil_message = "Try-finally statement"
4892 def generate_execution_code(self, code):
4893 old_error_label = code.error_label
4894 old_labels = code.all_new_labels()
4895 new_labels = code.get_all_labels()
4896 new_error_label = code.error_label
4897 catch_label = code.new_label()
4900 if self.disallow_continue_in_try_finally:
4901 was_in_try_finally = code.funcstate.in_try_finally
4902 code.funcstate.in_try_finally = 1
4903 self.body.generate_execution_code(code)
4904 if self.disallow_continue_in_try_finally:
4905 code.funcstate.in_try_finally = was_in_try_finally
4908 temps_to_clean_up = code.funcstate.all_free_managed_temps()
4909 code.mark_pos(self.finally_clause.pos)
4913 error_label_used = 0
4914 for i, new_label in enumerate(new_labels):
4915 if new_label in code.labels_used:
4916 cases_used.append(i)
4917 if new_label == new_error_label:
4918 error_label_used = 1
4919 error_label_case = i
4923 if error_label_used and self.preserve_exception:
4925 "PyObject *%s, *%s, *%s;" % Naming.exc_vars)
4927 "int %s;" % Naming.exc_lineno_name)
4928 exc_var_init_zero = ''.join(["%s = 0; " % var for var in Naming.exc_vars])
4929 exc_var_init_zero += '%s = 0;' % Naming.exc_lineno_name
4930 code.putln(exc_var_init_zero)
4932 exc_var_init_zero = None
4933 code.use_label(catch_label)
4935 "__pyx_why = 0; goto %s;" % catch_label)
4936 for i in cases_used:
4937 new_label = new_labels[i]
4938 #if new_label and new_label != "<try>":
4939 if new_label == new_error_label and self.preserve_exception:
4940 self.put_error_catcher(code,
4941 new_error_label, i+1, catch_label, temps_to_clean_up)
4943 code.put('%s: ' % new_label)
4944 if exc_var_init_zero:
4945 code.putln(exc_var_init_zero)
4946 code.putln("__pyx_why = %s; goto %s;" % (
4949 code.put_label(catch_label)
4950 code.set_all_labels(old_labels)
4951 if error_label_used:
4952 code.new_error_label()
4953 finally_error_label = code.error_label
4954 self.finally_clause.generate_execution_code(code)
4955 if error_label_used:
4956 if finally_error_label in code.labels_used and self.preserve_exception:
4957 over_label = code.new_label()
4958 code.put_goto(over_label);
4959 code.put_label(finally_error_label)
4960 code.putln("if (__pyx_why == %d) {" % (error_label_case + 1))
4961 for var in Naming.exc_vars:
4962 code.putln("Py_XDECREF(%s);" % var)
4964 code.put_goto(old_error_label)
4965 code.put_label(over_label)
4966 code.error_label = old_error_label
4969 "switch (__pyx_why) {")
4970 for i in cases_used:
4971 old_label = old_labels[i]
4972 if old_label == old_error_label and self.preserve_exception:
4973 self.put_error_uncatcher(code, i+1, old_error_label)
4975 code.use_label(old_label)
4977 "case %s: goto %s;" % (
4985 def generate_function_definitions(self, env, code):
4986 self.body.generate_function_definitions(env, code)
4987 self.finally_clause.generate_function_definitions(env, code)
4989 def put_error_catcher(self, code, error_label, i, catch_label, temps_to_clean_up):
4990 code.globalstate.use_utility_code(restore_exception_utility_code)
4997 for temp_name, type in temps_to_clean_up:
4998 code.put_xdecref_clear(temp_name, type)
5000 "__Pyx_ErrFetch(&%s, &%s, &%s);" %
5004 Naming.exc_lineno_name, Naming.lineno_cname))
5005 code.put_goto(catch_label)
5008 def put_error_uncatcher(self, code, i, error_label):
5009 code.globalstate.use_utility_code(restore_exception_utility_code)
5014 "__Pyx_ErrRestore(%s, %s, %s);" %
5018 Naming.lineno_cname, Naming.exc_lineno_name))
5019 for var in Naming.exc_vars:
5023 code.put_goto(error_label)
5027 def annotate(self, code):
5028 self.body.annotate(code)
5029 self.finally_clause.annotate(code)
5032 class GILStatNode(TryFinallyStatNode):
5033 # 'with gil' or 'with nogil' statement
5035 # state string 'gil' or 'nogil'
5039 preserve_exception = 0
5041 def __init__(self, pos, state, body):
5043 TryFinallyStatNode.__init__(self, pos,
5045 finally_clause = GILExitNode(pos, state = state))
5047 def analyse_expressions(self, env):
5048 env.use_utility_code(force_init_threads_utility_code)
5049 was_nogil = env.nogil
5051 TryFinallyStatNode.analyse_expressions(self, env)
5052 env.nogil = was_nogil
5056 def generate_execution_code(self, code):
5057 code.mark_pos(self.pos)
5059 if self.state == 'gil':
5060 code.putln("#ifdef WITH_THREAD")
5061 code.putln("PyGILState_STATE _save = PyGILState_Ensure();")
5062 code.putln("#endif")
5064 code.putln("#ifdef WITH_THREAD")
5065 code.putln("PyThreadState *_save;")
5066 code.putln("#endif")
5067 code.putln("Py_UNBLOCK_THREADS")
5068 TryFinallyStatNode.generate_execution_code(self, code)
5072 class GILExitNode(StatNode):
5073 # Used as the 'finally' block in a GILStatNode
5075 # state string 'gil' or 'nogil'
5079 def analyse_expressions(self, env):
5082 def generate_execution_code(self, code):
5083 if self.state == 'gil':
5084 code.putln("#ifdef WITH_THREAD")
5085 code.putln("PyGILState_Release(_save);")
5086 code.putln("#endif")
5088 code.putln("Py_BLOCK_THREADS")
5091 class CImportStatNode(StatNode):
5094 # module_name string Qualified name of module being imported
5095 # as_name string or None Name specified in "as" clause, if any
5099 def analyse_declarations(self, env):
5100 if not env.is_module_scope:
5101 error(self.pos, "cimport only allowed at module level")
5103 module_scope = env.find_module(self.module_name, self.pos)
5104 if "." in self.module_name:
5105 names = [EncodedString(name) for name in self.module_name.split(".")]
5107 top_module_scope = env.context.find_submodule(top_name)
5108 module_scope = top_module_scope
5109 for name in names[1:]:
5110 submodule_scope = module_scope.find_submodule(name)
5111 module_scope.declare_module(name, submodule_scope, self.pos)
5112 module_scope = submodule_scope
5114 env.declare_module(self.as_name, module_scope, self.pos)
5116 env.declare_module(top_name, top_module_scope, self.pos)
5118 name = self.as_name or self.module_name
5119 env.declare_module(name, module_scope, self.pos)
5121 def analyse_expressions(self, env):
5124 def generate_execution_code(self, code):
5128 class FromCImportStatNode(StatNode):
5129 # from ... cimport statement
5131 # module_name string Qualified name of module
5132 # imported_names [(pos, name, as_name, kind)] Names to be imported
5136 def analyse_declarations(self, env):
5137 if not env.is_module_scope:
5138 error(self.pos, "cimport only allowed at module level")
5140 module_scope = env.find_module(self.module_name, self.pos)
5141 env.add_imported_module(module_scope)
5142 for pos, name, as_name, kind in self.imported_names:
5144 for local_name, entry in module_scope.entries.items():
5145 env.add_imported_entry(local_name, entry, pos)
5147 entry = module_scope.lookup(name)
5149 if kind and not self.declaration_matches(entry, kind):
5150 entry.redeclared(pos)
5152 if kind == 'struct' or kind == 'union':
5153 entry = module_scope.declare_struct_or_union(name,
5154 kind = kind, scope = None, typedef_flag = 0, pos = pos)
5155 elif kind == 'class':
5156 entry = module_scope.declare_c_class(name, pos = pos,
5157 module_name = self.module_name)
5159 submodule_scope = env.context.find_module(name, relative_to = module_scope, pos = self.pos)
5160 if submodule_scope.parent_module is module_scope:
5161 env.declare_module(as_name or name, submodule_scope, self.pos)
5163 error(pos, "Name '%s' not declared in module '%s'"
5164 % (name, self.module_name))
5167 local_name = as_name or name
5168 env.add_imported_entry(local_name, entry, pos)
5170 def declaration_matches(self, entry, kind):
5171 if not entry.is_type:
5175 if not type.is_extension_type:
5178 if not type.is_struct_or_union:
5180 if kind != type.kind:
5184 def analyse_expressions(self, env):
5187 def generate_execution_code(self, code):
5191 class FromImportStatNode(StatNode):
5192 # from ... import statement
5195 # items [(string, NameNode)]
5196 # interned_items [(string, NameNode, ExprNode)]
5197 # item PyTempNode used internally
5198 # import_star boolean used internally
5200 child_attrs = ["module"]
5203 def analyse_declarations(self, env):
5204 for name, target in self.items:
5206 if not env.is_module_scope:
5207 error(self.pos, "import * only allowed at module level")
5209 env.has_import_star = 1
5210 self.import_star = 1
5212 target.analyse_target_declaration(env)
5214 def analyse_expressions(self, env):
5216 self.module.analyse_expressions(env)
5217 self.item = ExprNodes.RawCNameExprNode(self.pos, py_object_type)
5218 self.interned_items = []
5219 for name, target in self.items:
5221 for _, entry in env.entries.items():
5222 if not entry.is_type and entry.type.is_extension_type:
5223 env.use_utility_code(ExprNodes.type_test_utility_code)
5226 entry = env.lookup(target.name)
5227 # check whether or not entry is already cimported
5228 if (entry.is_type and entry.type.name == name
5229 and hasattr(entry.type, 'module_name')):
5230 if entry.type.module_name == self.module.module_name.value:
5231 # cimported with absolute name
5234 # cimported with relative name
5235 module = env.find_module(self.module.module_name.value,
5237 if entry.type.module_name == module.qualified_name:
5239 except AttributeError:
5241 target.analyse_target_expression(env, None)
5242 if target.type is py_object_type:
5245 coerced_item = self.item.coerce_to(target.type, env)
5246 self.interned_items.append((name, target, coerced_item))
5248 def generate_execution_code(self, code):
5249 self.module.generate_evaluation_code(code)
5250 if self.import_star:
5252 'if (%s(%s) < 0) %s;' % (
5254 self.module.py_result(),
5255 code.error_goto(self.pos)))
5256 item_temp = code.funcstate.allocate_temp(py_object_type, manage_ref=True)
5257 self.item.set_cname(item_temp)
5258 for name, target, coerced_item in self.interned_items:
5259 cname = code.intern_identifier(name)
5261 '%s = PyObject_GetAttr(%s, %s); %s' % (
5263 self.module.py_result(),
5265 code.error_goto_if_null(item_temp, self.pos)))
5266 code.put_gotref(item_temp)
5267 if coerced_item is None:
5268 target.generate_assignment_code(self.item, code)
5270 coerced_item.allocate_temp_result(code)
5271 coerced_item.generate_result_code(code)
5272 target.generate_assignment_code(coerced_item, code)
5273 code.put_decref_clear(item_temp, py_object_type)
5274 code.funcstate.release_temp(item_temp)
5275 self.module.generate_disposal_code(code)
5276 self.module.free_temps(code)
5280 #------------------------------------------------------------------------------------
5282 # Runtime support code
5284 #------------------------------------------------------------------------------------
5286 utility_function_predeclarations = \
5288 /* inline attribute */
5289 #ifndef CYTHON_INLINE
5290 #if defined(__GNUC__)
5291 #define CYTHON_INLINE __inline__
5292 #elif defined(_MSC_VER)
5293 #define CYTHON_INLINE __inline
5294 #elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
5295 #define CYTHON_INLINE inline
5297 #define CYTHON_INLINE
5301 /* unused attribute */
5302 #ifndef CYTHON_UNUSED
5303 # if defined(__GNUC__)
5304 # if !(defined(__cplusplus)) || (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4))
5305 # define CYTHON_UNUSED __attribute__ ((__unused__))
5307 # define CYTHON_UNUSED
5309 # elif defined(__ICC) || defined(__INTEL_COMPILER)
5310 # define CYTHON_UNUSED __attribute__ ((__unused__))
5312 # define CYTHON_UNUSED
5316 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*/
5320 if Options.gcc_branch_hints:
5321 branch_prediction_macros = \
5324 /* Test for GCC > 2.95 */
5325 #if __GNUC__ > 2 || (__GNUC__ == 2 && (__GNUC_MINOR__ > 95))
5326 #define likely(x) __builtin_expect(!!(x), 1)
5327 #define unlikely(x) __builtin_expect(!!(x), 0)
5328 #else /* __GNUC__ > 2 ... */
5329 #define likely(x) (x)
5330 #define unlikely(x) (x)
5331 #endif /* __GNUC__ > 2 ... */
5332 #else /* __GNUC__ */
5333 #define likely(x) (x)
5334 #define unlikely(x) (x)
5335 #endif /* __GNUC__ */
5338 branch_prediction_macros = \
5340 #define likely(x) (x)
5341 #define unlikely(x) (x)
5344 #get_name_predeclaration = \
5345 #"static PyObject *__Pyx_GetName(PyObject *dict, char *name); /*proto*/"
5347 #get_name_interned_predeclaration = \
5348 #"static PyObject *__Pyx_GetName(PyObject *dict, PyObject *name); /*proto*/"
5350 #------------------------------------------------------------------------------------
5352 printing_utility_code = UtilityCode(
5354 static int __Pyx_Print(PyObject*, PyObject *, int); /*proto*/
5355 #if PY_MAJOR_VERSION >= 3
5356 static PyObject* %s = 0;
5357 static PyObject* %s = 0;
5359 """ % (Naming.print_function, Naming.print_function_kwargs),
5361 #if PY_MAJOR_VERSION >= 3
5365 """ % (Naming.print_function, Naming.print_function_kwargs),
5367 #if PY_MAJOR_VERSION < 3
5368 static PyObject *__Pyx_GetStdout(void) {
5369 PyObject *f = PySys_GetObject((char *)"stdout");
5371 PyErr_SetString(PyExc_RuntimeError, "lost sys.stdout");
5376 static int __Pyx_Print(PyObject* f, PyObject *arg_tuple, int newline) {
5381 if (!(f = __Pyx_GetStdout()))
5384 for (i=0; i < PyTuple_GET_SIZE(arg_tuple); i++) {
5385 if (PyFile_SoftSpace(f, 1)) {
5386 if (PyFile_WriteString(" ", f) < 0)
5389 v = PyTuple_GET_ITEM(arg_tuple, i);
5390 if (PyFile_WriteObject(v, f, Py_PRINT_RAW) < 0)
5392 if (PyString_Check(v)) {
5393 char *s = PyString_AsString(v);
5394 Py_ssize_t len = PyString_Size(v);
5396 isspace(Py_CHARMASK(s[len-1])) &&
5398 PyFile_SoftSpace(f, 0);
5402 if (PyFile_WriteString("\n", f) < 0)
5404 PyFile_SoftSpace(f, 0);
5409 #else /* Python 3 has a print function */
5411 static int __Pyx_Print(PyObject* stream, PyObject *arg_tuple, int newline) {
5412 PyObject* kwargs = 0;
5413 PyObject* result = 0;
5414 PyObject* end_string;
5415 if (unlikely(!%(PRINT_FUNCTION)s)) {
5416 %(PRINT_FUNCTION)s = __Pyx_GetAttrString(%(BUILTINS)s, "print");
5417 if (!%(PRINT_FUNCTION)s)
5421 kwargs = PyDict_New();
5422 if (unlikely(!kwargs))
5424 if (unlikely(PyDict_SetItemString(kwargs, "file", stream) < 0))
5427 end_string = PyUnicode_FromStringAndSize(" ", 1);
5428 if (unlikely(!end_string))
5430 if (PyDict_SetItemString(kwargs, "end", end_string) < 0) {
5431 Py_DECREF(end_string);
5434 Py_DECREF(end_string);
5436 } else if (!newline) {
5437 if (unlikely(!%(PRINT_KWARGS)s)) {
5438 %(PRINT_KWARGS)s = PyDict_New();
5439 if (unlikely(!%(PRINT_KWARGS)s))
5441 end_string = PyUnicode_FromStringAndSize(" ", 1);
5442 if (unlikely(!end_string))
5444 if (PyDict_SetItemString(%(PRINT_KWARGS)s, "end", end_string) < 0) {
5445 Py_DECREF(end_string);
5448 Py_DECREF(end_string);
5450 kwargs = %(PRINT_KWARGS)s;
5452 result = PyObject_Call(%(PRINT_FUNCTION)s, arg_tuple, kwargs);
5453 if (unlikely(kwargs) && (kwargs != %(PRINT_KWARGS)s))
5460 if (kwargs != %(PRINT_KWARGS)s)
5466 """ % {'BUILTINS' : Naming.builtins_cname,
5467 'PRINT_FUNCTION' : Naming.print_function,
5468 'PRINT_KWARGS' : Naming.print_function_kwargs}
5472 printing_one_utility_code = UtilityCode(
5474 static int __Pyx_PrintOne(PyObject* stream, PyObject *o); /*proto*/
5477 #if PY_MAJOR_VERSION < 3
5479 static int __Pyx_PrintOne(PyObject* f, PyObject *o) {
5481 if (!(f = __Pyx_GetStdout()))
5484 if (PyFile_SoftSpace(f, 0)) {
5485 if (PyFile_WriteString(" ", f) < 0)
5488 if (PyFile_WriteObject(o, f, Py_PRINT_RAW) < 0)
5490 if (PyFile_WriteString("\n", f) < 0)
5493 /* the line below is just to avoid compiler
5494 * compiler warnings about unused functions */
5495 return __Pyx_Print(f, NULL, 0);
5498 #else /* Python 3 has a print function */
5500 static int __Pyx_PrintOne(PyObject* stream, PyObject *o) {
5502 PyObject* arg_tuple = PyTuple_New(1);
5503 if (unlikely(!arg_tuple))
5506 PyTuple_SET_ITEM(arg_tuple, 0, o);
5507 res = __Pyx_Print(stream, arg_tuple, 1);
5508 Py_DECREF(arg_tuple);
5514 requires=[printing_utility_code])
5518 #------------------------------------------------------------------------------------
5520 # Exception raising code
5522 # Exceptions are raised by __Pyx_Raise() and stored as plain
5523 # type/value/tb in PyThreadState->curexc_*. When being caught by an
5524 # 'except' statement, curexc_* is moved over to exc_* by
5525 # __Pyx_GetException()
5527 restore_exception_utility_code = UtilityCode(
5529 static CYTHON_INLINE void __Pyx_ErrRestore(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
5530 static CYTHON_INLINE void __Pyx_ErrFetch(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
5533 static CYTHON_INLINE void __Pyx_ErrRestore(PyObject *type, PyObject *value, PyObject *tb) {
5534 PyObject *tmp_type, *tmp_value, *tmp_tb;
5535 PyThreadState *tstate = PyThreadState_GET();
5537 tmp_type = tstate->curexc_type;
5538 tmp_value = tstate->curexc_value;
5539 tmp_tb = tstate->curexc_traceback;
5540 tstate->curexc_type = type;
5541 tstate->curexc_value = value;
5542 tstate->curexc_traceback = tb;
5543 Py_XDECREF(tmp_type);
5544 Py_XDECREF(tmp_value);
5548 static CYTHON_INLINE void __Pyx_ErrFetch(PyObject **type, PyObject **value, PyObject **tb) {
5549 PyThreadState *tstate = PyThreadState_GET();
5550 *type = tstate->curexc_type;
5551 *value = tstate->curexc_value;
5552 *tb = tstate->curexc_traceback;
5554 tstate->curexc_type = 0;
5555 tstate->curexc_value = 0;
5556 tstate->curexc_traceback = 0;
5561 # The following function is based on do_raise() from ceval.c. There
5562 # are separate versions for Python2 and Python3 as exception handling
5563 # has changed quite a lot between the two versions.
5565 raise_utility_code = UtilityCode(
5567 static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
5570 #if PY_MAJOR_VERSION < 3
5571 static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb) {
5575 /* First, check the traceback argument, replacing None with NULL. */
5576 if (tb == Py_None) {
5580 else if (tb != NULL && !PyTraceBack_Check(tb)) {
5581 PyErr_SetString(PyExc_TypeError,
5582 "raise: arg 3 must be a traceback or None");
5585 /* Next, replace a missing value with None */
5586 if (value == NULL) {
5590 #if PY_VERSION_HEX < 0x02050000
5591 if (!PyClass_Check(type))
5593 if (!PyType_Check(type))
5596 /* Raising an instance. The value should be a dummy. */
5597 if (value != Py_None) {
5598 PyErr_SetString(PyExc_TypeError,
5599 "instance exception may not have a separate value");
5602 /* Normalize to raise <class>, <instance> */
5605 #if PY_VERSION_HEX < 0x02050000
5606 if (PyInstance_Check(type)) {
5607 type = (PyObject*) ((PyInstanceObject*)type)->in_class;
5612 PyErr_SetString(PyExc_TypeError,
5613 "raise: exception must be an old-style class or instance");
5617 type = (PyObject*) Py_TYPE(type);
5619 if (!PyType_IsSubtype((PyTypeObject *)type, (PyTypeObject *)PyExc_BaseException)) {
5620 PyErr_SetString(PyExc_TypeError,
5621 "raise: exception class must be a subclass of BaseException");
5627 __Pyx_ErrRestore(type, value, tb);
5636 #else /* Python 3+ */
5638 static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb) {
5639 if (tb == Py_None) {
5641 } else if (tb && !PyTraceBack_Check(tb)) {
5642 PyErr_SetString(PyExc_TypeError,
5643 "raise: arg 3 must be a traceback or None");
5646 if (value == Py_None)
5649 if (PyExceptionInstance_Check(type)) {
5651 PyErr_SetString(PyExc_TypeError,
5652 "instance exception may not have a separate value");
5656 type = (PyObject*) Py_TYPE(value);
5657 } else if (!PyExceptionClass_Check(type)) {
5658 PyErr_SetString(PyExc_TypeError,
5659 "raise: exception class must be a subclass of BaseException");
5663 PyErr_SetObject(type, value);
5666 PyThreadState *tstate = PyThreadState_GET();
5667 PyObject* tmp_tb = tstate->curexc_traceback;
5670 tstate->curexc_traceback = tb;
5680 requires=[restore_exception_utility_code])
5682 #------------------------------------------------------------------------------------
5684 get_exception_utility_code = UtilityCode(
5686 static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
5689 static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb) {
5690 PyObject *local_type, *local_value, *local_tb;
5691 PyObject *tmp_type, *tmp_value, *tmp_tb;
5692 PyThreadState *tstate = PyThreadState_GET();
5693 local_type = tstate->curexc_type;
5694 local_value = tstate->curexc_value;
5695 local_tb = tstate->curexc_traceback;
5696 tstate->curexc_type = 0;
5697 tstate->curexc_value = 0;
5698 tstate->curexc_traceback = 0;
5699 PyErr_NormalizeException(&local_type, &local_value, &local_tb);
5700 if (unlikely(tstate->curexc_type))
5702 #if PY_MAJOR_VERSION >= 3
5703 if (unlikely(PyException_SetTraceback(local_value, local_tb) < 0))
5707 *value = local_value;
5709 Py_INCREF(local_type);
5710 Py_INCREF(local_value);
5711 Py_INCREF(local_tb);
5712 tmp_type = tstate->exc_type;
5713 tmp_value = tstate->exc_value;
5714 tmp_tb = tstate->exc_traceback;
5715 tstate->exc_type = local_type;
5716 tstate->exc_value = local_value;
5717 tstate->exc_traceback = local_tb;
5718 /* Make sure tstate is in a consistent state when we XDECREF
5719 these objects (XDECREF may run arbitrary code). */
5720 Py_XDECREF(tmp_type);
5721 Py_XDECREF(tmp_value);
5728 Py_XDECREF(local_type);
5729 Py_XDECREF(local_value);
5730 Py_XDECREF(local_tb);
5736 #------------------------------------------------------------------------------------
5738 get_exception_tuple_utility_code = UtilityCode(proto="""
5739 static PyObject *__Pyx_GetExceptionTuple(void); /*proto*/
5741 # I doubt that calling __Pyx_GetException() here is correct as it moves
5742 # the exception from tstate->curexc_* to tstate->exc_*, which prevents
5743 # exception handlers later on from receiving it.
5745 static PyObject *__Pyx_GetExceptionTuple(void) {
5746 PyObject *type = NULL, *value = NULL, *tb = NULL;
5747 if (__Pyx_GetException(&type, &value, &tb) == 0) {
5748 PyObject* exc_info = PyTuple_New(3);
5753 PyTuple_SET_ITEM(exc_info, 0, type);
5754 PyTuple_SET_ITEM(exc_info, 1, value);
5755 PyTuple_SET_ITEM(exc_info, 2, tb);
5762 requires=[get_exception_utility_code])
5764 #------------------------------------------------------------------------------------
5766 reset_exception_utility_code = UtilityCode(
5768 static CYTHON_INLINE void __Pyx_ExceptionSave(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
5769 static void __Pyx_ExceptionReset(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
5772 static CYTHON_INLINE void __Pyx_ExceptionSave(PyObject **type, PyObject **value, PyObject **tb) {
5773 PyThreadState *tstate = PyThreadState_GET();
5774 *type = tstate->exc_type;
5775 *value = tstate->exc_value;
5776 *tb = tstate->exc_traceback;
5782 static void __Pyx_ExceptionReset(PyObject *type, PyObject *value, PyObject *tb) {
5783 PyObject *tmp_type, *tmp_value, *tmp_tb;
5784 PyThreadState *tstate = PyThreadState_GET();
5785 tmp_type = tstate->exc_type;
5786 tmp_value = tstate->exc_value;
5787 tmp_tb = tstate->exc_traceback;
5788 tstate->exc_type = type;
5789 tstate->exc_value = value;
5790 tstate->exc_traceback = tb;
5791 Py_XDECREF(tmp_type);
5792 Py_XDECREF(tmp_value);
5797 #------------------------------------------------------------------------------------
5799 arg_type_test_utility_code = UtilityCode(
5801 static int __Pyx_ArgTypeTest(PyObject *obj, PyTypeObject *type, int none_allowed,
5802 const char *name, int exact); /*proto*/
5805 static int __Pyx_ArgTypeTest(PyObject *obj, PyTypeObject *type, int none_allowed,
5806 const char *name, int exact)
5809 PyErr_Format(PyExc_SystemError, "Missing type object");
5812 if (none_allowed && obj == Py_None) return 1;
5814 if (Py_TYPE(obj) == type) return 1;
5817 if (PyObject_TypeCheck(obj, type)) return 1;
5819 PyErr_Format(PyExc_TypeError,
5820 "Argument '%s' has incorrect type (expected %s, got %s)",
5821 name, type->tp_name, Py_TYPE(obj)->tp_name);
5826 #------------------------------------------------------------------------------------
5828 # __Pyx_RaiseArgtupleInvalid raises the correct exception when too
5829 # many or too few positional arguments were found. This handles
5830 # Py_ssize_t formatting correctly.
5832 raise_argtuple_invalid_utility_code = UtilityCode(
5834 static void __Pyx_RaiseArgtupleInvalid(const char* func_name, int exact,
5835 Py_ssize_t num_min, Py_ssize_t num_max, Py_ssize_t num_found); /*proto*/
5838 static void __Pyx_RaiseArgtupleInvalid(
5839 const char* func_name,
5843 Py_ssize_t num_found)
5845 Py_ssize_t num_expected;
5846 const char *number, *more_or_less;
5848 if (num_found < num_min) {
5849 num_expected = num_min;
5850 more_or_less = "at least";
5852 num_expected = num_max;
5853 more_or_less = "at most";
5856 more_or_less = "exactly";
5858 number = (num_expected == 1) ? "" : "s";
5859 PyErr_Format(PyExc_TypeError,
5860 #if PY_VERSION_HEX < 0x02050000
5861 "%s() takes %s %d positional argument%s (%d given)",
5863 "%s() takes %s %zd positional argument%s (%zd given)",
5865 func_name, more_or_less, num_expected, number, num_found);
5869 raise_keyword_required_utility_code = UtilityCode(
5871 static CYTHON_INLINE void __Pyx_RaiseKeywordRequired(const char* func_name, PyObject* kw_name); /*proto*/
5874 static CYTHON_INLINE void __Pyx_RaiseKeywordRequired(
5875 const char* func_name,
5878 PyErr_Format(PyExc_TypeError,
5879 #if PY_MAJOR_VERSION >= 3
5880 "%s() needs keyword-only argument %U", func_name, kw_name);
5882 "%s() needs keyword-only argument %s", func_name,
5883 PyString_AS_STRING(kw_name));
5888 raise_double_keywords_utility_code = UtilityCode(
5890 static void __Pyx_RaiseDoubleKeywordsError(
5891 const char* func_name, PyObject* kw_name); /*proto*/
5894 static void __Pyx_RaiseDoubleKeywordsError(
5895 const char* func_name,
5898 PyErr_Format(PyExc_TypeError,
5899 #if PY_MAJOR_VERSION >= 3
5900 "%s() got multiple values for keyword argument '%U'", func_name, kw_name);
5902 "%s() got multiple values for keyword argument '%s'", func_name,
5903 PyString_AS_STRING(kw_name));
5908 #------------------------------------------------------------------------------------
5910 # __Pyx_CheckKeywordStrings raises an error if non-string keywords
5911 # were passed to a function, or if any keywords were passed to a
5912 # function that does not accept them.
5914 keyword_string_check_utility_code = UtilityCode(
5916 static CYTHON_INLINE int __Pyx_CheckKeywordStrings(PyObject *kwdict,
5917 const char* function_name, int kw_allowed); /*proto*/
5920 static CYTHON_INLINE int __Pyx_CheckKeywordStrings(
5922 const char* function_name,
5927 while (PyDict_Next(kwdict, &pos, &key, 0)) {
5928 #if PY_MAJOR_VERSION < 3
5929 if (unlikely(!PyString_CheckExact(key)) && unlikely(!PyString_Check(key)))
5931 if (unlikely(!PyUnicode_CheckExact(key)) && unlikely(!PyUnicode_Check(key)))
5933 goto invalid_keyword_type;
5935 if ((!kw_allowed) && unlikely(key))
5936 goto invalid_keyword;
5938 invalid_keyword_type:
5939 PyErr_Format(PyExc_TypeError,
5940 "%s() keywords must be strings", function_name);
5943 PyErr_Format(PyExc_TypeError,
5944 #if PY_MAJOR_VERSION < 3
5945 "%s() got an unexpected keyword argument '%s'",
5946 function_name, PyString_AsString(key));
5948 "%s() got an unexpected keyword argument '%U'",
5949 function_name, key);
5955 #------------------------------------------------------------------------------------
5957 # __Pyx_ParseOptionalKeywords copies the optional/unknown keyword
5958 # arguments from the kwds dict into kwds2. If kwds2 is NULL, unknown
5959 # keywords will raise an invalid keyword error.
5961 # Three kinds of errors are checked: 1) non-string keywords, 2)
5962 # unexpected keywords and 3) overlap with positional arguments.
5964 # If num_posargs is greater 0, it denotes the number of positional
5965 # arguments that were passed and that must therefore not appear
5966 # amongst the keywords as well.
5968 # This method does not check for required keyword arguments.
5971 parse_keywords_utility_code = UtilityCode(
5973 static int __Pyx_ParseOptionalKeywords(PyObject *kwds, PyObject **argnames[], \
5974 PyObject *kwds2, PyObject *values[], Py_ssize_t num_pos_args, \
5975 const char* function_name); /*proto*/
5978 static int __Pyx_ParseOptionalKeywords(
5980 PyObject **argnames[],
5983 Py_ssize_t num_pos_args,
5984 const char* function_name)
5986 PyObject *key = 0, *value = 0;
5989 PyObject*** first_kw_arg = argnames + num_pos_args;
5991 while (PyDict_Next(kwds, &pos, &key, &value)) {
5992 name = first_kw_arg;
5993 while (*name && (**name != key)) name++;
5995 values[name-argnames] = value;
5997 #if PY_MAJOR_VERSION < 3
5998 if (unlikely(!PyString_CheckExact(key)) && unlikely(!PyString_Check(key))) {
6000 if (unlikely(!PyUnicode_CheckExact(key)) && unlikely(!PyUnicode_Check(key))) {
6002 goto invalid_keyword_type;
6004 for (name = first_kw_arg; *name; name++) {
6005 #if PY_MAJOR_VERSION >= 3
6006 if (PyUnicode_GET_SIZE(**name) == PyUnicode_GET_SIZE(key) &&
6007 PyUnicode_Compare(**name, key) == 0) break;
6009 if (PyString_GET_SIZE(**name) == PyString_GET_SIZE(key) &&
6010 _PyString_Eq(**name, key)) break;
6014 values[name-argnames] = value;
6016 /* unexpected keyword found */
6017 for (name=argnames; name != first_kw_arg; name++) {
6018 if (**name == key) goto arg_passed_twice;
6019 #if PY_MAJOR_VERSION >= 3
6020 if (PyUnicode_GET_SIZE(**name) == PyUnicode_GET_SIZE(key) &&
6021 PyUnicode_Compare(**name, key) == 0) goto arg_passed_twice;
6023 if (PyString_GET_SIZE(**name) == PyString_GET_SIZE(key) &&
6024 _PyString_Eq(**name, key)) goto arg_passed_twice;
6028 if (unlikely(PyDict_SetItem(kwds2, key, value))) goto bad;
6030 goto invalid_keyword;
6038 __Pyx_RaiseDoubleKeywordsError(function_name, **name);
6040 invalid_keyword_type:
6041 PyErr_Format(PyExc_TypeError,
6042 "%s() keywords must be strings", function_name);
6045 PyErr_Format(PyExc_TypeError,
6046 #if PY_MAJOR_VERSION < 3
6047 "%s() got an unexpected keyword argument '%s'",
6048 function_name, PyString_AsString(key));
6050 "%s() got an unexpected keyword argument '%U'",
6051 function_name, key);
6058 #------------------------------------------------------------------------------------
6060 traceback_utility_code = UtilityCode(
6062 static void __Pyx_AddTraceback(const char *funcname); /*proto*/
6065 #include "compile.h"
6066 #include "frameobject.h"
6067 #include "traceback.h"
6069 static void __Pyx_AddTraceback(const char *funcname) {
6070 PyObject *py_srcfile = 0;
6071 PyObject *py_funcname = 0;
6072 PyObject *py_globals = 0;
6073 PyCodeObject *py_code = 0;
6074 PyFrameObject *py_frame = 0;
6076 #if PY_MAJOR_VERSION < 3
6077 py_srcfile = PyString_FromString(%(FILENAME)s);
6079 py_srcfile = PyUnicode_FromString(%(FILENAME)s);
6081 if (!py_srcfile) goto bad;
6083 #if PY_MAJOR_VERSION < 3
6084 py_funcname = PyString_FromFormat( "%%s (%%s:%%d)", funcname, %(CFILENAME)s, %(CLINENO)s);
6086 py_funcname = PyUnicode_FromFormat( "%%s (%%s:%%d)", funcname, %(CFILENAME)s, %(CLINENO)s);
6090 #if PY_MAJOR_VERSION < 3
6091 py_funcname = PyString_FromString(funcname);
6093 py_funcname = PyUnicode_FromString(funcname);
6096 if (!py_funcname) goto bad;
6097 py_globals = PyModule_GetDict(%(GLOBALS)s);
6098 if (!py_globals) goto bad;
6099 py_code = PyCode_New(
6100 0, /*int argcount,*/
6101 #if PY_MAJOR_VERSION >= 3
6102 0, /*int kwonlyargcount,*/
6105 0, /*int stacksize,*/
6107 %(EMPTY_BYTES)s, /*PyObject *code,*/
6108 %(EMPTY_TUPLE)s, /*PyObject *consts,*/
6109 %(EMPTY_TUPLE)s, /*PyObject *names,*/
6110 %(EMPTY_TUPLE)s, /*PyObject *varnames,*/
6111 %(EMPTY_TUPLE)s, /*PyObject *freevars,*/
6112 %(EMPTY_TUPLE)s, /*PyObject *cellvars,*/
6113 py_srcfile, /*PyObject *filename,*/
6114 py_funcname, /*PyObject *name,*/
6115 %(LINENO)s, /*int firstlineno,*/
6116 %(EMPTY_BYTES)s /*PyObject *lnotab*/
6118 if (!py_code) goto bad;
6119 py_frame = PyFrame_New(
6120 PyThreadState_GET(), /*PyThreadState *tstate,*/
6121 py_code, /*PyCodeObject *code,*/
6122 py_globals, /*PyObject *globals,*/
6123 0 /*PyObject *locals*/
6125 if (!py_frame) goto bad;
6126 py_frame->f_lineno = %(LINENO)s;
6127 PyTraceBack_Here(py_frame);
6129 Py_XDECREF(py_srcfile);
6130 Py_XDECREF(py_funcname);
6131 Py_XDECREF(py_code);
6132 Py_XDECREF(py_frame);
6135 'FILENAME': Naming.filename_cname,
6136 'LINENO': Naming.lineno_cname,
6137 'CFILENAME': Naming.cfilenm_cname,
6138 'CLINENO': Naming.clineno_cname,
6139 'GLOBALS': Naming.module_cname,
6140 'EMPTY_TUPLE' : Naming.empty_tuple,
6141 'EMPTY_BYTES' : Naming.empty_bytes,
6144 #------------------------------------------------------------------------------------
6146 unraisable_exception_utility_code = UtilityCode(
6148 static void __Pyx_WriteUnraisable(const char *name); /*proto*/
6151 static void __Pyx_WriteUnraisable(const char *name) {
6152 PyObject *old_exc, *old_val, *old_tb;
6154 __Pyx_ErrFetch(&old_exc, &old_val, &old_tb);
6155 #if PY_MAJOR_VERSION < 3
6156 ctx = PyString_FromString(name);
6158 ctx = PyUnicode_FromString(name);
6160 __Pyx_ErrRestore(old_exc, old_val, old_tb);
6162 PyErr_WriteUnraisable(Py_None);
6164 PyErr_WriteUnraisable(ctx);
6169 requires=[restore_exception_utility_code])
6171 #------------------------------------------------------------------------------------
6173 set_vtable_utility_code = UtilityCode(
6175 static int __Pyx_SetVtable(PyObject *dict, void *vtable); /*proto*/
6178 static int __Pyx_SetVtable(PyObject *dict, void *vtable) {
6179 #if PY_VERSION_HEX >= 0x02070000 && !(PY_MAJOR_VERSION==3&&PY_MINOR_VERSION==0)
6180 PyObject *ob = PyCapsule_New(vtable, 0, 0);
6182 PyObject *ob = PyCObject_FromVoidPtr(vtable, 0);
6186 if (PyDict_SetItemString(dict, "__pyx_vtable__", ob) < 0)
6196 #------------------------------------------------------------------------------------
6198 get_vtable_utility_code = UtilityCode(
6200 static int __Pyx_GetVtable(PyObject *dict, void *vtabptr); /*proto*/
6203 static int __Pyx_GetVtable(PyObject *dict, void *vtabptr) {
6204 PyObject *ob = PyMapping_GetItemString(dict, (char *)"__pyx_vtable__");
6207 #if PY_VERSION_HEX >= 0x02070000 && !(PY_MAJOR_VERSION==3&&PY_MINOR_VERSION==0)
6208 *(void **)vtabptr = PyCapsule_GetPointer(ob, 0);
6210 *(void **)vtabptr = PyCObject_AsVoidPtr(ob);
6212 if (!*(void **)vtabptr)
6222 #------------------------------------------------------------------------------------
6224 init_string_tab_utility_code = UtilityCode(
6226 static int __Pyx_InitStrings(__Pyx_StringTabEntry *t); /*proto*/
6229 static int __Pyx_InitStrings(__Pyx_StringTabEntry *t) {
6231 #if PY_MAJOR_VERSION < 3
6232 if (t->is_unicode) {
6233 *t->p = PyUnicode_DecodeUTF8(t->s, t->n - 1, NULL);
6234 } else if (t->intern) {
6235 *t->p = PyString_InternFromString(t->s);
6237 *t->p = PyString_FromStringAndSize(t->s, t->n - 1);
6239 #else /* Python 3+ has unicode identifiers */
6240 if (t->is_unicode | t->is_str) {
6242 *t->p = PyUnicode_InternFromString(t->s);
6243 } else if (t->encoding) {
6244 *t->p = PyUnicode_Decode(t->s, t->n - 1, t->encoding, NULL);
6246 *t->p = PyUnicode_FromStringAndSize(t->s, t->n - 1);
6249 *t->p = PyBytes_FromStringAndSize(t->s, t->n - 1);
6260 #------------------------------------------------------------------------------------
6262 force_init_threads_utility_code = UtilityCode(
6264 #ifndef __PYX_FORCE_INIT_THREADS
6265 #if PY_VERSION_HEX < 0x02040200
6266 #define __PYX_FORCE_INIT_THREADS 1
6268 #define __PYX_FORCE_INIT_THREADS 0
6273 #------------------------------------------------------------------------------------
6275 # Note that cPython ignores PyTrace_EXCEPTION,
6276 # but maybe some other profilers don't.
6278 profile_utility_code = UtilityCode(proto="""
6279 #ifndef CYTHON_PROFILE
6280 #define CYTHON_PROFILE 1
6283 #ifndef CYTHON_PROFILE_REUSE_FRAME
6284 #define CYTHON_PROFILE_REUSE_FRAME 0
6289 #include "compile.h"
6290 #include "frameobject.h"
6291 #include "traceback.h"
6293 #if CYTHON_PROFILE_REUSE_FRAME
6294 #define CYTHON_FRAME_MODIFIER static
6295 #define CYTHON_FRAME_DEL
6297 #define CYTHON_FRAME_MODIFIER
6298 #define CYTHON_FRAME_DEL Py_DECREF(%(FRAME)s)
6301 #define __Pyx_TraceDeclarations \\
6302 static PyCodeObject *%(FRAME_CODE)s = NULL; \\
6303 CYTHON_FRAME_MODIFIER PyFrameObject *%(FRAME)s = NULL; \\
6304 int __Pyx_use_tracing = 0;
6306 #define __Pyx_TraceCall(funcname, srcfile, firstlineno) \\
6307 if (unlikely(PyThreadState_GET()->use_tracing && PyThreadState_GET()->c_profilefunc)) { \\
6308 __Pyx_use_tracing = __Pyx_TraceSetupAndCall(&%(FRAME_CODE)s, &%(FRAME)s, funcname, srcfile, firstlineno); \\
6311 #define __Pyx_TraceException() \\
6312 if (unlikely(__Pyx_use_tracing( && PyThreadState_GET()->use_tracing && PyThreadState_GET()->c_profilefunc) { \\
6313 PyObject *exc_info = __Pyx_GetExceptionTuple(); \\
6315 PyThreadState_GET()->c_profilefunc( \\
6316 PyThreadState_GET()->c_profileobj, %(FRAME)s, PyTrace_EXCEPTION, exc_info); \\
6317 Py_DECREF(exc_info); \\
6321 #define __Pyx_TraceReturn(result) \\
6322 if (unlikely(__Pyx_use_tracing) && PyThreadState_GET()->use_tracing && PyThreadState_GET()->c_profilefunc) { \\
6323 PyThreadState_GET()->c_profilefunc( \\
6324 PyThreadState_GET()->c_profileobj, %(FRAME)s, PyTrace_RETURN, (PyObject*)result); \\
6325 CYTHON_FRAME_DEL; \\
6328 static PyCodeObject *__Pyx_createFrameCodeObject(const char *funcname, const char *srcfile, int firstlineno); /*proto*/
6329 static int __Pyx_TraceSetupAndCall(PyCodeObject** code, PyFrameObject** frame, const char *funcname, const char *srcfile, int firstlineno); /*proto*/
6333 #define __Pyx_TraceDeclarations
6334 #define __Pyx_TraceCall(funcname, srcfile, firstlineno)
6335 #define __Pyx_TraceException()
6336 #define __Pyx_TraceReturn(result)
6338 #endif /* CYTHON_PROFILE */
6341 "FRAME": Naming.frame_cname,
6342 "FRAME_CODE": Naming.frame_code_cname,
6348 static int __Pyx_TraceSetupAndCall(PyCodeObject** code,
6349 PyFrameObject** frame,
6350 const char *funcname,
6351 const char *srcfile,
6353 if (*frame == NULL || !CYTHON_PROFILE_REUSE_FRAME) {
6354 if (*code == NULL) {
6355 *code = __Pyx_createFrameCodeObject(funcname, srcfile, firstlineno);
6356 if (*code == NULL) return 0;
6358 *frame = PyFrame_New(
6359 PyThreadState_GET(), /*PyThreadState *tstate*/
6360 *code, /*PyCodeObject *code*/
6361 PyModule_GetDict(%(MODULE)s), /*PyObject *globals*/
6362 0 /*PyObject *locals*/
6364 if (*frame == NULL) return 0;
6367 (*frame)->f_tstate = PyThreadState_GET();
6369 return PyThreadState_GET()->c_profilefunc(PyThreadState_GET()->c_profileobj, *frame, PyTrace_CALL, NULL) == 0;
6372 static PyCodeObject *__Pyx_createFrameCodeObject(const char *funcname, const char *srcfile, int firstlineno) {
6373 PyObject *py_srcfile = 0;
6374 PyObject *py_funcname = 0;
6375 PyCodeObject *py_code = 0;
6377 #if PY_MAJOR_VERSION < 3
6378 py_funcname = PyString_FromString(funcname);
6379 py_srcfile = PyString_FromString(srcfile);
6381 py_funcname = PyUnicode_FromString(funcname);
6382 py_srcfile = PyUnicode_FromString(srcfile);
6384 if (!py_funcname | !py_srcfile) goto bad;
6386 py_code = PyCode_New(
6387 0, /*int argcount,*/
6388 #if PY_MAJOR_VERSION >= 3
6389 0, /*int kwonlyargcount,*/
6392 0, /*int stacksize,*/
6394 %(EMPTY_BYTES)s, /*PyObject *code,*/
6395 %(EMPTY_TUPLE)s, /*PyObject *consts,*/
6396 %(EMPTY_TUPLE)s, /*PyObject *names,*/
6397 %(EMPTY_TUPLE)s, /*PyObject *varnames,*/
6398 %(EMPTY_TUPLE)s, /*PyObject *freevars,*/
6399 %(EMPTY_TUPLE)s, /*PyObject *cellvars,*/
6400 py_srcfile, /*PyObject *filename,*/
6401 py_funcname, /*PyObject *name,*/
6402 firstlineno, /*int firstlineno,*/
6403 %(EMPTY_BYTES)s /*PyObject *lnotab*/
6407 Py_XDECREF(py_srcfile);
6408 Py_XDECREF(py_funcname);
6413 #endif /* CYTHON_PROFILE */
6415 'EMPTY_TUPLE' : Naming.empty_tuple,
6416 'EMPTY_BYTES' : Naming.empty_bytes,
6417 "MODULE": Naming.module_cname,