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 = genv.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 # Find function scope
1260 while cenv.is_py_class_scope or cenv.is_c_class_scope:
1261 cenv = cenv.outer_scope
1262 if lenv.is_closure_scope:
1263 code.put(lenv.scope_class.type.declaration_code(Naming.cur_scope_cname))
1265 elif cenv.is_closure_scope:
1266 code.put(cenv.scope_class.type.declaration_code(Naming.outer_scope_cname))
1268 self.generate_argument_declarations(lenv, code)
1269 for entry in lenv.var_entries:
1270 if not entry.in_closure:
1271 code.put_var_declaration(entry)
1273 if not self.return_type.is_void:
1274 if self.return_type.is_pyobject:
1278 (self.return_type.declaration_code(Naming.retval_cname),
1280 tempvardecl_code = code.insertion_point()
1281 self.generate_keyword_list(code)
1283 code.put_trace_declarations()
1284 # ----- Extern library function declarations
1285 lenv.generate_library_function_declarations(code)
1286 # ----- GIL acquisition
1287 acquire_gil = self.acquire_gil
1289 env.use_utility_code(force_init_threads_utility_code)
1290 code.putln("#ifdef WITH_THREAD")
1291 code.putln("PyGILState_STATE _save = PyGILState_Ensure();")
1292 code.putln("#endif")
1293 # ----- set up refnanny
1295 code.put_setup_refcount_context(self.entry.name)
1296 # ----- Automatic lead-ins for certain special functions
1297 if is_getbuffer_slot:
1298 self.getbuffer_init(code)
1299 # ----- Create closure scope object
1300 if self.needs_closure:
1301 code.putln("%s = (%s)%s->tp_new(%s, %s, NULL);" % (
1302 Naming.cur_scope_cname,
1303 lenv.scope_class.type.declaration_code(''),
1304 lenv.scope_class.type.typeptr_cname,
1305 lenv.scope_class.type.typeptr_cname,
1306 Naming.empty_tuple))
1307 code.putln("if (unlikely(!%s)) {" % Naming.cur_scope_cname)
1308 if is_getbuffer_slot:
1309 self.getbuffer_error_cleanup(code)
1311 code.put_finish_refcount_context()
1312 # FIXME: what if the error return value is a Python value?
1313 code.putln("return %s;" % self.error_value())
1315 code.put_gotref(Naming.cur_scope_cname)
1316 # Note that it is unsafe to decref the scope at this point.
1317 if cenv.is_closure_scope:
1318 code.putln("%s = (%s)%s;" % (
1320 cenv.scope_class.type.declaration_code(''),
1322 if self.needs_closure:
1323 # inner closures own a reference to their outer parent
1324 code.put_incref(outer_scope_cname, cenv.scope_class.type)
1325 code.put_giveref(outer_scope_cname)
1326 # ----- Trace function call
1328 # this looks a bit late, but if we don't get here due to a
1329 # fatal error before hand, it's not really worth tracing
1330 code.put_trace_call(self.entry.name, self.pos)
1331 # ----- Fetch arguments
1332 self.generate_argument_parsing_code(env, code)
1333 # If an argument is assigned to in the body, we must
1334 # incref it to properly keep track of refcounts.
1335 for entry in lenv.arg_entries:
1336 if entry.type.is_pyobject:
1337 if entry.assignments and not entry.in_closure:
1338 code.put_var_incref(entry)
1339 # ----- Initialise local variables
1340 for entry in lenv.var_entries:
1341 if entry.type.is_pyobject and entry.init_to_none and entry.used:
1342 code.put_init_var_to_py_none(entry)
1343 # ----- Initialise local buffer auxiliary variables
1344 for entry in lenv.var_entries + lenv.arg_entries:
1345 if entry.type.is_buffer and entry.buffer_aux.buffer_info_var.used:
1346 code.putln("%s.buf = NULL;" %
1347 entry.buffer_aux.buffer_info_var.cname)
1348 # ----- Check and convert arguments
1349 self.generate_argument_type_tests(code)
1350 # ----- Acquire buffer arguments
1351 for entry in lenv.arg_entries:
1352 if entry.type.is_buffer:
1353 Buffer.put_acquire_arg_buffer(entry, code, self.pos)
1355 # -------------------------
1356 # ----- Function body -----
1357 # -------------------------
1358 self.body.generate_execution_code(code)
1360 # ----- Default return value
1362 if self.return_type.is_pyobject:
1363 #if self.return_type.is_extension_type:
1364 # lhs = "(PyObject *)%s" % Naming.retval_cname
1366 lhs = Naming.retval_cname
1367 code.put_init_to_py_none(lhs, self.return_type)
1369 val = self.return_type.default_value
1371 code.putln("%s = %s;" % (Naming.retval_cname, val))
1372 # ----- Error cleanup
1373 if code.error_label in code.labels_used:
1374 code.put_goto(code.return_label)
1375 code.put_label(code.error_label)
1376 for cname, type in code.funcstate.all_managed_temps():
1377 code.put_xdecref(cname, type)
1379 # Clean up buffers -- this calls a Python function
1380 # so need to save and restore error state
1381 buffers_present = len(lenv.buffer_entries) > 0
1383 code.globalstate.use_utility_code(restore_exception_utility_code)
1384 code.putln("{ PyObject *__pyx_type, *__pyx_value, *__pyx_tb;")
1385 code.putln("__Pyx_ErrFetch(&__pyx_type, &__pyx_value, &__pyx_tb);")
1386 for entry in lenv.buffer_entries:
1387 Buffer.put_release_buffer_code(code, entry)
1388 #code.putln("%s = 0;" % entry.cname)
1389 code.putln("__Pyx_ErrRestore(__pyx_type, __pyx_value, __pyx_tb);}")
1391 err_val = self.error_value()
1392 exc_check = self.caller_will_check_exceptions()
1393 if err_val is not None or exc_check:
1394 # TODO: Fix exception tracing (though currently unused by cProfile).
1395 # code.globalstate.use_utility_code(get_exception_tuple_utility_code)
1396 # code.put_trace_exception()
1397 code.putln('__Pyx_AddTraceback("%s");' % self.entry.qualified_name)
1399 warning(self.entry.pos, "Unraisable exception in function '%s'." \
1400 % self.entry.qualified_name, 0)
1402 '__Pyx_WriteUnraisable("%s");' %
1403 self.entry.qualified_name)
1404 env.use_utility_code(unraisable_exception_utility_code)
1405 env.use_utility_code(restore_exception_utility_code)
1406 default_retval = self.return_type.default_value
1407 if err_val is None and default_retval:
1408 err_val = default_retval
1409 if err_val is not None:
1410 code.putln("%s = %s;" % (Naming.retval_cname, err_val))
1412 if is_getbuffer_slot:
1413 self.getbuffer_error_cleanup(code)
1415 # If we are using the non-error cleanup section we should
1416 # jump past it if we have an error. The if-test below determine
1417 # whether this section is used.
1418 if buffers_present or is_getbuffer_slot:
1419 code.put_goto(code.return_from_error_cleanup_label)
1422 # ----- Non-error return cleanup
1423 code.put_label(code.return_label)
1424 for entry in lenv.buffer_entries:
1426 Buffer.put_release_buffer_code(code, entry)
1427 if is_getbuffer_slot:
1428 self.getbuffer_normal_cleanup(code)
1429 # ----- Return cleanup for both error and no-error return
1430 code.put_label(code.return_from_error_cleanup_label)
1431 if not Options.init_local_none:
1432 for entry in lenv.var_entries:
1433 if lenv.control_flow.get_state((entry.name, 'initialized')) is not True:
1434 entry.xdecref_cleanup = 1
1436 for entry in lenv.var_entries:
1437 if entry.type.is_pyobject:
1438 if entry.used and not entry.in_closure:
1439 code.put_var_decref(entry)
1440 elif entry.in_closure and self.needs_closure:
1441 code.put_giveref(entry.cname)
1442 # Decref any increfed args
1443 for entry in lenv.arg_entries:
1444 if entry.type.is_pyobject:
1445 if entry.in_closure:
1446 code.put_var_giveref(entry)
1447 elif entry.assignments:
1448 code.put_var_decref(entry)
1449 if self.needs_closure:
1450 code.put_decref(Naming.cur_scope_cname, lenv.scope_class.type)
1453 # This code is duplicated in ModuleNode.generate_module_init_func
1455 default_retval = self.return_type.default_value
1456 err_val = self.error_value()
1457 if err_val is None and default_retval:
1458 err_val = default_retval
1459 if self.return_type.is_pyobject:
1460 code.put_xgiveref(self.return_type.as_pyobject(Naming.retval_cname))
1462 if self.entry.is_special and self.entry.name == "__hash__":
1463 # Returning -1 for __hash__ is supposed to signal an error
1464 # We do as Python instances and coerce -1 into -2.
1465 code.putln("if (unlikely(%s == -1) && !PyErr_Occurred()) %s = -2;" % (
1466 Naming.retval_cname, Naming.retval_cname))
1469 if self.return_type.is_pyobject:
1470 code.put_trace_return(Naming.retval_cname)
1472 code.put_trace_return("Py_None")
1474 code.put_finish_refcount_context()
1477 code.putln("#ifdef WITH_THREAD")
1478 code.putln("PyGILState_Release(_save);")
1479 code.putln("#endif")
1481 if not self.return_type.is_void:
1482 code.putln("return %s;" % Naming.retval_cname)
1486 if preprocessor_guard:
1487 code.putln("#endif /*!(%s)*/" % preprocessor_guard)
1489 # ----- Go back and insert temp variable declarations
1490 tempvardecl_code.put_temp_declarations(code.funcstate)
1491 # ----- Python version
1492 code.exit_cfunc_scope()
1494 self.py_func.generate_function_definitions(env, code)
1495 self.generate_wrapper_functions(code)
1497 def declare_argument(self, env, arg):
1498 if arg.type.is_void:
1499 error(arg.pos, "Invalid use of 'void'")
1500 elif not arg.type.is_complete() and not arg.type.is_array:
1502 "Argument type '%s' is incomplete" % arg.type)
1503 return env.declare_arg(arg.name, arg.type, arg.pos)
1505 def generate_arg_type_test(self, arg, code):
1506 # Generate type test for one argument.
1507 if arg.type.typeobj_is_available():
1508 code.globalstate.use_utility_code(arg_type_test_utility_code)
1509 typeptr_cname = arg.type.typeptr_cname
1510 arg_code = "((PyObject *)%s)" % arg.entry.cname
1512 'if (unlikely(!__Pyx_ArgTypeTest(%s, %s, %d, "%s", %s))) %s' % (
1517 arg.type.is_builtin_type,
1518 code.error_goto(arg.pos)))
1520 error(arg.pos, "Cannot test type of extern C class "
1521 "without type object name specification")
1523 def generate_arg_none_check(self, arg, code):
1524 # Generate None check for one argument.
1525 code.globalstate.use_utility_code(arg_type_test_utility_code)
1526 code.putln('if (unlikely(((PyObject *)%s) == Py_None)) {' % arg.entry.cname)
1527 code.putln('''PyErr_Format(PyExc_TypeError, "Argument '%s' must not be None"); %s''' % (
1529 code.error_goto(arg.pos)))
1532 def generate_wrapper_functions(self, code):
1535 def generate_execution_code(self, code):
1536 # Evaluate and store argument default values
1537 for arg in self.args:
1538 default = arg.default
1540 if not default.is_literal:
1541 default.generate_evaluation_code(code)
1542 default.make_owned_reference(code)
1543 result = default.result_as(arg.type)
1546 arg.calculate_default_value_code(code),
1548 if arg.type.is_pyobject:
1549 code.put_giveref(default.result())
1550 default.generate_post_assignment_code(code)
1551 default.free_temps(code)
1552 # For Python class methods, create and store function object
1554 self.assmt.generate_execution_code(code)
1557 # Special code for the __getbuffer__ function
1559 def getbuffer_init(self, code):
1560 info = self.local_scope.arg_entries[1].cname
1561 # Python 3.0 betas have a bug in memoryview which makes it call
1562 # getbuffer with a NULL parameter. For now we work around this;
1563 # the following line should be removed when this bug is fixed.
1564 code.putln("if (%s == NULL) return 0;" % info)
1565 code.putln("%s->obj = Py_None; __Pyx_INCREF(Py_None);" % info)
1566 code.put_giveref("%s->obj" % info) # Do not refnanny object within structs
1568 def getbuffer_error_cleanup(self, code):
1569 info = self.local_scope.arg_entries[1].cname
1570 code.put_gotref("%s->obj" % info)
1571 code.putln("__Pyx_DECREF(%s->obj); %s->obj = NULL;" %
1574 def getbuffer_normal_cleanup(self, code):
1575 info = self.local_scope.arg_entries[1].cname
1576 code.putln("if (%s->obj == Py_None) {" % info)
1577 code.put_gotref("Py_None")
1578 code.putln("__Pyx_DECREF(Py_None); %s->obj = NULL;" % info)
1581 class CFuncDefNode(FuncDefNode):
1582 # C function definition.
1584 # modifiers ['inline']
1585 # visibility 'private' or 'public' or 'extern'
1586 # base_type CBaseTypeNode
1587 # declarator CDeclaratorNode
1590 # decorators [DecoratorNode] list of decorators
1592 # with_gil boolean Acquire GIL around body
1594 # py_func wrapper for calling from Python
1595 # overridable whether or not this is a cpdef function
1596 # inline_in_pxd whether this is an inline function in a pxd file
1598 child_attrs = ["base_type", "declarator", "body", "py_func"]
1600 inline_in_pxd = False
1602 directive_locals = {}
1604 def unqualified_name(self):
1605 return self.entry.name
1607 def analyse_declarations(self, env):
1608 self.directive_locals.update(env.directives['locals'])
1609 base_type = self.base_type.analyse(env)
1610 # The 2 here is because we need both function and argument names.
1611 name_declarator, type = self.declarator.analyse(base_type, env, nonempty = 2 * (self.body is not None))
1612 if not type.is_cfunction:
1614 "Suite attached to non-function declaration")
1615 # Remember the actual type according to the function header
1616 # written here, because the type in the symbol table entry
1617 # may be different if we're overriding a C method inherited
1618 # from the base type of an extension type.
1620 type.is_overridable = self.overridable
1621 declarator = self.declarator
1622 while not hasattr(declarator, 'args'):
1623 declarator = declarator.base
1624 self.args = declarator.args
1625 for formal_arg, type_arg in zip(self.args, type.args):
1626 formal_arg.type = type_arg.type
1627 formal_arg.name = type_arg.name
1628 formal_arg.cname = type_arg.cname
1629 name = name_declarator.name
1630 cname = name_declarator.cname
1631 self.entry = env.declare_cfunction(
1632 name, type, self.pos,
1633 cname = cname, visibility = self.visibility,
1634 defining = self.body is not None,
1635 api = self.api, modifiers = self.modifiers)
1636 self.entry.inline_func_in_pxd = self.inline_in_pxd
1637 self.return_type = type.return_type
1639 if self.overridable and not env.is_module_scope:
1640 if len(self.args) < 1 or not self.args[0].type.is_pyobject:
1641 # An error will be produced in the cdef function
1642 self.overridable = False
1644 if self.overridable:
1646 py_func_body = self.call_self_node(is_module_scope = env.is_module_scope)
1647 self.py_func = DefNode(pos = self.pos,
1648 name = self.entry.name,
1651 starstar_arg = None,
1653 body = py_func_body,
1655 self.py_func.is_module_scope = env.is_module_scope
1656 self.py_func.analyse_declarations(env)
1657 self.entry.as_variable = self.py_func.entry
1658 # Reset scope entry the above cfunction
1659 env.entries[name] = self.entry
1660 if not env.is_module_scope or Options.lookup_module_cpdef:
1661 self.override = OverrideCheckNode(self.pos, py_func = self.py_func)
1662 self.body = StatListNode(self.pos, stats=[self.override, self.body])
1663 self.create_local_scope(env)
1665 def call_self_node(self, omit_optional_args=0, is_module_scope=0):
1667 args = self.type.args
1668 if omit_optional_args:
1669 args = args[:len(args) - self.type.optional_arg_count]
1670 arg_names = [arg.name for arg in args]
1672 cfunc = ExprNodes.NameNode(self.pos, name=self.entry.name)
1674 self_arg = ExprNodes.NameNode(self.pos, name=arg_names[0])
1675 cfunc = ExprNodes.AttributeNode(self.pos, obj=self_arg, attribute=self.entry.name)
1676 skip_dispatch = not is_module_scope or Options.lookup_module_cpdef
1677 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)
1678 return ReturnStatNode(pos=self.pos, return_type=PyrexTypes.py_object_type, value=c_call)
1680 def declare_arguments(self, env):
1681 for arg in self.type.args:
1683 error(arg.pos, "Missing argument name")
1684 self.declare_argument(env, arg)
1686 def need_gil_acquisition(self, lenv):
1687 return self.type.with_gil
1689 def nogil_check(self, env):
1691 with_gil = type.with_gil
1692 if type.nogil and not with_gil:
1693 if type.return_type.is_pyobject:
1695 "Function with Python return type cannot be declared nogil")
1696 for entry in self.local_scope.var_entries:
1697 if entry.type.is_pyobject:
1698 error(self.pos, "Function declared nogil has Python locals or temporaries")
1700 def analyse_expressions(self, env):
1701 self.local_scope.directives = env.directives
1702 if self.py_func is not None:
1703 # this will also analyse the default values
1704 self.py_func.analyse_expressions(env)
1706 self.analyse_default_values(env)
1707 self.acquire_gil = self.need_gil_acquisition(self.local_scope)
1709 def needs_assignment_synthesis(self, env, code=None):
1712 def generate_function_header(self, code, with_pymethdef, with_opt_args = 1, with_dispatch = 1, cname = None):
1715 visibility = self.entry.visibility
1716 for arg in type.args[:len(type.args)-type.optional_arg_count]:
1717 arg_decls.append(arg.declaration_code())
1718 if with_dispatch and self.overridable:
1719 arg_decls.append(PyrexTypes.c_int_type.declaration_code(Naming.skip_dispatch_cname))
1720 if type.optional_arg_count and with_opt_args:
1721 arg_decls.append(type.op_arg_struct.declaration_code(Naming.optional_args_cname))
1722 if type.has_varargs:
1723 arg_decls.append("...")
1725 arg_decls = ["void"]
1727 cname = self.entry.func_cname
1728 entity = type.function_header_code(cname, ', '.join(arg_decls))
1729 if visibility == 'public':
1730 dll_linkage = "DL_EXPORT"
1733 header = self.return_type.declaration_code(entity,
1734 dll_linkage = dll_linkage)
1735 if visibility == 'extern':
1736 storage_class = "%s " % Naming.extern_c_macro
1737 elif visibility == 'public':
1740 storage_class = "static "
1741 if 'inline' in self.modifiers:
1742 self.modifiers[self.modifiers.index('inline')] = 'cython_inline'
1743 code.putln("%s%s %s {" % (
1745 ' '.join(self.modifiers).upper(), # macro forms
1748 def generate_argument_declarations(self, env, code):
1749 for arg in self.args:
1751 result = arg.calculate_default_value_code(code)
1752 code.putln('%s = %s;' % (
1753 arg.type.declaration_code(arg.cname), result))
1755 def generate_keyword_list(self, code):
1758 def generate_argument_parsing_code(self, env, code):
1760 if self.type.optional_arg_count:
1761 code.putln('if (%s) {' % Naming.optional_args_cname)
1762 for arg in self.args:
1764 code.putln('if (%s->%sn > %s) {' % (Naming.optional_args_cname, Naming.pyrex_prefix, i))
1765 declarator = arg.declarator
1766 while not hasattr(declarator, 'name'):
1767 declarator = declarator.base
1768 code.putln('%s = %s->%s;' % (arg.cname, Naming.optional_args_cname, self.type.opt_arg_cname(declarator.name)))
1770 for _ in range(self.type.optional_arg_count):
1774 def generate_argument_conversion_code(self, code):
1777 def generate_argument_type_tests(self, code):
1778 # Generate type tests for args whose type in a parent
1779 # class is a supertype of the declared type.
1780 for arg in self.type.args:
1781 if arg.needs_type_test:
1782 self.generate_arg_type_test(arg, code)
1783 elif arg.type.is_pyobject and not arg.accept_none:
1784 self.generate_arg_none_check(arg, code)
1786 def error_value(self):
1787 if self.return_type.is_pyobject:
1791 return self.entry.type.exception_value
1793 def caller_will_check_exceptions(self):
1794 return self.entry.type.exception_check
1796 def generate_wrapper_functions(self, code):
1797 # If the C signature of a function has changed, we need to generate
1798 # wrappers to put in the slots here.
1801 func_type = entry.type
1802 while entry.prev_entry is not None:
1804 entry = entry.prev_entry
1805 entry.func_cname = "%s%swrap_%s" % (self.entry.func_cname, Naming.pyrex_prefix, k)
1807 self.generate_function_header(code,
1809 with_dispatch = entry.type.is_overridable,
1810 with_opt_args = entry.type.optional_arg_count,
1811 cname = entry.func_cname)
1812 if not self.return_type.is_void:
1814 args = self.type.args
1815 arglist = [arg.cname for arg in args[:len(args)-self.type.optional_arg_count]]
1816 if entry.type.is_overridable:
1817 arglist.append(Naming.skip_dispatch_cname)
1818 elif func_type.is_overridable:
1820 if entry.type.optional_arg_count:
1821 arglist.append(Naming.optional_args_cname)
1822 elif func_type.optional_arg_count:
1823 arglist.append('NULL')
1824 code.putln('%s(%s);' % (self.entry.func_cname, ', '.join(arglist)))
1828 class PyArgDeclNode(Node):
1829 # Argument which must be a Python object (used
1830 # for * and ** arguments).
1833 # entry Symtab.Entry
1834 # annotation ExprNode or None Py3 argument annotation
1837 def generate_function_definitions(self, env, code):
1838 self.entry.generate_function_definitions(env, code)
1840 class DecoratorNode(Node):
1843 # decorator NameNode or CallNode or AttributeNode
1844 child_attrs = ['decorator']
1847 class DefNode(FuncDefNode):
1848 # A Python function definition.
1850 # name string the Python name of the function
1851 # lambda_name string the internal name of a lambda 'function'
1852 # decorators [DecoratorNode] list of decorators
1853 # args [CArgDeclNode] formal arguments
1854 # star_arg PyArgDeclNode or None * argument
1855 # starstar_arg PyArgDeclNode or None ** argument
1856 # doc EncodedString or None
1858 # return_type_annotation
1859 # ExprNode or None the Py3 return type annotation
1861 # The following subnode is constructed internally
1862 # when the def statement is inside a Python class definition.
1864 # assmt AssignmentNode Function construction/assignment
1866 child_attrs = ["args", "star_arg", "starstar_arg", "body", "decorators"]
1871 num_required_kw_args = 0
1872 reqd_kw_flags_cname = "0"
1875 return_type_annotation = None
1880 def __init__(self, pos, **kwds):
1881 FuncDefNode.__init__(self, pos, **kwds)
1883 for arg in self.args:
1890 self.num_kwonly_args = k
1891 self.num_required_kw_args = rk
1892 self.num_required_args = r
1894 def as_cfunction(self, cfunc=None, scope=None):
1896 error(self.star_arg.pos, "cdef function cannot have star argument")
1897 if self.starstar_arg:
1898 error(self.starstar_arg.pos, "cdef function cannot have starstar argument")
1901 for formal_arg in self.args:
1902 name_declarator, type = formal_arg.analyse(scope, nonempty=1)
1903 cfunc_args.append(PyrexTypes.CFuncTypeArg(name = name_declarator.name,
1905 type = py_object_type,
1906 pos = formal_arg.pos))
1907 cfunc_type = PyrexTypes.CFuncType(return_type = py_object_type,
1909 has_varargs = False,
1910 exception_value = None,
1911 exception_check = False,
1914 is_overridable = True)
1915 cfunc = CVarDefNode(self.pos, type=cfunc_type)
1919 cfunc_type = cfunc.type
1920 if len(self.args) != len(cfunc_type.args) or cfunc_type.has_varargs:
1921 error(self.pos, "wrong number of arguments")
1922 error(cfunc.pos, "previous declaration here")
1923 for i, (formal_arg, type_arg) in enumerate(zip(self.args, cfunc_type.args)):
1924 name_declarator, type = formal_arg.analyse(scope, nonempty=1,
1925 is_self_arg = (i == 0 and scope.is_c_class_scope))
1926 if type is None or type is PyrexTypes.py_object_type:
1927 formal_arg.type = type_arg.type
1928 formal_arg.name_declarator = name_declarator
1930 if cfunc_type.exception_value is None:
1931 exception_value = None
1933 exception_value = ExprNodes.ConstNode(self.pos, value=cfunc_type.exception_value, type=cfunc_type.return_type)
1934 declarator = CFuncDeclaratorNode(self.pos,
1935 base = CNameDeclaratorNode(self.pos, name=self.name, cname=None),
1937 has_varargs = False,
1938 exception_check = cfunc_type.exception_check,
1939 exception_value = exception_value,
1940 with_gil = cfunc_type.with_gil,
1941 nogil = cfunc_type.nogil)
1942 return CFuncDefNode(self.pos,
1944 base_type = CAnalysedBaseTypeNode(self.pos, type=cfunc_type.return_type),
1945 declarator = declarator,
1948 overridable = cfunc_type.is_overridable,
1950 with_gil = cfunc_type.with_gil,
1951 nogil = cfunc_type.nogil,
1952 visibility = 'private',
1954 directive_locals = getattr(cfunc, 'directive_locals', {}))
1956 def analyse_declarations(self, env):
1957 self.is_classmethod = self.is_staticmethod = False
1959 for decorator in self.decorators:
1960 func = decorator.decorator
1962 self.is_classmethod |= func.name == 'classmethod'
1963 self.is_staticmethod |= func.name == 'staticmethod'
1965 if self.is_classmethod and env.lookup_here('classmethod'):
1966 # classmethod() was overridden - not much we can do here ...
1967 self.is_classmethod = False
1968 if self.is_staticmethod and env.lookup_here('staticmethod'):
1969 # staticmethod() was overridden - not much we can do here ...
1970 self.is_staticmethod = False
1972 if self.name == '__new__':
1973 self.is_staticmethod = 1
1975 self.analyse_argument_types(env)
1976 if self.name == '<lambda>':
1977 self.declare_lambda_function(env)
1979 self.declare_pyfunction(env)
1980 self.analyse_signature(env)
1981 self.return_type = self.entry.signature.return_type()
1982 self.create_local_scope(env)
1984 def analyse_argument_types(self, env):
1985 directive_locals = self.directive_locals = env.directives['locals']
1986 allow_none_for_extension_args = env.directives['allow_none_for_extension_args']
1987 for arg in self.args:
1988 if hasattr(arg, 'name'):
1990 name_declarator = None
1992 base_type = arg.base_type.analyse(env)
1993 name_declarator, type = \
1994 arg.declarator.analyse(base_type, env)
1995 arg.name = name_declarator.name
1996 if arg.name in directive_locals:
1997 type_node = directive_locals[arg.name]
1998 other_type = type_node.analyse_as_type(env)
1999 if other_type is None:
2000 error(type_node.pos, "Not a type")
2001 elif (type is not PyrexTypes.py_object_type
2002 and not type.same_as(other_type)):
2003 error(arg.base_type.pos, "Signature does not agree with previous declaration")
2004 error(type_node.pos, "Previous declaration here")
2007 if name_declarator and name_declarator.cname:
2009 "Python function argument cannot have C name specification")
2010 arg.type = type.as_argument_type()
2012 arg.needs_conversion = 0
2013 arg.needs_type_test = 0
2015 if arg.type.is_pyobject:
2017 arg.accept_none = True
2019 arg.accept_none = False
2020 elif arg.type.is_extension_type or arg.type.is_builtin_type:
2021 if arg.default and arg.default.constant_result is None:
2022 # special case: def func(MyType obj = None)
2023 arg.accept_none = True
2025 # default depends on compiler directive
2026 arg.accept_none = allow_none_for_extension_args
2028 # probably just a plain 'object'
2029 arg.accept_none = True
2031 arg.accept_none = True # won't be used, but must be there
2033 error(arg.pos, "Only Python type arguments can have 'not None'")
2035 error(arg.pos, "Only Python type arguments can have 'or None'")
2037 def analyse_signature(self, env):
2038 if self.entry.is_special:
2039 self.entry.trivial_signature = len(self.args) == 1 and not (self.star_arg or self.starstar_arg)
2040 elif not env.directives['always_allow_keywords'] and not (self.star_arg or self.starstar_arg):
2041 # Use the simpler calling signature for zero- and one-argument functions.
2042 if self.entry.signature is TypeSlots.pyfunction_signature:
2043 if len(self.args) == 0:
2044 self.entry.signature = TypeSlots.pyfunction_noargs
2045 elif len(self.args) == 1:
2046 if self.args[0].default is None and not self.args[0].kw_only:
2047 self.entry.signature = TypeSlots.pyfunction_onearg
2048 elif self.entry.signature is TypeSlots.pymethod_signature:
2049 if len(self.args) == 1:
2050 self.entry.signature = TypeSlots.unaryfunc
2051 elif len(self.args) == 2:
2052 if self.args[1].default is None and not self.args[1].kw_only:
2053 self.entry.signature = TypeSlots.ibinaryfunc
2055 sig = self.entry.signature
2056 nfixed = sig.num_fixed_args()
2057 if sig is TypeSlots.pymethod_signature and nfixed == 1 \
2058 and len(self.args) == 0 and self.star_arg:
2059 # this is the only case where a diverging number of
2060 # arguments is not an error - when we have no explicit
2061 # 'self' parameter as in method(*args)
2062 sig = self.entry.signature = TypeSlots.pyfunction_signature # self is not 'really' used
2063 self.self_in_stararg = 1
2066 for i in range(min(nfixed, len(self.args))):
2069 if sig.is_self_arg(i) and not self.is_staticmethod:
2070 if self.is_classmethod:
2072 arg.hdr_type = arg.type = Builtin.type_type
2075 arg.hdr_type = arg.type = env.parent_type
2076 arg.needs_conversion = 0
2078 arg.hdr_type = sig.fixed_arg_type(i)
2079 if not arg.type.same_as(arg.hdr_type):
2080 if arg.hdr_type.is_pyobject and arg.type.is_pyobject:
2081 arg.needs_type_test = 1
2083 arg.needs_conversion = 1
2084 if arg.needs_conversion:
2085 arg.hdr_cname = Naming.arg_prefix + arg.name
2087 arg.hdr_cname = Naming.var_prefix + arg.name
2089 if nfixed > len(self.args):
2090 self.bad_signature()
2092 elif nfixed < len(self.args):
2093 if not sig.has_generic_args:
2094 self.bad_signature()
2095 for arg in self.args:
2096 if arg.is_generic and \
2097 (arg.type.is_extension_type or arg.type.is_builtin_type):
2098 arg.needs_type_test = 1
2100 def bad_signature(self):
2101 sig = self.entry.signature
2102 expected_str = "%d" % sig.num_fixed_args()
2103 if sig.has_generic_args:
2104 expected_str = expected_str + " or more"
2106 if name.startswith("__") and name.endswith("__"):
2107 desc = "Special method"
2111 "%s %s has wrong number of arguments "
2112 "(%d declared, %s expected)" % (
2113 desc, self.name, len(self.args), expected_str))
2115 def signature_has_nongeneric_args(self):
2116 argcount = len(self.args)
2117 if argcount == 0 or (
2118 argcount == 1 and (self.args[0].is_self_arg or
2119 self.args[0].is_type_arg)):
2123 def signature_has_generic_args(self):
2124 return self.entry.signature.has_generic_args
2126 def declare_pyfunction(self, env):
2127 #print "DefNode.declare_pyfunction:", self.name, "in", env ###
2129 entry = env.lookup_here(name)
2130 if entry and entry.type.is_cfunction and not self.is_wrapper:
2131 warning(self.pos, "Overriding cdef method with def method.", 5)
2132 entry = env.declare_pyfunction(name, self.pos)
2134 prefix = env.scope_prefix
2135 entry.func_cname = \
2136 Naming.pyfunc_prefix + prefix + name
2137 entry.pymethdef_cname = \
2138 Naming.pymethdef_prefix + prefix + name
2139 if Options.docstrings:
2140 entry.doc = embed_position(self.pos, self.doc)
2142 Naming.funcdoc_prefix + prefix + name
2143 if entry.is_special:
2144 if entry.name in TypeSlots.invisible or not entry.doc or (entry.name in '__getattr__' and env.directives['fast_getattr']):
2145 entry.wrapperbase_cname = None
2147 entry.wrapperbase_cname = Naming.wrapperbase_prefix + prefix + name
2151 def declare_lambda_function(self, env):
2153 prefix = env.scope_prefix
2155 Naming.lambda_func_prefix + u'funcdef' + prefix + self.lambda_name
2156 entry = env.declare_lambda_function(func_cname, self.pos)
2157 entry.pymethdef_cname = \
2158 Naming.lambda_func_prefix + u'methdef' + prefix + self.lambda_name
2159 entry.qualified_name = env.qualify_name(self.lambda_name)
2163 def declare_arguments(self, env):
2164 for arg in self.args:
2166 error(arg.pos, "Missing argument name")
2168 env.control_flow.set_state((), (arg.name, 'source'), 'arg')
2169 env.control_flow.set_state((), (arg.name, 'initialized'), True)
2170 if arg.needs_conversion:
2171 arg.entry = env.declare_var(arg.name, arg.type, arg.pos)
2172 if arg.type.is_pyobject:
2173 arg.entry.init = "0"
2174 arg.entry.init_to_none = 0
2176 arg.entry = self.declare_argument(env, arg)
2178 arg.entry.is_self_arg = arg.is_self_arg
2180 if arg.is_self_arg or arg.is_type_arg or \
2181 (arg.type.is_extension_type and not arg.hdr_type.is_extension_type):
2182 arg.entry.is_declared_generic = 1
2183 self.declare_python_arg(env, self.star_arg)
2184 self.declare_python_arg(env, self.starstar_arg)
2186 def declare_python_arg(self, env, arg):
2188 if env.directives['infer_types'] != False:
2189 type = PyrexTypes.unspecified_type
2191 type = py_object_type
2192 entry = env.declare_var(arg.name, type, arg.pos)
2195 entry.init_to_none = 0
2196 entry.xdecref_cleanup = 1
2198 env.control_flow.set_state((), (arg.name, 'initialized'), True)
2200 def analyse_expressions(self, env):
2201 self.local_scope.directives = env.directives
2202 self.analyse_default_values(env)
2203 if self.needs_assignment_synthesis(env):
2204 # Shouldn't we be doing this at the module level too?
2205 self.synthesize_assignment_node(env)
2207 def needs_assignment_synthesis(self, env, code=None):
2208 # Should enable for module level as well, that will require more testing...
2209 if env.is_module_scope:
2211 return env.directives['binding']
2213 return code.globalstate.directives['binding']
2214 return env.is_py_class_scope or env.is_closure_scope
2216 def synthesize_assignment_node(self, env):
2219 while genv.is_py_class_scope or genv.is_c_class_scope:
2220 genv = genv.outer_scope
2222 if genv.is_closure_scope:
2223 rhs = ExprNodes.InnerFunctionNode(
2224 self.pos, pymethdef_cname = self.entry.pymethdef_cname)
2226 rhs = ExprNodes.PyCFunctionNode(
2227 self.pos, pymethdef_cname = self.entry.pymethdef_cname, binding = env.directives['binding'])
2229 if env.is_py_class_scope:
2230 if not self.is_staticmethod and not self.is_classmethod:
2233 self.assmt = SingleAssignmentNode(self.pos,
2234 lhs = ExprNodes.NameNode(self.pos, name = self.name),
2236 self.assmt.analyse_declarations(env)
2237 self.assmt.analyse_expressions(env)
2239 def generate_function_header(self, code, with_pymethdef, proto_only=0):
2241 sig = self.entry.signature
2242 if sig.has_dummy_arg or self.self_in_stararg:
2243 arg_code_list.append(
2244 "PyObject *%s" % Naming.self_cname)
2245 for arg in self.args:
2246 if not arg.is_generic:
2247 if arg.is_self_arg or arg.is_type_arg:
2248 arg_code_list.append("PyObject *%s" % arg.hdr_cname)
2250 arg_code_list.append(
2251 arg.hdr_type.declaration_code(arg.hdr_cname))
2252 if not self.entry.is_special and sig.method_flags() == [TypeSlots.method_noargs]:
2253 arg_code_list.append("CYTHON_UNUSED PyObject *unused")
2254 if sig.has_generic_args:
2255 arg_code_list.append(
2256 "PyObject *%s, PyObject *%s"
2257 % (Naming.args_cname, Naming.kwds_cname))
2258 arg_code = ", ".join(arg_code_list)
2259 dc = self.return_type.declaration_code(self.entry.func_cname)
2260 mf = " ".join(self.modifiers).upper()
2262 header = "static %s%s(%s)" % (mf, dc, arg_code)
2263 code.putln("%s; /*proto*/" % header)
2266 if (Options.docstrings and self.entry.doc and
2267 not self.entry.scope.is_property_scope and
2268 (not self.entry.is_special or self.entry.wrapperbase_cname)):
2269 docstr = self.entry.doc
2270 if docstr.is_unicode:
2271 docstr = docstr.utf8encode()
2273 'static char %s[] = "%s";' % (
2274 self.entry.doc_cname,
2275 split_string_literal(escape_byte_string(docstr))))
2276 if self.entry.is_special:
2278 "struct wrapperbase %s;" % self.entry.wrapperbase_cname)
2281 "static PyMethodDef %s = " %
2282 self.entry.pymethdef_cname)
2283 code.put_pymethoddef(self.entry, ";", allow_skip=False)
2284 code.putln("%s {" % header)
2286 def generate_argument_declarations(self, env, code):
2287 for arg in self.args:
2288 if arg.is_generic: # or arg.needs_conversion:
2289 if arg.needs_conversion:
2290 code.putln("PyObject *%s = 0;" % arg.hdr_cname)
2291 elif not arg.entry.in_closure:
2292 code.put_var_declaration(arg.entry)
2294 def generate_keyword_list(self, code):
2295 if self.signature_has_generic_args() and \
2296 self.signature_has_nongeneric_args():
2298 "static PyObject **%s[] = {" %
2299 Naming.pykwdlist_cname)
2300 for arg in self.args:
2302 pystring_cname = code.intern_identifier(arg.name)
2303 code.put('&%s,' % pystring_cname)
2306 def generate_argument_parsing_code(self, env, code):
2307 # Generate PyArg_ParseTuple call for generic
2308 # arguments, if any.
2309 if self.entry.signature.has_dummy_arg and not self.self_in_stararg:
2310 # get rid of unused argument warning
2311 code.putln("%s = %s;" % (Naming.self_cname, Naming.self_cname))
2313 old_error_label = code.new_error_label()
2314 our_error_label = code.error_label
2315 end_label = code.new_label("argument_unpacking_done")
2317 has_kwonly_args = self.num_kwonly_args > 0
2318 has_star_or_kw_args = self.star_arg is not None \
2319 or self.starstar_arg is not None or has_kwonly_args
2321 for arg in self.args:
2322 if not arg.type.is_pyobject:
2323 done = arg.type.create_from_py_utility_code(env)
2324 if not done: pass # will fail later
2326 if not self.signature_has_generic_args():
2327 if has_star_or_kw_args:
2328 error(self.pos, "This method cannot have * or keyword arguments")
2329 self.generate_argument_conversion_code(code)
2331 elif not self.signature_has_nongeneric_args():
2332 # func(*args) or func(**kw) or func(*args, **kw)
2333 self.generate_stararg_copy_code(code)
2336 positional_args = []
2338 for arg in self.args:
2339 arg_entry = arg.entry
2342 if not arg.is_self_arg and not arg.is_type_arg:
2344 kw_only_args.append(arg)
2346 positional_args.append(arg)
2348 kw_only_args.append(arg)
2349 elif not arg.is_self_arg and not arg.is_type_arg:
2350 positional_args.append(arg)
2352 self.generate_tuple_and_keyword_parsing_code(
2353 positional_args, kw_only_args, end_label, code)
2355 code.error_label = old_error_label
2356 if code.label_used(our_error_label):
2357 if not code.label_used(end_label):
2358 code.put_goto(end_label)
2359 code.put_label(our_error_label)
2360 if has_star_or_kw_args:
2361 self.generate_arg_decref(self.star_arg, code)
2362 if self.starstar_arg:
2363 if self.starstar_arg.entry.xdecref_cleanup:
2364 code.put_var_xdecref(self.starstar_arg.entry)
2366 code.put_var_decref(self.starstar_arg.entry)
2367 code.putln('__Pyx_AddTraceback("%s");' % self.entry.qualified_name)
2368 # The arguments are put into the closure one after the
2369 # other, so when type errors are found, all references in
2370 # the closure instance must be properly ref-counted to
2371 # facilitate generic closure instance deallocation. In
2372 # the case of an argument type error, it's best to just
2373 # DECREF+clear the already handled references, as this
2374 # frees their references as early as possible.
2375 for arg in self.args:
2376 if arg.type.is_pyobject and arg.entry.in_closure:
2377 code.put_var_xdecref_clear(arg.entry)
2378 if self.needs_closure:
2379 code.put_decref(Naming.cur_scope_cname, self.local_scope.scope_class.type)
2380 code.put_finish_refcount_context()
2381 code.putln("return %s;" % self.error_value())
2382 if code.label_used(end_label):
2383 code.put_label(end_label)
2385 def generate_arg_assignment(self, arg, item, code):
2386 if arg.type.is_pyobject:
2388 item = PyrexTypes.typecast(arg.type, PyrexTypes.py_object_type, item)
2390 code.putln("%s = %s;" % (entry.cname, item))
2391 if entry.in_closure:
2392 code.put_var_incref(entry)
2394 func = arg.type.from_py_function
2396 code.putln("%s = %s(%s); %s" % (
2400 code.error_goto_if(arg.type.error_condition(arg.entry.cname), arg.pos)))
2402 error(arg.pos, "Cannot convert Python object argument to type '%s'" % arg.type)
2404 def generate_arg_xdecref(self, arg, code):
2406 code.put_var_xdecref(arg.entry)
2408 def generate_arg_decref(self, arg, code):
2410 code.put_var_decref(arg.entry)
2412 def generate_stararg_copy_code(self, code):
2413 if not self.star_arg:
2414 code.globalstate.use_utility_code(raise_argtuple_invalid_utility_code)
2415 code.putln("if (unlikely(PyTuple_GET_SIZE(%s) > 0)) {" %
2417 code.put('__Pyx_RaiseArgtupleInvalid("%s", 1, 0, 0, PyTuple_GET_SIZE(%s)); return %s;' % (
2418 self.name, Naming.args_cname, self.error_value()))
2421 code.globalstate.use_utility_code(keyword_string_check_utility_code)
2423 if self.starstar_arg:
2425 kwarg_check = "unlikely(%s)" % Naming.kwds_cname
2427 kwarg_check = "%s" % Naming.kwds_cname
2429 kwarg_check = "unlikely(%s) && unlikely(PyDict_Size(%s) > 0)" % (
2430 Naming.kwds_cname, Naming.kwds_cname)
2432 "if (%s && unlikely(!__Pyx_CheckKeywordStrings(%s, \"%s\", %d))) return %s;" % (
2433 kwarg_check, Naming.kwds_cname, self.name,
2434 bool(self.starstar_arg), self.error_value()))
2436 if self.starstar_arg:
2437 code.putln("%s = (%s) ? PyDict_Copy(%s) : PyDict_New();" % (
2438 self.starstar_arg.entry.cname,
2441 code.putln("if (unlikely(!%s)) return %s;" % (
2442 self.starstar_arg.entry.cname, self.error_value()))
2443 self.starstar_arg.entry.xdecref_cleanup = 0
2444 code.put_gotref(self.starstar_arg.entry.cname)
2446 if self.self_in_stararg:
2447 # need to create a new tuple with 'self' inserted as first item
2448 code.put("%s = PyTuple_New(PyTuple_GET_SIZE(%s)+1); if (unlikely(!%s)) " % (
2449 self.star_arg.entry.cname,
2451 self.star_arg.entry.cname))
2452 if self.starstar_arg:
2454 code.put_decref_clear(self.starstar_arg.entry.cname, py_object_type)
2455 code.putln("return %s;" % self.error_value())
2458 code.putln("return %s;" % self.error_value())
2459 code.put_gotref(self.star_arg.entry.cname)
2460 code.put_incref(Naming.self_cname, py_object_type)
2461 code.put_giveref(Naming.self_cname)
2462 code.putln("PyTuple_SET_ITEM(%s, 0, %s);" % (
2463 self.star_arg.entry.cname, Naming.self_cname))
2464 temp = code.funcstate.allocate_temp(PyrexTypes.c_py_ssize_t_type, manage_ref=False)
2465 code.putln("for (%s=0; %s < PyTuple_GET_SIZE(%s); %s++) {" % (
2466 temp, temp, Naming.args_cname, temp))
2467 code.putln("PyObject* item = PyTuple_GET_ITEM(%s, %s);" % (
2468 Naming.args_cname, temp))
2469 code.put_incref("item", py_object_type)
2470 code.put_giveref("item")
2471 code.putln("PyTuple_SET_ITEM(%s, %s+1, item);" % (
2472 self.star_arg.entry.cname, temp))
2474 code.funcstate.release_temp(temp)
2475 self.star_arg.entry.xdecref_cleanup = 0
2477 code.put_incref(Naming.args_cname, py_object_type)
2478 code.putln("%s = %s;" % (
2479 self.star_arg.entry.cname,
2481 self.star_arg.entry.xdecref_cleanup = 0
2483 def generate_tuple_and_keyword_parsing_code(self, positional_args,
2484 kw_only_args, success_label, code):
2485 argtuple_error_label = code.new_label("argtuple_error")
2487 min_positional_args = self.num_required_args - self.num_required_kw_args
2488 if len(self.args) > 0 and (self.args[0].is_self_arg or self.args[0].is_type_arg):
2489 min_positional_args -= 1
2490 max_positional_args = len(positional_args)
2491 has_fixed_positional_count = not self.star_arg and \
2492 min_positional_args == max_positional_args
2494 code.globalstate.use_utility_code(raise_double_keywords_utility_code)
2495 code.globalstate.use_utility_code(raise_argtuple_invalid_utility_code)
2496 if self.num_required_kw_args:
2497 code.globalstate.use_utility_code(raise_keyword_required_utility_code)
2499 if self.starstar_arg or self.star_arg:
2500 self.generate_stararg_init_code(max_positional_args, code)
2502 # --- optimised code when we receive keyword arguments
2503 if self.num_required_kw_args:
2504 likely_hint = "likely"
2506 likely_hint = "unlikely"
2507 code.putln("if (%s(%s)) {" % (likely_hint, Naming.kwds_cname))
2508 self.generate_keyword_unpacking_code(
2509 min_positional_args, max_positional_args,
2510 has_fixed_positional_count,
2511 positional_args, kw_only_args, argtuple_error_label, code)
2513 # --- optimised code when we do not receive any keyword arguments
2514 if (self.num_required_kw_args and min_positional_args > 0) or min_positional_args == max_positional_args:
2515 # Python raises arg tuple related errors first, so we must
2516 # check the length here
2517 if min_positional_args == max_positional_args and not self.star_arg:
2521 code.putln('} else if (PyTuple_GET_SIZE(%s) %s %d) {' % (
2522 Naming.args_cname, compare, min_positional_args))
2523 code.put_goto(argtuple_error_label)
2525 if self.num_required_kw_args:
2526 # pure error case: keywords required but not passed
2527 if max_positional_args > min_positional_args and not self.star_arg:
2528 code.putln('} else if (PyTuple_GET_SIZE(%s) > %d) {' % (
2529 Naming.args_cname, max_positional_args))
2530 code.put_goto(argtuple_error_label)
2531 code.putln('} else {')
2532 for i, arg in enumerate(kw_only_args):
2534 pystring_cname = code.intern_identifier(arg.name)
2535 # required keyword-only argument missing
2536 code.put('__Pyx_RaiseKeywordRequired("%s", %s); ' % (
2539 code.putln(code.error_goto(self.pos))
2542 elif min_positional_args == max_positional_args:
2543 # parse the exact number of positional arguments from the
2545 code.putln('} else {')
2546 for i, arg in enumerate(positional_args):
2547 item = "PyTuple_GET_ITEM(%s, %d)" % (Naming.args_cname, i)
2548 self.generate_arg_assignment(arg, item, code)
2549 self.generate_arg_default_assignments(code)
2552 # parse the positional arguments from the variable length
2554 code.putln('} else {')
2555 self.generate_arg_default_assignments(code)
2556 code.putln('switch (PyTuple_GET_SIZE(%s)) {' % Naming.args_cname)
2558 code.putln('default:')
2559 reversed_args = list(enumerate(positional_args))[::-1]
2560 for i, arg in reversed_args:
2561 if i >= min_positional_args-1:
2562 if min_positional_args > 1:
2563 code.putln('case %2d:' % (i+1)) # pure code beautification
2565 code.put('case %2d: ' % (i+1))
2566 item = "PyTuple_GET_ITEM(%s, %d)" % (Naming.args_cname, i)
2567 self.generate_arg_assignment(arg, item, code)
2568 if min_positional_args == 0:
2569 code.put('case 0: ')
2570 code.putln('break;')
2572 if min_positional_args:
2573 for i in range(min_positional_args-1, -1, -1):
2574 code.putln('case %2d:' % i)
2575 code.put_goto(argtuple_error_label)
2577 code.put('default: ')
2578 code.put_goto(argtuple_error_label)
2583 if code.label_used(argtuple_error_label):
2584 code.put_goto(success_label)
2585 code.put_label(argtuple_error_label)
2586 code.put('__Pyx_RaiseArgtupleInvalid("%s", %d, %d, %d, PyTuple_GET_SIZE(%s)); ' % (
2587 self.name, has_fixed_positional_count,
2588 min_positional_args, max_positional_args,
2590 code.putln(code.error_goto(self.pos))
2592 def generate_arg_default_assignments(self, code):
2593 for arg in self.args:
2594 if arg.is_generic and arg.default:
2598 arg.calculate_default_value_code(code)))
2600 def generate_stararg_init_code(self, max_positional_args, code):
2601 if self.starstar_arg:
2602 self.starstar_arg.entry.xdecref_cleanup = 0
2603 code.putln('%s = PyDict_New(); if (unlikely(!%s)) return %s;' % (
2604 self.starstar_arg.entry.cname,
2605 self.starstar_arg.entry.cname,
2606 self.error_value()))
2607 code.put_gotref(self.starstar_arg.entry.cname)
2609 self.star_arg.entry.xdecref_cleanup = 0
2610 code.putln('if (PyTuple_GET_SIZE(%s) > %d) {' % (
2612 max_positional_args))
2613 code.put('%s = PyTuple_GetSlice(%s, %d, PyTuple_GET_SIZE(%s)); ' % (
2614 self.star_arg.entry.cname, Naming.args_cname,
2615 max_positional_args, Naming.args_cname))
2616 code.put_gotref(self.star_arg.entry.cname)
2617 if self.starstar_arg:
2619 code.putln("if (unlikely(!%s)) {" % self.star_arg.entry.cname)
2620 code.put_decref(self.starstar_arg.entry.cname, py_object_type)
2621 code.putln('return %s;' % self.error_value())
2624 code.putln("if (unlikely(!%s)) return %s;" % (
2625 self.star_arg.entry.cname, self.error_value()))
2626 code.putln('} else {')
2627 code.put("%s = %s; " % (self.star_arg.entry.cname, Naming.empty_tuple))
2628 code.put_incref(Naming.empty_tuple, py_object_type)
2631 def generate_keyword_unpacking_code(self, min_positional_args, max_positional_args,
2632 has_fixed_positional_count, positional_args,
2633 kw_only_args, argtuple_error_label, code):
2634 all_args = tuple(positional_args) + tuple(kw_only_args)
2635 max_args = len(all_args)
2637 code.putln("Py_ssize_t kw_args = PyDict_Size(%s);" %
2639 # the 'values' array collects borrowed references to arguments
2640 # before doing any type coercion etc.
2641 code.putln("PyObject* values[%d] = {%s};" % (
2642 max_args, ','.join('0'*max_args)))
2644 # assign borrowed Python default values to the values array,
2645 # so that they can be overwritten by received arguments below
2646 for i, arg in enumerate(all_args):
2647 if arg.default and arg.type.is_pyobject:
2648 default_value = arg.calculate_default_value_code(code)
2649 code.putln('values[%d] = %s;' % (i, arg.type.as_pyobject(default_value)))
2651 # parse the args tuple and check that it's not too long
2652 code.putln('switch (PyTuple_GET_SIZE(%s)) {' % Naming.args_cname)
2654 code.putln('default:')
2655 for i in range(max_positional_args-1, -1, -1):
2656 code.put('case %2d: ' % (i+1))
2657 code.putln("values[%d] = PyTuple_GET_ITEM(%s, %d);" % (
2658 i, Naming.args_cname, i))
2659 code.putln('case 0: break;')
2660 if not self.star_arg:
2661 code.put('default: ') # more arguments than allowed
2662 code.put_goto(argtuple_error_label)
2665 # now fill up the positional/required arguments with values
2667 if self.num_required_args or max_positional_args > 0:
2668 last_required_arg = -1
2669 for i, arg in enumerate(all_args):
2671 last_required_arg = i
2672 if last_required_arg < max_positional_args:
2673 last_required_arg = max_positional_args-1
2674 num_required_args = self.num_required_args
2675 if max_positional_args > 0:
2676 code.putln('switch (PyTuple_GET_SIZE(%s)) {' % Naming.args_cname)
2677 for i, arg in enumerate(all_args[:last_required_arg+1]):
2678 if max_positional_args > 0 and i <= max_positional_args:
2679 if self.star_arg and i == max_positional_args:
2680 code.putln('default:')
2682 code.putln('case %2d:' % i)
2683 pystring_cname = code.intern_identifier(arg.name)
2686 # handled separately below
2688 code.putln('if (kw_args > 0) {')
2689 code.putln('PyObject* value = PyDict_GetItem(%s, %s);' % (
2690 Naming.kwds_cname, pystring_cname))
2691 code.putln('if (value) { values[%d] = value; kw_args--; }' % i)
2694 num_required_args -= 1
2695 code.putln('values[%d] = PyDict_GetItem(%s, %s);' % (
2696 i, Naming.kwds_cname, pystring_cname))
2697 code.putln('if (likely(values[%d])) kw_args--;' % i);
2698 if i < min_positional_args:
2700 # special case: we know arg 0 is missing
2702 code.put_goto(argtuple_error_label)
2704 # print the correct number of values (args or
2705 # kwargs) that were passed into positional
2706 # arguments up to this point
2707 code.putln('else {')
2708 code.put('__Pyx_RaiseArgtupleInvalid("%s", %d, %d, %d, %d); ' % (
2709 self.name, has_fixed_positional_count,
2710 min_positional_args, max_positional_args, i))
2711 code.putln(code.error_goto(self.pos))
2714 code.putln('else {')
2715 code.put('__Pyx_RaiseKeywordRequired("%s", %s); ' %(
2716 self.name, pystring_cname))
2717 code.putln(code.error_goto(self.pos))
2719 if max_positional_args > 0:
2722 if kw_only_args and not self.starstar_arg:
2723 # unpack optional keyword-only arguments
2724 # checking for interned strings in a dict is faster than iterating
2725 # but it's too likely that we must iterate if we expect **kwargs
2727 for i, arg in enumerate(all_args[max_positional_args:]):
2728 if not arg.kw_only or not arg.default:
2730 optional_args.append((i+max_positional_args, arg))
2732 # this mimics an unrolled loop so that we can "break" out of it
2733 code.putln('while (kw_args > 0) {')
2734 code.putln('PyObject* value;')
2735 for i, arg in optional_args:
2736 pystring_cname = code.intern_identifier(arg.name)
2738 'value = PyDict_GetItem(%s, %s);' % (
2739 Naming.kwds_cname, pystring_cname))
2741 'if (value) { values[%d] = value; if (!(--kw_args)) break; }' % i)
2742 code.putln('break;')
2745 code.putln('if (unlikely(kw_args > 0)) {')
2746 # non-positional/-required kw args left in dict: default args,
2747 # kw-only args, **kwargs or error
2749 # This is sort of a catch-all: except for checking required
2750 # arguments, this will always do the right thing for unpacking
2751 # keyword arguments, so that we can concentrate on optimising
2752 # common cases above.
2753 if max_positional_args == 0:
2756 code.putln("const Py_ssize_t used_pos_args = (PyTuple_GET_SIZE(%s) < %d) ? PyTuple_GET_SIZE(%s) : %d;" % (
2757 Naming.args_cname, max_positional_args,
2758 Naming.args_cname, max_positional_args))
2759 pos_arg_count = "used_pos_args"
2761 pos_arg_count = "PyTuple_GET_SIZE(%s)" % Naming.args_cname
2762 code.globalstate.use_utility_code(parse_keywords_utility_code)
2764 'if (unlikely(__Pyx_ParseOptionalKeywords(%s, %s, %s, values, %s, "%s") < 0)) ' % (
2766 Naming.pykwdlist_cname,
2767 self.starstar_arg and self.starstar_arg.entry.cname or '0',
2770 code.putln(code.error_goto(self.pos))
2773 # convert arg values to their final type and assign them
2774 for i, arg in enumerate(all_args):
2775 if arg.default and not arg.type.is_pyobject:
2776 code.putln("if (values[%d]) {" % i)
2777 self.generate_arg_assignment(arg, "values[%d]" % i, code)
2778 if arg.default and not arg.type.is_pyobject:
2779 code.putln('} else {')
2783 arg.calculate_default_value_code(code)))
2786 def generate_argument_conversion_code(self, code):
2787 # Generate code to convert arguments from signature type to
2788 # declared type, if needed. Also copies signature arguments
2789 # into closure fields.
2790 for arg in self.args:
2791 if arg.needs_conversion:
2792 self.generate_arg_conversion(arg, code)
2793 elif arg.entry.in_closure:
2794 code.putln('%s = %s;' % (arg.entry.cname, arg.hdr_cname))
2795 if arg.type.is_pyobject:
2796 code.put_var_incref(arg.entry)
2798 def generate_arg_conversion(self, arg, code):
2799 # Generate conversion code for one argument.
2800 old_type = arg.hdr_type
2802 if old_type.is_pyobject:
2804 code.putln("if (%s) {" % arg.hdr_cname)
2806 code.putln("assert(%s); {" % arg.hdr_cname)
2807 self.generate_arg_conversion_from_pyobject(arg, code)
2809 elif new_type.is_pyobject:
2810 self.generate_arg_conversion_to_pyobject(arg, code)
2812 if new_type.assignable_from(old_type):
2814 "%s = %s;" % (arg.entry.cname, arg.hdr_cname))
2817 "Cannot convert 1 argument from '%s' to '%s'" %
2818 (old_type, new_type))
2820 def generate_arg_conversion_from_pyobject(self, arg, code):
2822 func = new_type.from_py_function
2823 # copied from CoerceFromPyTypeNode
2825 lhs = arg.entry.cname
2826 rhs = "%s(%s)" % (func, arg.hdr_cname)
2827 if new_type.is_enum:
2828 rhs = PyrexTypes.typecast(new_type, PyrexTypes.c_long_type, rhs)
2829 code.putln("%s = %s; %s" % (
2832 code.error_goto_if(new_type.error_condition(arg.entry.cname), arg.pos)))
2835 "Cannot convert Python object argument to type '%s'"
2838 def generate_arg_conversion_to_pyobject(self, arg, code):
2839 old_type = arg.hdr_type
2840 func = old_type.to_py_function
2842 code.putln("%s = %s(%s); %s" % (
2846 code.error_goto_if_null(arg.entry.cname, arg.pos)))
2847 code.put_var_gotref(arg.entry)
2850 "Cannot convert argument of type '%s' to Python object"
2853 def generate_argument_type_tests(self, code):
2854 # Generate type tests for args whose signature
2855 # type is PyObject * and whose declared type is
2856 # a subtype thereof.
2857 for arg in self.args:
2858 if arg.needs_type_test:
2859 self.generate_arg_type_test(arg, code)
2860 elif not arg.accept_none and arg.type.is_pyobject:
2861 self.generate_arg_none_check(arg, code)
2863 def error_value(self):
2864 return self.entry.signature.error_value
2866 def caller_will_check_exceptions(self):
2869 class OverrideCheckNode(StatNode):
2870 # A Node for dispatching to the def method if it
2879 child_attrs = ['body']
2883 def analyse_expressions(self, env):
2884 self.args = env.arg_entries
2885 if self.py_func.is_module_scope:
2890 self.func_node = ExprNodes.RawCNameExprNode(self.pos, py_object_type)
2891 call_tuple = ExprNodes.TupleNode(self.pos, args=[ExprNodes.NameNode(self.pos, name=arg.name) for arg in self.args[first_arg:]])
2892 call_node = ExprNodes.SimpleCallNode(self.pos,
2893 function=self.func_node,
2894 args=[ExprNodes.NameNode(self.pos, name=arg.name) for arg in self.args[first_arg:]])
2895 self.body = ReturnStatNode(self.pos, value=call_node)
2896 self.body.analyse_expressions(env)
2898 def generate_execution_code(self, code):
2899 interned_attr_cname = code.intern_identifier(self.py_func.entry.name)
2900 # Check to see if we are an extension type
2901 if self.py_func.is_module_scope:
2902 self_arg = "((PyObject *)%s)" % Naming.module_cname
2904 self_arg = "((PyObject *)%s)" % self.args[0].cname
2905 code.putln("/* Check if called by wrapper */")
2906 code.putln("if (unlikely(%s)) ;" % Naming.skip_dispatch_cname)
2907 code.putln("/* Check if overriden in Python */")
2908 if self.py_func.is_module_scope:
2909 code.putln("else {")
2911 code.putln("else if (unlikely(Py_TYPE(%s)->tp_dictoffset != 0)) {" % self_arg)
2912 func_node_temp = code.funcstate.allocate_temp(py_object_type, manage_ref=True)
2913 self.func_node.set_cname(func_node_temp)
2914 # need to get attribute manually--scope would return cdef method
2915 err = code.error_goto_if_null(func_node_temp, self.pos)
2916 code.putln("%s = PyObject_GetAttr(%s, %s); %s" % (
2917 func_node_temp, self_arg, interned_attr_cname, err))
2918 code.put_gotref(func_node_temp)
2919 is_builtin_function_or_method = "PyCFunction_Check(%s)" % func_node_temp
2920 is_overridden = "(PyCFunction_GET_FUNCTION(%s) != (void *)&%s)" % (
2921 func_node_temp, self.py_func.entry.func_cname)
2922 code.putln("if (!%s || %s) {" % (is_builtin_function_or_method, is_overridden))
2923 self.body.generate_execution_code(code)
2925 code.put_decref_clear(func_node_temp, PyrexTypes.py_object_type)
2926 code.funcstate.release_temp(func_node_temp)
2929 class ClassDefNode(StatNode, BlockNode):
2932 class PyClassDefNode(ClassDefNode):
2933 # A Python class definition.
2935 # name EncodedString Name of the class
2936 # doc string or None
2937 # body StatNode Attribute definition code
2938 # entry Symtab.Entry
2939 # scope PyClassScope
2940 # decorators [DecoratorNode] list of decorators or None
2942 # The following subnodes are constructed internally:
2944 # dict DictNode Class dictionary or Py3 namespace
2945 # classobj ClassNode Class object
2946 # target NameNode Variable to assign class object to
2948 child_attrs = ["body", "dict", "metaclass", "mkw", "bases", "classobj", "target"]
2950 py3_style_class = False # Python3 style class (bases+kwargs)
2952 def __init__(self, pos, name, bases, doc, body, decorators = None,
2953 keyword_args = None, starstar_arg = None):
2954 StatNode.__init__(self, pos)
2958 self.decorators = decorators
2960 if self.doc and Options.docstrings:
2961 doc = embed_position(self.pos, self.doc)
2962 doc_node = ExprNodes.StringNode(pos, value = doc)
2965 if keyword_args or starstar_arg:
2966 self.py3_style_class = True
2968 self.metaclass = None
2969 if keyword_args and not starstar_arg:
2970 for i, item in list(enumerate(keyword_args.key_value_pairs))[::-1]:
2971 if item.key.value == 'metaclass':
2972 if self.metaclass is not None:
2973 error(item.pos, "keyword argument 'metaclass' passed multiple times")
2974 # special case: we already know the metaclass,
2975 # so we don't need to do the "build kwargs,
2976 # find metaclass" dance at runtime
2977 self.metaclass = item.value
2978 del keyword_args.key_value_pairs[i]
2979 if starstar_arg or (keyword_args and keyword_args.key_value_pairs):
2980 self.mkw = ExprNodes.KeywordArgsNode(
2981 pos, keyword_args = keyword_args, starstar_arg = starstar_arg)
2983 self.mkw = ExprNodes.NullNode(pos)
2984 if self.metaclass is None:
2985 self.metaclass = ExprNodes.PyClassMetaclassNode(
2986 pos, mkw = self.mkw, bases = self.bases)
2987 self.dict = ExprNodes.PyClassNamespaceNode(pos, name = name,
2988 doc = doc_node, metaclass = self.metaclass, bases = self.bases,
2990 self.classobj = ExprNodes.Py3ClassNode(pos, name = name,
2991 bases = self.bases, dict = self.dict, doc = doc_node,
2992 metaclass = self.metaclass, mkw = self.mkw)
2994 self.dict = ExprNodes.DictNode(pos, key_value_pairs = [])
2995 self.metaclass = None
2998 self.classobj = ExprNodes.ClassNode(pos, name = name,
2999 bases = bases, dict = self.dict, doc = doc_node)
3000 self.target = ExprNodes.NameNode(pos, name = name)
3002 def as_cclass(self):
3004 Return this node as if it were declared as an extension class
3006 if self.py3_style_class:
3007 error(self.classobj.pos, "Python3 style class could not be represented as C class")
3009 bases = self.classobj.bases.args
3011 base_class_name = None
3012 base_class_module = None
3013 elif len(bases) == 1:
3016 from ExprNodes import AttributeNode, NameNode
3017 while isinstance(base, AttributeNode):
3018 path.insert(0, base.attribute)
3020 if isinstance(base, NameNode):
3021 path.insert(0, base.name)
3022 base_class_name = path[-1]
3024 base_class_module = u'.'.join(path[:-1])
3026 base_class_module = None
3028 error(self.classobj.bases.args.pos, "Invalid base class")
3030 error(self.classobj.bases.args.pos, "C class may only have one base class")
3033 return CClassDefNode(self.pos,
3034 visibility = 'private',
3036 class_name = self.name,
3037 base_class_module = base_class_module,
3038 base_class_name = base_class_name,
3039 decorators = self.decorators,
3044 def create_scope(self, env):
3046 while genv.is_py_class_scope or genv.is_c_class_scope:
3047 genv = genv.outer_scope
3048 cenv = self.scope = PyClassScope(name = self.name, outer_scope = genv)
3051 def analyse_declarations(self, env):
3052 self.target.analyse_target_declaration(env)
3053 cenv = self.create_scope(env)
3054 cenv.directives = env.directives
3055 cenv.class_obj_cname = self.target.entry.cname
3056 self.body.analyse_declarations(cenv)
3058 def analyse_expressions(self, env):
3059 if self.py3_style_class:
3060 self.bases.analyse_expressions(env)
3061 self.metaclass.analyse_expressions(env)
3062 self.mkw.analyse_expressions(env)
3063 self.dict.analyse_expressions(env)
3064 self.classobj.analyse_expressions(env)
3065 genv = env.global_scope()
3067 self.body.analyse_expressions(cenv)
3068 self.target.analyse_target_expression(env, self.classobj)
3070 def generate_function_definitions(self, env, code):
3071 self.body.generate_function_definitions(self.scope, code)
3073 def generate_execution_code(self, code):
3074 code.pyclass_stack.append(self)
3076 if self.py3_style_class:
3077 self.bases.generate_evaluation_code(code)
3078 self.mkw.generate_evaluation_code(code)
3079 self.metaclass.generate_evaluation_code(code)
3080 self.dict.generate_evaluation_code(code)
3081 cenv.namespace_cname = cenv.class_obj_cname = self.dict.result()
3082 self.body.generate_execution_code(code)
3083 self.classobj.generate_evaluation_code(code)
3084 cenv.namespace_cname = cenv.class_obj_cname = self.classobj.result()
3085 self.target.generate_assignment_code(self.classobj, code)
3086 self.dict.generate_disposal_code(code)
3087 self.dict.free_temps(code)
3088 if self.py3_style_class:
3089 self.mkw.generate_disposal_code(code)
3090 self.mkw.free_temps(code)
3091 self.metaclass.generate_disposal_code(code)
3092 self.metaclass.free_temps(code)
3093 self.bases.generate_disposal_code(code)
3094 self.bases.free_temps(code)
3095 code.pyclass_stack.pop()
3097 class CClassDefNode(ClassDefNode):
3098 # An extension type definition.
3100 # visibility 'private' or 'public' or 'extern'
3101 # typedef_flag boolean
3103 # module_name string or None For import of extern type objects
3104 # class_name string Unqualified name of class
3105 # as_name string or None Name to declare as in this scope
3106 # base_class_module string or None Module containing the base class
3107 # base_class_name string or None Name of the base class
3108 # objstruct_name string or None Specified C name of object struct
3109 # typeobj_name string or None Specified C name of type object
3110 # in_pxd boolean Is in a .pxd file
3111 # decorators [DecoratorNode] list of decorators or None
3112 # doc string or None
3113 # body StatNode or None
3114 # entry Symtab.Entry
3115 # base_type PyExtensionType or None
3116 # buffer_defaults_node DictNode or None Declares defaults for a buffer
3117 # buffer_defaults_pos
3119 child_attrs = ["body"]
3120 buffer_defaults_node = None
3121 buffer_defaults_pos = None
3122 typedef_flag = False
3124 objstruct_name = None
3128 def analyse_declarations(self, env):
3129 #print "CClassDefNode.analyse_declarations:", self.class_name
3130 #print "...visibility =", self.visibility
3131 #print "...module_name =", self.module_name
3134 if self.buffer_defaults_node:
3135 buffer_defaults = Buffer.analyse_buffer_options(self.buffer_defaults_pos,
3136 env, [], self.buffer_defaults_node,
3137 need_complete=False)
3139 buffer_defaults = None
3141 if env.in_cinclude and not self.objstruct_name:
3142 error(self.pos, "Object struct name specification required for "
3143 "C class defined in 'extern from' block")
3144 self.base_type = None
3145 # Now that module imports are cached, we need to
3146 # import the modules for extern classes.
3147 if self.module_name:
3149 for module in env.cimported_modules:
3150 if module.name == self.module_name:
3151 self.module = module
3152 if self.module is None:
3153 self.module = ModuleScope(self.module_name, None, env.context)
3154 self.module.has_extern_class = 1
3155 env.add_imported_module(self.module)
3157 if self.base_class_name:
3158 if self.base_class_module:
3159 base_class_scope = env.find_module(self.base_class_module, self.pos)
3161 base_class_scope = env
3162 if self.base_class_name == 'object':
3163 # extension classes are special and don't need to inherit from object
3164 if base_class_scope is None or base_class_scope.lookup('object') is None:
3165 self.base_class_name = None
3166 self.base_class_module = None
3167 base_class_scope = None
3168 if base_class_scope:
3169 base_class_entry = base_class_scope.find(self.base_class_name, self.pos)
3170 if base_class_entry:
3171 if not base_class_entry.is_type:
3172 error(self.pos, "'%s' is not a type name" % self.base_class_name)
3173 elif not base_class_entry.type.is_extension_type:
3174 error(self.pos, "'%s' is not an extension type" % self.base_class_name)
3175 elif not base_class_entry.type.is_complete():
3176 error(self.pos, "Base class '%s' of type '%s' is incomplete" % (
3177 self.base_class_name, self.class_name))
3178 elif base_class_entry.type.scope and base_class_entry.type.scope.directives and \
3179 base_class_entry.type.scope.directives['final']:
3180 error(self.pos, "Base class '%s' of type '%s' is final" % (
3181 self.base_class_name, self.class_name))
3183 self.base_type = base_class_entry.type
3184 has_body = self.body is not None
3185 if self.module_name and self.visibility != 'extern':
3186 module_path = self.module_name.split(".")
3187 home_scope = env.find_imported_module(module_path, self.pos)
3193 if self.visibility == 'extern':
3194 if self.module_name == '__builtin__' and self.class_name in Builtin.builtin_types:
3195 warning(self.pos, "%s already a builtin Cython type" % self.class_name, 1)
3197 self.entry = home_scope.declare_c_class(
3198 name = self.class_name,
3200 defining = has_body and self.in_pxd,
3201 implementing = has_body and not self.in_pxd,
3202 module_name = self.module_name,
3203 base_type = self.base_type,
3204 objstruct_cname = self.objstruct_name,
3205 typeobj_cname = self.typeobj_name,
3206 visibility = self.visibility,
3207 typedef_flag = self.typedef_flag,
3209 buffer_defaults = buffer_defaults)
3210 if home_scope is not env and self.visibility == 'extern':
3211 env.add_imported_entry(self.class_name, self.entry, pos)
3212 self.scope = scope = self.entry.type.scope
3213 if scope is not None:
3214 scope.directives = env.directives
3216 if self.doc and Options.docstrings:
3217 scope.doc = embed_position(self.pos, self.doc)
3220 self.body.analyse_declarations(scope)
3224 scope.implemented = 1
3225 env.allocate_vtable_names(self.entry)
3227 def analyse_expressions(self, env):
3229 scope = self.entry.type.scope
3230 self.body.analyse_expressions(scope)
3232 def generate_function_definitions(self, env, code):
3234 self.body.generate_function_definitions(
3235 self.entry.type.scope, code)
3237 def generate_execution_code(self, code):
3238 # This is needed to generate evaluation code for
3239 # default values of method arguments.
3241 self.body.generate_execution_code(code)
3243 def annotate(self, code):
3245 self.body.annotate(code)
3248 class PropertyNode(StatNode):
3249 # Definition of a property in an extension type.
3252 # doc EncodedString or None Doc string
3255 child_attrs = ["body"]
3257 def analyse_declarations(self, env):
3258 entry = env.declare_property(self.name, self.doc, self.pos)
3260 entry.scope.directives = env.directives
3261 self.body.analyse_declarations(entry.scope)
3263 def analyse_expressions(self, env):
3264 self.body.analyse_expressions(env)
3266 def generate_function_definitions(self, env, code):
3267 self.body.generate_function_definitions(env, code)
3269 def generate_execution_code(self, code):
3272 def annotate(self, code):
3273 self.body.annotate(code)
3276 class GlobalNode(StatNode):
3277 # Global variable declaration.
3283 def analyse_declarations(self, env):
3284 for name in self.names:
3285 env.declare_global(name, self.pos)
3287 def analyse_expressions(self, env):
3290 def generate_execution_code(self, code):
3294 class ExprStatNode(StatNode):
3295 # Expression used as a statement.
3299 child_attrs = ["expr"]
3301 def analyse_declarations(self, env):
3303 if isinstance(self.expr, ExprNodes.GeneralCallNode):
3304 func = self.expr.function.as_cython_attribute()
3305 if func == u'declare':
3306 args, kwds = self.expr.explicit_args_kwds()
3308 error(self.expr.pos, "Variable names must be specified.")
3309 for var, type_node in kwds.key_value_pairs:
3310 type = type_node.analyse_as_type(env)
3312 error(type_node.pos, "Unknown type")
3314 env.declare_var(var.value, type, var.pos, is_cdef = True)
3315 self.__class__ = PassStatNode
3317 def analyse_expressions(self, env):
3318 self.expr.analyse_expressions(env)
3320 def generate_execution_code(self, code):
3321 self.expr.generate_evaluation_code(code)
3322 if not self.expr.is_temp and self.expr.result():
3323 code.putln("%s;" % self.expr.result())
3324 self.expr.generate_disposal_code(code)
3325 self.expr.free_temps(code)
3327 def generate_function_definitions(self, env, code):
3328 self.expr.generate_function_definitions(env, code)
3330 def annotate(self, code):
3331 self.expr.annotate(code)
3334 class AssignmentNode(StatNode):
3335 # Abstract base class for assignment nodes.
3337 # The analyse_expressions and generate_execution_code
3338 # phases of assignments are split into two sub-phases
3339 # each, to enable all the right hand sides of a
3340 # parallel assignment to be evaluated before assigning
3341 # to any of the left hand sides.
3343 def analyse_expressions(self, env):
3344 self.analyse_types(env)
3346 # def analyse_expressions(self, env):
3347 # self.analyse_expressions_1(env)
3348 # self.analyse_expressions_2(env)
3350 def generate_execution_code(self, code):
3351 self.generate_rhs_evaluation_code(code)
3352 self.generate_assignment_code(code)
3355 class SingleAssignmentNode(AssignmentNode):
3356 # The simplest case:
3360 # lhs ExprNode Left hand side
3361 # rhs ExprNode Right hand side
3362 # first bool Is this guaranteed the first assignment to lhs?
3364 child_attrs = ["lhs", "rhs"]
3366 declaration_only = False
3368 def analyse_declarations(self, env):
3371 # handle declarations of the form x = cython.foo()
3372 if isinstance(self.rhs, ExprNodes.CallNode):
3373 func_name = self.rhs.function.as_cython_attribute()
3375 args, kwds = self.rhs.explicit_args_kwds()
3377 if func_name in ['declare', 'typedef']:
3378 if len(args) > 2 or kwds is not None:
3379 error(rhs.pos, "Can only declare one type at a time.")
3381 type = args[0].analyse_as_type(env)
3383 error(args[0].pos, "Unknown type")
3386 if func_name == 'declare':
3387 if isinstance(lhs, ExprNodes.NameNode):
3388 vars = [(lhs.name, lhs.pos)]
3389 elif isinstance(lhs, ExprNodes.TupleNode):
3390 vars = [(var.name, var.pos) for var in lhs.args]
3392 error(lhs.pos, "Invalid declaration")
3394 for var, pos in vars:
3395 env.declare_var(var, type, pos, is_cdef = True)
3400 self.declaration_only = True
3402 self.declaration_only = True
3403 if not isinstance(lhs, ExprNodes.NameNode):
3404 error(lhs.pos, "Invalid declaration.")
3405 env.declare_typedef(lhs.name, type, self.pos, visibility='private')
3407 elif func_name in ['struct', 'union']:
3408 self.declaration_only = True
3409 if len(args) > 0 or kwds is None:
3410 error(rhs.pos, "Struct or union members must be given by name.")
3413 for member, type_node in kwds.key_value_pairs:
3414 type = type_node.analyse_as_type(env)
3416 error(type_node.pos, "Unknown type")
3418 members.append((member.value, type, member.pos))
3419 if len(members) < len(kwds.key_value_pairs):
3421 if not isinstance(self.lhs, ExprNodes.NameNode):
3422 error(self.lhs.pos, "Invalid declaration.")
3423 name = self.lhs.name
3424 scope = StructOrUnionScope(name)
3425 env.declare_struct_or_union(name, func_name, scope, False, self.rhs.pos)
3426 for member, type, pos in members:
3427 scope.declare_var(member, type, pos)
3429 if self.declaration_only:
3432 self.lhs.analyse_target_declaration(env)
3434 def analyse_types(self, env, use_temp = 0):
3435 self.rhs.analyse_types(env)
3436 self.lhs.analyse_target_types(env)
3437 self.lhs.gil_assignment_check(env)
3438 self.rhs = self.rhs.coerce_to(self.lhs.type, env)
3440 self.rhs = self.rhs.coerce_to_temp(env)
3442 def generate_rhs_evaluation_code(self, code):
3443 self.rhs.generate_evaluation_code(code)
3445 def generate_assignment_code(self, code):
3446 self.lhs.generate_assignment_code(self.rhs, code)
3448 def generate_function_definitions(self, env, code):
3449 self.rhs.generate_function_definitions(env, code)
3451 def annotate(self, code):
3452 self.lhs.annotate(code)
3453 self.rhs.annotate(code)
3456 class CascadedAssignmentNode(AssignmentNode):
3457 # An assignment with multiple left hand sides:
3461 # lhs_list [ExprNode] Left hand sides
3462 # rhs ExprNode Right hand sides
3466 # coerced_rhs_list [ExprNode] RHS coerced to type of each LHS
3468 child_attrs = ["lhs_list", "rhs", "coerced_rhs_list"]
3469 coerced_rhs_list = None
3471 def analyse_declarations(self, env):
3472 for lhs in self.lhs_list:
3473 lhs.analyse_target_declaration(env)
3475 def analyse_types(self, env, use_temp = 0):
3476 self.rhs.analyse_types(env)
3477 if not self.rhs.is_simple():
3479 self.rhs = self.rhs.coerce_to_temp(env)
3481 self.rhs = self.rhs.coerce_to_simple(env)
3482 from ExprNodes import CloneNode
3483 self.coerced_rhs_list = []
3484 for lhs in self.lhs_list:
3485 lhs.analyse_target_types(env)
3486 lhs.gil_assignment_check(env)
3487 rhs = CloneNode(self.rhs)
3488 rhs = rhs.coerce_to(lhs.type, env)
3489 self.coerced_rhs_list.append(rhs)
3491 def generate_rhs_evaluation_code(self, code):
3492 self.rhs.generate_evaluation_code(code)
3494 def generate_assignment_code(self, code):
3495 for i in range(len(self.lhs_list)):
3496 lhs = self.lhs_list[i]
3497 rhs = self.coerced_rhs_list[i]
3498 rhs.generate_evaluation_code(code)
3499 lhs.generate_assignment_code(rhs, code)
3500 # Assignment has disposed of the cloned RHS
3501 self.rhs.generate_disposal_code(code)
3502 self.rhs.free_temps(code)
3504 def generate_function_definitions(self, env, code):
3505 self.rhs.generate_function_definitions(env, code)
3507 def annotate(self, code):
3508 for i in range(len(self.lhs_list)):
3509 lhs = self.lhs_list[i].annotate(code)
3510 rhs = self.coerced_rhs_list[i].annotate(code)
3511 self.rhs.annotate(code)
3514 class ParallelAssignmentNode(AssignmentNode):
3515 # A combined packing/unpacking assignment:
3519 # This has been rearranged by the parser into
3521 # a = d ; b = e ; c = f
3523 # but we must evaluate all the right hand sides
3524 # before assigning to any of the left hand sides.
3526 # stats [AssignmentNode] The constituent assignments
3528 child_attrs = ["stats"]
3530 def analyse_declarations(self, env):
3531 for stat in self.stats:
3532 stat.analyse_declarations(env)
3534 def analyse_expressions(self, env):
3535 for stat in self.stats:
3536 stat.analyse_types(env, use_temp = 1)
3538 # def analyse_expressions(self, env):
3539 # for stat in self.stats:
3540 # stat.analyse_expressions_1(env, use_temp = 1)
3541 # for stat in self.stats:
3542 # stat.analyse_expressions_2(env)
3544 def generate_execution_code(self, code):
3545 for stat in self.stats:
3546 stat.generate_rhs_evaluation_code(code)
3547 for stat in self.stats:
3548 stat.generate_assignment_code(code)
3550 def generate_function_definitions(self, env, code):
3551 for stat in self.stats:
3552 stat.generate_function_definitions(env, code)
3554 def annotate(self, code):
3555 for stat in self.stats:
3559 class InPlaceAssignmentNode(AssignmentNode):
3560 # An in place arithmetic operand:
3566 # lhs ExprNode Left hand side
3567 # rhs ExprNode Right hand side
3568 # op char one of "+-*/%^&|"
3569 # dup (ExprNode) copy of lhs used for operation (auto-generated)
3571 # This code is a bit tricky because in order to obey Python
3572 # semantics the sub-expressions (e.g. indices) of the lhs must
3573 # not be evaluated twice. So we must re-use the values calculated
3574 # in evaluation phase for the assignment phase as well.
3575 # Fortunately, the type of the lhs node is fairly constrained
3576 # (it must be a NameNode, AttributeNode, or IndexNode).
3578 child_attrs = ["lhs", "rhs"]
3580 def analyse_declarations(self, env):
3581 self.lhs.analyse_target_declaration(env)
3583 def analyse_types(self, env):
3584 self.rhs.analyse_types(env)
3585 self.lhs.analyse_target_types(env)
3587 def generate_execution_code(self, code):
3589 self.rhs.generate_evaluation_code(code)
3590 self.lhs.generate_subexpr_evaluation_code(code)
3591 c_op = self.operator
3595 error(self.pos, "No C inplace power operator")
3596 if isinstance(self.lhs, ExprNodes.IndexNode) and self.lhs.is_buffer_access:
3597 if self.lhs.type.is_pyobject:
3598 error(self.pos, "In-place operators not allowed on object buffers in this release.")
3599 if c_op in ('/', '%') and self.lhs.type.is_int and not code.directives['cdivision']:
3600 error(self.pos, "In-place non-c divide operators not allowed on int buffers.")
3601 self.lhs.generate_buffer_setitem_code(self.rhs, code, c_op)
3604 # TODO: make sure overload is declared
3605 code.putln("%s %s= %s;" % (self.lhs.result(), c_op, self.rhs.result()))
3606 self.lhs.generate_subexpr_disposal_code(code)
3607 self.lhs.free_subexpr_temps(code)
3608 self.rhs.generate_disposal_code(code)
3609 self.rhs.free_temps(code)
3611 def annotate(self, code):
3612 self.lhs.annotate(code)
3613 self.rhs.annotate(code)
3615 def create_binop_node(self):
3617 return ExprNodes.binop_node(self.pos, self.operator, self.lhs, self.rhs)
3620 class PrintStatNode(StatNode):
3623 # arg_tuple TupleNode
3624 # stream ExprNode or None (stdout)
3625 # append_newline boolean
3627 child_attrs = ["arg_tuple", "stream"]
3629 def analyse_expressions(self, env):
3631 self.stream.analyse_expressions(env)
3632 self.stream = self.stream.coerce_to_pyobject(env)
3633 self.arg_tuple.analyse_expressions(env)
3634 self.arg_tuple = self.arg_tuple.coerce_to_pyobject(env)
3635 env.use_utility_code(printing_utility_code)
3636 if len(self.arg_tuple.args) == 1 and self.append_newline:
3637 env.use_utility_code(printing_one_utility_code)
3639 nogil_check = Node.gil_error
3640 gil_message = "Python print statement"
3642 def generate_execution_code(self, code):
3644 self.stream.generate_evaluation_code(code)
3645 stream_result = self.stream.py_result()
3648 if len(self.arg_tuple.args) == 1 and self.append_newline:
3649 arg = self.arg_tuple.args[0]
3650 arg.generate_evaluation_code(code)
3653 "if (__Pyx_PrintOne(%s, %s) < 0) %s" % (
3656 code.error_goto(self.pos)))
3657 arg.generate_disposal_code(code)
3658 arg.free_temps(code)
3660 self.arg_tuple.generate_evaluation_code(code)
3662 "if (__Pyx_Print(%s, %s, %d) < 0) %s" % (
3664 self.arg_tuple.py_result(),
3665 self.append_newline,
3666 code.error_goto(self.pos)))
3667 self.arg_tuple.generate_disposal_code(code)
3668 self.arg_tuple.free_temps(code)
3671 self.stream.generate_disposal_code(code)
3672 self.stream.free_temps(code)
3674 def generate_function_definitions(self, env, code):
3676 self.stream.generate_function_definitions(env, code)
3677 self.arg_tuple.generate_function_definitions(env, code)
3679 def annotate(self, code):
3681 self.stream.annotate(code)
3682 self.arg_tuple.annotate(code)
3685 class ExecStatNode(StatNode):
3690 child_attrs = ["args"]
3692 def analyse_expressions(self, env):
3693 for i, arg in enumerate(self.args):
3694 arg.analyse_expressions(env)
3695 arg = arg.coerce_to_pyobject(env)
3697 env.use_utility_code(Builtin.pyexec_utility_code)
3699 nogil_check = Node.gil_error
3700 gil_message = "Python exec statement"
3702 def generate_execution_code(self, code):
3704 for arg in self.args:
3705 arg.generate_evaluation_code(code)
3706 args.append( arg.py_result() )
3707 args = tuple(args + ['0', '0'][:3-len(args)])
3708 temp_result = code.funcstate.allocate_temp(PyrexTypes.py_object_type, manage_ref=True)
3709 code.putln("%s = __Pyx_PyRun(%s, %s, %s);" % (
3710 (temp_result,) + args))
3711 for arg in self.args:
3712 arg.generate_disposal_code(code)
3713 arg.free_temps(code)
3715 code.error_goto_if_null(temp_result, self.pos))
3716 code.put_gotref(temp_result)
3717 code.put_decref_clear(temp_result, py_object_type)
3718 code.funcstate.release_temp(temp_result)
3720 def annotate(self, code):
3721 for arg in self.args:
3725 class DelStatNode(StatNode):
3730 child_attrs = ["args"]
3732 def analyse_declarations(self, env):
3733 for arg in self.args:
3734 arg.analyse_target_declaration(env)
3736 def analyse_expressions(self, env):
3737 for arg in self.args:
3738 arg.analyse_target_expression(env, None)
3739 if arg.type.is_pyobject:
3741 elif arg.type.is_ptr and arg.type.base_type.is_cpp_class:
3743 elif arg.type.is_cpp_class:
3744 error(arg.pos, "Deletion of non-heap C++ object")
3746 error(arg.pos, "Deletion of non-Python, non-C++ object")
3747 #arg.release_target_temp(env)
3749 def nogil_check(self, env):
3750 for arg in self.args:
3751 if arg.type.is_pyobject:
3754 gil_message = "Deleting Python object"
3756 def generate_execution_code(self, code):
3757 for arg in self.args:
3758 if arg.type.is_pyobject:
3759 arg.generate_deletion_code(code)
3760 elif arg.type.is_ptr and arg.type.base_type.is_cpp_class:
3761 arg.generate_result_code(code)
3762 code.putln("delete %s;" % arg.result())
3763 # else error reported earlier
3765 def annotate(self, code):
3766 for arg in self.args:
3770 class PassStatNode(StatNode):
3775 def analyse_expressions(self, env):
3778 def generate_execution_code(self, code):
3782 class BreakStatNode(StatNode):
3786 def analyse_expressions(self, env):
3789 def generate_execution_code(self, code):
3790 if not code.break_label:
3791 error(self.pos, "break statement not inside loop")
3793 code.put_goto(code.break_label)
3796 class ContinueStatNode(StatNode):
3800 def analyse_expressions(self, env):
3803 def generate_execution_code(self, code):
3804 if code.funcstate.in_try_finally:
3805 error(self.pos, "continue statement inside try of try...finally")
3806 elif not code.continue_label:
3807 error(self.pos, "continue statement not inside loop")
3809 code.put_goto(code.continue_label)
3812 class ReturnStatNode(StatNode):
3815 # value ExprNode or None
3816 # return_type PyrexType
3818 child_attrs = ["value"]
3820 def analyse_expressions(self, env):
3821 return_type = env.return_type
3822 self.return_type = return_type
3824 error(self.pos, "Return not inside a function body")
3827 self.value.analyse_types(env)
3828 if return_type.is_void or return_type.is_returncode:
3829 error(self.value.pos,
3830 "Return with value in void function")
3832 self.value = self.value.coerce_to(env.return_type, env)
3834 if (not return_type.is_void
3835 and not return_type.is_pyobject
3836 and not return_type.is_returncode):
3837 error(self.pos, "Return value required")
3839 def nogil_check(self, env):
3840 if self.return_type.is_pyobject:
3843 gil_message = "Returning Python object"
3845 def generate_execution_code(self, code):
3846 code.mark_pos(self.pos)
3847 if not self.return_type:
3848 # error reported earlier
3850 if self.return_type.is_pyobject:
3851 code.put_xdecref(Naming.retval_cname,
3854 self.value.generate_evaluation_code(code)
3855 self.value.make_owned_reference(code)
3858 Naming.retval_cname,
3859 self.value.result_as(self.return_type)))
3860 self.value.generate_post_assignment_code(code)
3861 self.value.free_temps(code)
3863 if self.return_type.is_pyobject:
3864 code.put_init_to_py_none(Naming.retval_cname, self.return_type)
3865 elif self.return_type.is_returncode:
3868 Naming.retval_cname,
3869 self.return_type.default_value))
3870 for cname, type in code.funcstate.temps_holding_reference():
3871 code.put_decref_clear(cname, type)
3872 code.put_goto(code.return_label)
3874 def generate_function_definitions(self, env, code):
3875 if self.value is not None:
3876 self.value.generate_function_definitions(env, code)
3878 def annotate(self, code):
3880 self.value.annotate(code)
3883 class RaiseStatNode(StatNode):
3886 # exc_type ExprNode or None
3887 # exc_value ExprNode or None
3888 # exc_tb ExprNode or None
3890 child_attrs = ["exc_type", "exc_value", "exc_tb"]
3892 def analyse_expressions(self, env):
3894 self.exc_type.analyse_types(env)
3895 self.exc_type = self.exc_type.coerce_to_pyobject(env)
3897 self.exc_value.analyse_types(env)
3898 self.exc_value = self.exc_value.coerce_to_pyobject(env)
3900 self.exc_tb.analyse_types(env)
3901 self.exc_tb = self.exc_tb.coerce_to_pyobject(env)
3902 env.use_utility_code(raise_utility_code)
3904 nogil_check = Node.gil_error
3905 gil_message = "Raising exception"
3907 def generate_execution_code(self, code):
3909 self.exc_type.generate_evaluation_code(code)
3910 type_code = self.exc_type.py_result()
3914 self.exc_value.generate_evaluation_code(code)
3915 value_code = self.exc_value.py_result()
3919 self.exc_tb.generate_evaluation_code(code)
3920 tb_code = self.exc_tb.py_result()
3924 "__Pyx_Raise(%s, %s, %s);" % (
3928 for obj in (self.exc_type, self.exc_value, self.exc_tb):
3930 obj.generate_disposal_code(code)
3931 obj.free_temps(code)
3933 code.error_goto(self.pos))
3935 def generate_function_definitions(self, env, code):
3936 if self.exc_type is not None:
3937 self.exc_type.generate_function_definitions(env, code)
3938 if self.exc_value is not None:
3939 self.exc_value.generate_function_definitions(env, code)
3940 if self.exc_tb is not None:
3941 self.exc_tb.generate_function_definitions(env, code)
3943 def annotate(self, code):
3945 self.exc_type.annotate(code)
3947 self.exc_value.annotate(code)
3949 self.exc_tb.annotate(code)
3952 class ReraiseStatNode(StatNode):
3956 def analyse_expressions(self, env):
3957 env.use_utility_code(restore_exception_utility_code)
3959 nogil_check = Node.gil_error
3960 gil_message = "Raising exception"
3962 def generate_execution_code(self, code):
3963 vars = code.funcstate.exc_vars
3965 for varname in vars:
3966 code.put_giveref(varname)
3967 code.putln("__Pyx_ErrRestore(%s, %s, %s);" % tuple(vars))
3968 for varname in vars:
3969 code.put("%s = 0; " % varname)
3971 code.putln(code.error_goto(self.pos))
3973 error(self.pos, "Reraise not inside except clause")
3976 class AssertStatNode(StatNode):
3980 # value ExprNode or None
3982 child_attrs = ["cond", "value"]
3984 def analyse_expressions(self, env):
3985 self.cond = self.cond.analyse_boolean_expression(env)
3987 self.value.analyse_types(env)
3988 self.value = self.value.coerce_to_pyobject(env)
3990 nogil_check = Node.gil_error
3991 gil_message = "Raising exception"
3993 def generate_execution_code(self, code):
3994 code.putln("#ifndef PYREX_WITHOUT_ASSERTIONS")
3995 self.cond.generate_evaluation_code(code)
3997 "if (unlikely(!%s)) {" %
4000 self.value.generate_evaluation_code(code)
4002 "PyErr_SetObject(PyExc_AssertionError, %s);" %
4003 self.value.py_result())
4004 self.value.generate_disposal_code(code)
4005 self.value.free_temps(code)
4008 "PyErr_SetNone(PyExc_AssertionError);")
4010 code.error_goto(self.pos))
4013 self.cond.generate_disposal_code(code)
4014 self.cond.free_temps(code)
4015 code.putln("#endif")
4017 def generate_function_definitions(self, env, code):
4018 self.cond.generate_function_definitions(env, code)
4019 if self.value is not None:
4020 self.value.generate_function_definitions(env, code)
4022 def annotate(self, code):
4023 self.cond.annotate(code)
4025 self.value.annotate(code)
4028 class IfStatNode(StatNode):
4031 # if_clauses [IfClauseNode]
4032 # else_clause StatNode or None
4034 child_attrs = ["if_clauses", "else_clause"]
4036 def analyse_control_flow(self, env):
4037 env.start_branching(self.pos)
4038 for if_clause in self.if_clauses:
4039 if_clause.analyse_control_flow(env)
4040 env.next_branch(if_clause.end_pos())
4041 if self.else_clause:
4042 self.else_clause.analyse_control_flow(env)
4043 env.finish_branching(self.end_pos())
4045 def analyse_declarations(self, env):
4046 for if_clause in self.if_clauses:
4047 if_clause.analyse_declarations(env)
4048 if self.else_clause:
4049 self.else_clause.analyse_declarations(env)
4051 def analyse_expressions(self, env):
4052 for if_clause in self.if_clauses:
4053 if_clause.analyse_expressions(env)
4054 if self.else_clause:
4055 self.else_clause.analyse_expressions(env)
4057 def generate_execution_code(self, code):
4058 code.mark_pos(self.pos)
4059 end_label = code.new_label()
4060 for if_clause in self.if_clauses:
4061 if_clause.generate_execution_code(code, end_label)
4062 if self.else_clause:
4063 code.putln("/*else*/ {")
4064 self.else_clause.generate_execution_code(code)
4066 code.put_label(end_label)
4068 def generate_function_definitions(self, env, code):
4069 for clause in self.if_clauses:
4070 clause.generate_function_definitions(env, code)
4071 if self.else_clause is not None:
4072 self.else_clause.generate_function_definitions(env, code)
4074 def annotate(self, code):
4075 for if_clause in self.if_clauses:
4076 if_clause.annotate(code)
4077 if self.else_clause:
4078 self.else_clause.annotate(code)
4081 class IfClauseNode(Node):
4082 # if or elif clause in an if statement
4084 # condition ExprNode
4087 child_attrs = ["condition", "body"]
4089 def analyse_control_flow(self, env):
4090 self.body.analyse_control_flow(env)
4092 def analyse_declarations(self, env):
4093 self.body.analyse_declarations(env)
4095 def analyse_expressions(self, env):
4097 self.condition.analyse_temp_boolean_expression(env)
4098 self.body.analyse_expressions(env)
4100 def get_constant_condition_result(self):
4101 if self.condition.has_constant_result():
4102 return bool(self.condition.constant_result)
4106 def generate_execution_code(self, code, end_label):
4107 self.condition.generate_evaluation_code(code)
4110 self.condition.result())
4111 self.condition.generate_disposal_code(code)
4112 self.condition.free_temps(code)
4113 self.body.generate_execution_code(code)
4114 code.put_goto(end_label)
4117 def generate_function_definitions(self, env, code):
4118 self.condition.generate_function_definitions(env, code)
4119 self.body.generate_function_definitions(env, code)
4121 def annotate(self, code):
4122 self.condition.annotate(code)
4123 self.body.annotate(code)
4126 class SwitchCaseNode(StatNode):
4127 # Generated in the optimization of an if-elif-else node
4129 # conditions [ExprNode]
4132 child_attrs = ['conditions', 'body']
4134 def generate_execution_code(self, code):
4135 for cond in self.conditions:
4136 code.mark_pos(cond.pos)
4137 cond.generate_evaluation_code(code)
4138 code.putln("case %s:" % cond.result())
4139 self.body.generate_execution_code(code)
4140 code.putln("break;")
4142 def generate_function_definitions(self, env, code):
4143 for cond in self.conditions:
4144 cond.generate_function_definitions(env, code)
4145 self.body.generate_function_definitions(env, code)
4147 def annotate(self, code):
4148 for cond in self.conditions:
4150 self.body.annotate(code)
4152 class SwitchStatNode(StatNode):
4153 # Generated in the optimization of an if-elif-else node
4156 # cases [SwitchCaseNode]
4157 # else_clause StatNode or None
4159 child_attrs = ['test', 'cases', 'else_clause']
4161 def generate_execution_code(self, code):
4162 self.test.generate_evaluation_code(code)
4163 code.putln("switch (%s) {" % self.test.result())
4164 for case in self.cases:
4165 case.generate_execution_code(code)
4166 if self.else_clause is not None:
4167 code.putln("default:")
4168 self.else_clause.generate_execution_code(code)
4169 code.putln("break;")
4172 def generate_function_definitions(self, env, code):
4173 self.test.generate_function_definitions(env, code)
4174 for case in self.cases:
4175 case.generate_function_definitions(env, code)
4176 if self.else_clause is not None:
4177 self.else_clause.generate_function_definitions(env, code)
4179 def annotate(self, code):
4180 self.test.annotate(code)
4181 for case in self.cases:
4183 if self.else_clause is not None:
4184 self.else_clause.annotate(code)
4186 class LoopNode(object):
4188 def analyse_control_flow(self, env):
4189 env.start_branching(self.pos)
4190 self.body.analyse_control_flow(env)
4191 env.next_branch(self.body.end_pos())
4192 if self.else_clause:
4193 self.else_clause.analyse_control_flow(env)
4194 env.finish_branching(self.end_pos())
4197 class WhileStatNode(LoopNode, StatNode):
4200 # condition ExprNode
4202 # else_clause StatNode
4204 child_attrs = ["condition", "body", "else_clause"]
4206 def analyse_declarations(self, env):
4207 self.body.analyse_declarations(env)
4208 if self.else_clause:
4209 self.else_clause.analyse_declarations(env)
4211 def analyse_expressions(self, env):
4213 self.condition.analyse_temp_boolean_expression(env)
4214 self.body.analyse_expressions(env)
4215 if self.else_clause:
4216 self.else_clause.analyse_expressions(env)
4218 def generate_execution_code(self, code):
4219 old_loop_labels = code.new_loop_labels()
4222 self.condition.generate_evaluation_code(code)
4223 self.condition.generate_disposal_code(code)
4226 self.condition.result())
4227 self.condition.free_temps(code)
4228 self.body.generate_execution_code(code)
4229 code.put_label(code.continue_label)
4231 break_label = code.break_label
4232 code.set_loop_labels(old_loop_labels)
4233 if self.else_clause:
4234 code.putln("/*else*/ {")
4235 self.else_clause.generate_execution_code(code)
4237 code.put_label(break_label)
4239 def generate_function_definitions(self, env, code):
4240 self.condition.generate_function_definitions(env, code)
4241 self.body.generate_function_definitions(env, code)
4242 if self.else_clause is not None:
4243 self.else_clause.generate_function_definitions(env, code)
4245 def annotate(self, code):
4246 self.condition.annotate(code)
4247 self.body.annotate(code)
4248 if self.else_clause:
4249 self.else_clause.annotate(code)
4252 def ForStatNode(pos, **kw):
4253 if 'iterator' in kw:
4254 return ForInStatNode(pos, **kw)
4256 return ForFromStatNode(pos, **kw)
4258 class ForInStatNode(LoopNode, StatNode):
4262 # iterator IteratorNode
4264 # else_clause StatNode
4265 # item NextNode used internally
4267 child_attrs = ["target", "iterator", "body", "else_clause"]
4270 def analyse_declarations(self, env):
4271 self.target.analyse_target_declaration(env)
4272 self.body.analyse_declarations(env)
4273 if self.else_clause:
4274 self.else_clause.analyse_declarations(env)
4276 def analyse_expressions(self, env):
4278 self.target.analyse_target_types(env)
4279 self.iterator.analyse_expressions(env)
4280 self.item = ExprNodes.NextNode(self.iterator, env)
4281 self.item = self.item.coerce_to(self.target.type, env)
4282 self.body.analyse_expressions(env)
4283 if self.else_clause:
4284 self.else_clause.analyse_expressions(env)
4286 def generate_execution_code(self, code):
4287 old_loop_labels = code.new_loop_labels()
4288 self.iterator.allocate_counter_temp(code)
4289 self.iterator.generate_evaluation_code(code)
4292 self.item.generate_evaluation_code(code)
4293 self.target.generate_assignment_code(self.item, code)
4294 self.body.generate_execution_code(code)
4295 code.put_label(code.continue_label)
4298 break_label = code.break_label
4299 code.set_loop_labels(old_loop_labels)
4301 if self.else_clause:
4302 # in nested loops, the 'else' block can contain a
4303 # 'continue' statement for the outer loop, but we may need
4304 # to generate cleanup code before taking that path, so we
4306 orig_continue_label = code.continue_label
4307 code.continue_label = code.new_label('outer_continue')
4309 code.putln("/*else*/ {")
4310 self.else_clause.generate_execution_code(code)
4313 if code.label_used(code.continue_label):
4314 code.put_goto(break_label)
4315 code.put_label(code.continue_label)
4316 self.iterator.generate_disposal_code(code)
4317 code.put_goto(orig_continue_label)
4318 code.set_loop_labels(old_loop_labels)
4320 if code.label_used(break_label):
4321 code.put_label(break_label)
4322 self.iterator.release_counter_temp(code)
4323 self.iterator.generate_disposal_code(code)
4324 self.iterator.free_temps(code)
4326 def generate_function_definitions(self, env, code):
4327 self.target.generate_function_definitions(env, code)
4328 self.iterator.generate_function_definitions(env, code)
4329 self.body.generate_function_definitions(env, code)
4330 if self.else_clause is not None:
4331 self.else_clause.generate_function_definitions(env, code)
4333 def annotate(self, code):
4334 self.target.annotate(code)
4335 self.iterator.annotate(code)
4336 self.body.annotate(code)
4337 if self.else_clause:
4338 self.else_clause.annotate(code)
4339 self.item.annotate(code)
4342 class ForFromStatNode(LoopNode, StatNode):
4343 # for name from expr rel name rel expr
4350 # step ExprNode or None
4352 # else_clause StatNode or None
4358 # loopvar_node ExprNode (usually a NameNode or temp node)
4359 # py_loopvar_node PyTempNode or None
4360 child_attrs = ["target", "bound1", "bound2", "step", "body", "else_clause"]
4362 is_py_target = False
4364 py_loopvar_node = None
4367 gil_message = "For-loop using object bounds or target"
4369 def nogil_check(self, env):
4370 for x in (self.target, self.bound1, self.bound2):
4371 if x.type.is_pyobject:
4374 def analyse_declarations(self, env):
4375 self.target.analyse_target_declaration(env)
4376 self.body.analyse_declarations(env)
4377 if self.else_clause:
4378 self.else_clause.analyse_declarations(env)
4380 def analyse_expressions(self, env):
4382 self.target.analyse_target_types(env)
4383 self.bound1.analyse_types(env)
4384 self.bound2.analyse_types(env)
4385 if self.step is not None:
4386 if isinstance(self.step, ExprNodes.UnaryMinusNode):
4387 warning(self.step.pos, "Probable infinite loop in for-from-by statment. Consider switching the directions of the relations.", 2)
4388 self.step.analyse_types(env)
4390 target_type = self.target.type
4391 if self.target.type.is_numeric:
4392 loop_type = self.target.type
4394 loop_type = PyrexTypes.c_int_type
4395 if not self.bound1.type.is_pyobject:
4396 loop_type = PyrexTypes.widest_numeric_type(loop_type, self.bound1.type)
4397 if not self.bound2.type.is_pyobject:
4398 loop_type = PyrexTypes.widest_numeric_type(loop_type, self.bound2.type)
4399 if self.step is not None and not self.step.type.is_pyobject:
4400 loop_type = PyrexTypes.widest_numeric_type(loop_type, self.step.type)
4401 self.bound1 = self.bound1.coerce_to(loop_type, env)
4402 self.bound2 = self.bound2.coerce_to(loop_type, env)
4403 if not self.bound2.is_literal:
4404 self.bound2 = self.bound2.coerce_to_temp(env)
4405 if self.step is not None:
4406 self.step = self.step.coerce_to(loop_type, env)
4407 if not self.step.is_literal:
4408 self.step = self.step.coerce_to_temp(env)
4410 target_type = self.target.type
4411 if not (target_type.is_pyobject or target_type.is_numeric):
4412 error(self.target.pos,
4413 "for-from loop variable must be c numeric type or Python object")
4414 if target_type.is_numeric:
4415 self.is_py_target = False
4416 if isinstance(self.target, ExprNodes.IndexNode) and self.target.is_buffer_access:
4417 raise error(self.pos, "Buffer indexing not allowed as for loop target.")
4418 self.loopvar_node = self.target
4419 self.py_loopvar_node = None
4421 self.is_py_target = True
4422 c_loopvar_node = ExprNodes.TempNode(self.pos, loop_type, env)
4423 self.loopvar_node = c_loopvar_node
4424 self.py_loopvar_node = \
4425 ExprNodes.CloneNode(c_loopvar_node).coerce_to_pyobject(env)
4426 self.body.analyse_expressions(env)
4427 if self.else_clause:
4428 self.else_clause.analyse_expressions(env)
4430 def generate_execution_code(self, code):
4431 old_loop_labels = code.new_loop_labels()
4432 from_range = self.from_range
4433 self.bound1.generate_evaluation_code(code)
4434 self.bound2.generate_evaluation_code(code)
4435 offset, incop = self.relation_table[self.relation1]
4436 if self.step is not None:
4437 self.step.generate_evaluation_code(code)
4438 step = self.step.result()
4439 incop = "%s=%s" % (incop[0], step)
4441 if isinstance(self.loopvar_node, ExprNodes.TempNode):
4442 self.loopvar_node.allocate(code)
4443 if isinstance(self.py_loopvar_node, ExprNodes.TempNode):
4444 self.py_loopvar_node.allocate(code)
4446 loopvar_name = code.funcstate.allocate_temp(self.target.type, False)
4448 loopvar_name = self.loopvar_node.result()
4450 "for (%s = %s%s; %s %s %s; %s%s) {" % (
4452 self.bound1.result(), offset,
4453 loopvar_name, self.relation2, self.bound2.result(),
4454 loopvar_name, incop))
4455 if self.py_loopvar_node:
4456 self.py_loopvar_node.generate_evaluation_code(code)
4457 self.target.generate_assignment_code(self.py_loopvar_node, code)
4459 code.putln("%s = %s;" % (
4460 self.target.result(), loopvar_name))
4461 self.body.generate_execution_code(code)
4462 code.put_label(code.continue_label)
4463 if self.py_loopvar_node:
4464 # This mess is to make for..from loops with python targets behave
4465 # exactly like those with C targets with regards to re-assignment
4466 # of the loop variable.
4468 if self.target.entry.is_pyglobal:
4469 # We know target is a NameNode, this is the only ugly case.
4470 target_node = ExprNodes.PyTempNode(self.target.pos, None)
4471 target_node.allocate(code)
4472 interned_cname = code.intern_identifier(self.target.entry.name)
4473 code.globalstate.use_utility_code(ExprNodes.get_name_interned_utility_code)
4474 code.putln("%s = __Pyx_GetName(%s, %s); %s" % (
4475 target_node.result(),
4476 Naming.module_cname,
4478 code.error_goto_if_null(target_node.result(), self.target.pos)))
4479 code.put_gotref(target_node.result())
4481 target_node = self.target
4482 from_py_node = ExprNodes.CoerceFromPyTypeNode(self.loopvar_node.type, target_node, None)
4483 from_py_node.temp_code = loopvar_name
4484 from_py_node.generate_result_code(code)
4485 if self.target.entry.is_pyglobal:
4486 code.put_decref(target_node.result(), target_node.type)
4487 target_node.release(code)
4489 if self.py_loopvar_node:
4490 # This is potentially wasteful, but we don't want the semantics to
4491 # depend on whether or not the loop is a python type.
4492 self.py_loopvar_node.generate_evaluation_code(code)
4493 self.target.generate_assignment_code(self.py_loopvar_node, code)
4495 code.funcstate.release_temp(loopvar_name)
4496 break_label = code.break_label
4497 code.set_loop_labels(old_loop_labels)
4498 if self.else_clause:
4499 code.putln("/*else*/ {")
4500 self.else_clause.generate_execution_code(code)
4502 code.put_label(break_label)
4503 self.bound1.generate_disposal_code(code)
4504 self.bound1.free_temps(code)
4505 self.bound2.generate_disposal_code(code)
4506 self.bound2.free_temps(code)
4507 if isinstance(self.loopvar_node, ExprNodes.TempNode):
4508 self.loopvar_node.release(code)
4509 if isinstance(self.py_loopvar_node, ExprNodes.TempNode):
4510 self.py_loopvar_node.release(code)
4511 if self.step is not None:
4512 self.step.generate_disposal_code(code)
4513 self.step.free_temps(code)
4516 # {relop : (initial offset, increment op)}
4523 def generate_function_definitions(self, env, code):
4524 self.target.generate_function_definitions(env, code)
4525 self.bound1.generate_function_definitions(env, code)
4526 self.bound2.generate_function_definitions(env, code)
4527 if self.step is not None:
4528 self.step.generate_function_definitions(env, code)
4529 self.body.generate_function_definitions(env, code)
4530 if self.else_clause is not None:
4531 self.else_clause.generate_function_definitions(env, code)
4533 def annotate(self, code):
4534 self.target.annotate(code)
4535 self.bound1.annotate(code)
4536 self.bound2.annotate(code)
4538 self.step.annotate(code)
4539 self.body.annotate(code)
4540 if self.else_clause:
4541 self.else_clause.annotate(code)
4544 class WithStatNode(StatNode):
4546 Represents a Python with statement.
4548 This is only used at parse tree level; and is not present in
4549 analysis or generation phases.
4551 # manager The with statement manager object
4552 # target Node (lhs expression)
4554 child_attrs = ["manager", "target", "body"]
4556 class TryExceptStatNode(StatNode):
4557 # try .. except statement
4560 # except_clauses [ExceptClauseNode]
4561 # else_clause StatNode or None
4563 child_attrs = ["body", "except_clauses", "else_clause"]
4565 def analyse_control_flow(self, env):
4566 env.start_branching(self.pos)
4567 self.body.analyse_control_flow(env)
4568 successful_try = env.control_flow # grab this for later
4569 env.next_branch(self.body.end_pos())
4570 env.finish_branching(self.body.end_pos())
4572 env.start_branching(self.except_clauses[0].pos)
4573 for except_clause in self.except_clauses:
4574 except_clause.analyse_control_flow(env)
4575 env.next_branch(except_clause.end_pos())
4577 # the else cause it executed only when the try clause finishes
4578 env.control_flow.incoming = successful_try
4579 if self.else_clause:
4580 self.else_clause.analyse_control_flow(env)
4581 env.finish_branching(self.end_pos())
4583 def analyse_declarations(self, env):
4584 self.body.analyse_declarations(env)
4585 for except_clause in self.except_clauses:
4586 except_clause.analyse_declarations(env)
4587 if self.else_clause:
4588 self.else_clause.analyse_declarations(env)
4589 env.use_utility_code(reset_exception_utility_code)
4591 def analyse_expressions(self, env):
4592 self.body.analyse_expressions(env)
4593 default_clause_seen = 0
4594 for except_clause in self.except_clauses:
4595 except_clause.analyse_expressions(env)
4596 if default_clause_seen:
4597 error(except_clause.pos, "default 'except:' must be last")
4598 if not except_clause.pattern:
4599 default_clause_seen = 1
4600 self.has_default_clause = default_clause_seen
4601 if self.else_clause:
4602 self.else_clause.analyse_expressions(env)
4604 nogil_check = Node.gil_error
4605 gil_message = "Try-except statement"
4607 def generate_execution_code(self, code):
4608 old_return_label = code.return_label
4609 old_break_label = code.break_label
4610 old_continue_label = code.continue_label
4611 old_error_label = code.new_error_label()
4612 our_error_label = code.error_label
4613 except_end_label = code.new_label('exception_handled')
4614 except_error_label = code.new_label('except_error')
4615 except_return_label = code.new_label('except_return')
4616 try_return_label = code.new_label('try_return')
4617 try_break_label = code.new_label('try_break')
4618 try_continue_label = code.new_label('try_continue')
4619 try_end_label = code.new_label('try_end')
4622 code.putln("PyObject %s;" %
4623 ', '.join(['*%s' % var for var in Naming.exc_save_vars]))
4624 code.putln("__Pyx_ExceptionSave(%s);" %
4625 ', '.join(['&%s' % var for var in Naming.exc_save_vars]))
4626 for var in Naming.exc_save_vars:
4627 code.put_xgotref(var)
4630 code.return_label = try_return_label
4631 code.break_label = try_break_label
4632 code.continue_label = try_continue_label
4633 self.body.generate_execution_code(code)
4636 temps_to_clean_up = code.funcstate.all_free_managed_temps()
4637 code.error_label = except_error_label
4638 code.return_label = except_return_label
4639 if self.else_clause:
4642 self.else_clause.generate_execution_code(code)
4645 for var in Naming.exc_save_vars:
4646 code.put_xdecref_clear(var, py_object_type)
4647 code.put_goto(try_end_label)
4648 if code.label_used(try_return_label):
4649 code.put_label(try_return_label)
4650 for var in Naming.exc_save_vars: code.put_xgiveref(var)
4651 code.putln("__Pyx_ExceptionReset(%s);" %
4652 ', '.join(Naming.exc_save_vars))
4653 code.put_goto(old_return_label)
4654 code.put_label(our_error_label)
4655 for temp_name, type in temps_to_clean_up:
4656 code.put_xdecref_clear(temp_name, type)
4657 for except_clause in self.except_clauses:
4658 except_clause.generate_handling_code(code, except_end_label)
4660 error_label_used = code.label_used(except_error_label)
4661 if error_label_used or not self.has_default_clause:
4662 if error_label_used:
4663 code.put_label(except_error_label)
4664 for var in Naming.exc_save_vars: code.put_xgiveref(var)
4665 code.putln("__Pyx_ExceptionReset(%s);" %
4666 ', '.join(Naming.exc_save_vars))
4667 code.put_goto(old_error_label)
4669 for exit_label, old_label in zip(
4670 [try_break_label, try_continue_label, except_return_label],
4671 [old_break_label, old_continue_label, old_return_label]):
4673 if code.label_used(exit_label):
4674 code.put_label(exit_label)
4675 for var in Naming.exc_save_vars: code.put_xgiveref(var)
4676 code.putln("__Pyx_ExceptionReset(%s);" %
4677 ', '.join(Naming.exc_save_vars))
4678 code.put_goto(old_label)
4680 if code.label_used(except_end_label):
4681 code.put_label(except_end_label)
4682 for var in Naming.exc_save_vars: code.put_xgiveref(var)
4683 code.putln("__Pyx_ExceptionReset(%s);" %
4684 ', '.join(Naming.exc_save_vars))
4685 code.put_label(try_end_label)
4688 code.return_label = old_return_label
4689 code.break_label = old_break_label
4690 code.continue_label = old_continue_label
4691 code.error_label = old_error_label
4693 def generate_function_definitions(self, env, code):
4694 self.body.generate_function_definitions(env, code)
4695 for except_clause in self.except_clauses:
4696 except_clause.generate_function_definitions(env, code)
4697 if self.else_clause is not None:
4698 self.else_clause.generate_function_definitions(env, code)
4700 def annotate(self, code):
4701 self.body.annotate(code)
4702 for except_node in self.except_clauses:
4703 except_node.annotate(code)
4704 if self.else_clause:
4705 self.else_clause.annotate(code)
4708 class ExceptClauseNode(Node):
4709 # Part of try ... except statement.
4711 # pattern [ExprNode]
4712 # target ExprNode or None
4714 # excinfo_target NameNode or None optional target for exception info
4715 # match_flag string result of exception match
4716 # exc_value ExcValueNode used internally
4717 # function_name string qualified name of enclosing function
4718 # exc_vars (string * 3) local exception variables
4720 # excinfo_target is never set by the parser, but can be set by a transform
4721 # in order to extract more extensive information about the exception as a
4722 # sys.exc_info()-style tuple into a target variable
4724 child_attrs = ["pattern", "target", "body", "exc_value", "excinfo_target"]
4727 excinfo_target = None
4729 def analyse_declarations(self, env):
4731 self.target.analyse_target_declaration(env)
4732 if self.excinfo_target is not None:
4733 self.excinfo_target.analyse_target_declaration(env)
4734 self.body.analyse_declarations(env)
4736 def analyse_expressions(self, env):
4738 genv = env.global_scope()
4739 self.function_name = env.qualified_name
4741 # normalise/unpack self.pattern into a list
4742 for i, pattern in enumerate(self.pattern):
4743 pattern.analyse_expressions(env)
4744 self.pattern[i] = pattern.coerce_to_pyobject(env)
4747 self.exc_value = ExprNodes.ExcValueNode(self.pos, env)
4748 self.target.analyse_target_expression(env, self.exc_value)
4749 if self.excinfo_target is not None:
4751 self.excinfo_tuple = ExprNodes.TupleNode(pos=self.pos, args=[
4752 ExprNodes.ExcValueNode(pos=self.pos, env=env) for x in range(3)])
4753 self.excinfo_tuple.analyse_expressions(env)
4754 self.excinfo_target.analyse_target_expression(env, self.excinfo_tuple)
4756 self.body.analyse_expressions(env)
4758 def generate_handling_code(self, code, end_label):
4759 code.mark_pos(self.pos)
4762 for pattern in self.pattern:
4763 pattern.generate_evaluation_code(code)
4764 exc_tests.append("PyErr_ExceptionMatches(%s)" % pattern.py_result())
4766 match_flag = code.funcstate.allocate_temp(PyrexTypes.c_int_type, False)
4768 "%s = %s;" % (match_flag, ' || '.join(exc_tests)))
4769 for pattern in self.pattern:
4770 pattern.generate_disposal_code(code)
4771 pattern.free_temps(code)
4775 code.funcstate.release_temp(match_flag)
4777 code.putln("/*except:*/ {")
4779 if not getattr(self.body, 'stats', True) and \
4780 self.excinfo_target is None and self.target is None:
4781 # most simple case: no exception variable, empty body (pass)
4782 # => reset the exception state, done
4783 code.putln("PyErr_Restore(0,0,0);")
4784 code.put_goto(end_label)
4788 exc_vars = [code.funcstate.allocate_temp(py_object_type,
4791 code.putln('__Pyx_AddTraceback("%s");' % self.function_name)
4792 # We always have to fetch the exception value even if
4793 # there is no target, because this also normalises the
4794 # exception and stores it in the thread state.
4795 code.globalstate.use_utility_code(get_exception_utility_code)
4796 exc_args = "&%s, &%s, &%s" % tuple(exc_vars)
4797 code.putln("if (__Pyx_GetException(%s) < 0) %s" % (exc_args,
4798 code.error_goto(self.pos)))
4802 self.exc_value.set_var(exc_vars[1])
4803 self.exc_value.generate_evaluation_code(code)
4804 self.target.generate_assignment_code(self.exc_value, code)
4805 if self.excinfo_target is not None:
4806 for tempvar, node in zip(exc_vars, self.excinfo_tuple.args):
4807 node.set_var(tempvar)
4808 self.excinfo_tuple.generate_evaluation_code(code)
4809 self.excinfo_target.generate_assignment_code(self.excinfo_tuple, code)
4811 old_break_label, old_continue_label = code.break_label, code.continue_label
4812 code.break_label = code.new_label('except_break')
4813 code.continue_label = code.new_label('except_continue')
4815 old_exc_vars = code.funcstate.exc_vars
4816 code.funcstate.exc_vars = exc_vars
4817 self.body.generate_execution_code(code)
4818 code.funcstate.exc_vars = old_exc_vars
4819 for var in exc_vars:
4820 code.putln("__Pyx_DECREF(%s); %s = 0;" % (var, var))
4821 code.put_goto(end_label)
4823 if code.label_used(code.break_label):
4824 code.put_label(code.break_label)
4825 for var in exc_vars:
4826 code.putln("__Pyx_DECREF(%s); %s = 0;" % (var, var))
4827 code.put_goto(old_break_label)
4828 code.break_label = old_break_label
4830 if code.label_used(code.continue_label):
4831 code.put_label(code.continue_label)
4832 for var in exc_vars:
4833 code.putln("__Pyx_DECREF(%s); %s = 0;" % (var, var))
4834 code.put_goto(old_continue_label)
4835 code.continue_label = old_continue_label
4837 for temp in exc_vars:
4838 code.funcstate.release_temp(temp)
4843 def generate_function_definitions(self, env, code):
4844 if self.target is not None:
4845 self.target.generate_function_definitions(env, code)
4846 self.body.generate_function_definitions(env, code)
4848 def annotate(self, code):
4850 for pattern in self.pattern:
4851 pattern.annotate(code)
4853 self.target.annotate(code)
4854 self.body.annotate(code)
4857 class TryFinallyStatNode(StatNode):
4858 # try ... finally statement
4861 # finally_clause StatNode
4863 # The plan is that we funnel all continue, break
4864 # return and error gotos into the beginning of the
4865 # finally block, setting a variable to remember which
4866 # one we're doing. At the end of the finally block, we
4867 # switch on the variable to figure out where to go.
4868 # In addition, if we're doing an error, we save the
4869 # exception on entry to the finally block and restore
4872 child_attrs = ["body", "finally_clause"]
4874 preserve_exception = 1
4876 disallow_continue_in_try_finally = 0
4877 # There doesn't seem to be any point in disallowing
4878 # continue in the try block, since we have no problem
4881 def create_analysed(pos, env, body, finally_clause):
4882 node = TryFinallyStatNode(pos, body=body, finally_clause=finally_clause)
4884 create_analysed = staticmethod(create_analysed)
4886 def analyse_control_flow(self, env):
4887 env.start_branching(self.pos)
4888 self.body.analyse_control_flow(env)
4889 env.next_branch(self.body.end_pos())
4890 env.finish_branching(self.body.end_pos())
4891 self.finally_clause.analyse_control_flow(env)
4893 def analyse_declarations(self, env):
4894 self.body.analyse_declarations(env)
4895 self.finally_clause.analyse_declarations(env)
4897 def analyse_expressions(self, env):
4898 self.body.analyse_expressions(env)
4899 self.finally_clause.analyse_expressions(env)
4901 nogil_check = Node.gil_error
4902 gil_message = "Try-finally statement"
4904 def generate_execution_code(self, code):
4905 old_error_label = code.error_label
4906 old_labels = code.all_new_labels()
4907 new_labels = code.get_all_labels()
4908 new_error_label = code.error_label
4909 catch_label = code.new_label()
4912 if self.disallow_continue_in_try_finally:
4913 was_in_try_finally = code.funcstate.in_try_finally
4914 code.funcstate.in_try_finally = 1
4915 self.body.generate_execution_code(code)
4916 if self.disallow_continue_in_try_finally:
4917 code.funcstate.in_try_finally = was_in_try_finally
4920 temps_to_clean_up = code.funcstate.all_free_managed_temps()
4921 code.mark_pos(self.finally_clause.pos)
4925 error_label_used = 0
4926 for i, new_label in enumerate(new_labels):
4927 if new_label in code.labels_used:
4928 cases_used.append(i)
4929 if new_label == new_error_label:
4930 error_label_used = 1
4931 error_label_case = i
4935 if error_label_used and self.preserve_exception:
4937 "PyObject *%s, *%s, *%s;" % Naming.exc_vars)
4939 "int %s;" % Naming.exc_lineno_name)
4940 exc_var_init_zero = ''.join(["%s = 0; " % var for var in Naming.exc_vars])
4941 exc_var_init_zero += '%s = 0;' % Naming.exc_lineno_name
4942 code.putln(exc_var_init_zero)
4944 exc_var_init_zero = None
4945 code.use_label(catch_label)
4947 "__pyx_why = 0; goto %s;" % catch_label)
4948 for i in cases_used:
4949 new_label = new_labels[i]
4950 #if new_label and new_label != "<try>":
4951 if new_label == new_error_label and self.preserve_exception:
4952 self.put_error_catcher(code,
4953 new_error_label, i+1, catch_label, temps_to_clean_up)
4955 code.put('%s: ' % new_label)
4956 if exc_var_init_zero:
4957 code.putln(exc_var_init_zero)
4958 code.putln("__pyx_why = %s; goto %s;" % (
4961 code.put_label(catch_label)
4962 code.set_all_labels(old_labels)
4963 if error_label_used:
4964 code.new_error_label()
4965 finally_error_label = code.error_label
4966 self.finally_clause.generate_execution_code(code)
4967 if error_label_used:
4968 if finally_error_label in code.labels_used and self.preserve_exception:
4969 over_label = code.new_label()
4970 code.put_goto(over_label);
4971 code.put_label(finally_error_label)
4972 code.putln("if (__pyx_why == %d) {" % (error_label_case + 1))
4973 for var in Naming.exc_vars:
4974 code.putln("Py_XDECREF(%s);" % var)
4976 code.put_goto(old_error_label)
4977 code.put_label(over_label)
4978 code.error_label = old_error_label
4981 "switch (__pyx_why) {")
4982 for i in cases_used:
4983 old_label = old_labels[i]
4984 if old_label == old_error_label and self.preserve_exception:
4985 self.put_error_uncatcher(code, i+1, old_error_label)
4987 code.use_label(old_label)
4989 "case %s: goto %s;" % (
4997 def generate_function_definitions(self, env, code):
4998 self.body.generate_function_definitions(env, code)
4999 self.finally_clause.generate_function_definitions(env, code)
5001 def put_error_catcher(self, code, error_label, i, catch_label, temps_to_clean_up):
5002 code.globalstate.use_utility_code(restore_exception_utility_code)
5009 for temp_name, type in temps_to_clean_up:
5010 code.put_xdecref_clear(temp_name, type)
5012 "__Pyx_ErrFetch(&%s, &%s, &%s);" %
5016 Naming.exc_lineno_name, Naming.lineno_cname))
5017 code.put_goto(catch_label)
5020 def put_error_uncatcher(self, code, i, error_label):
5021 code.globalstate.use_utility_code(restore_exception_utility_code)
5026 "__Pyx_ErrRestore(%s, %s, %s);" %
5030 Naming.lineno_cname, Naming.exc_lineno_name))
5031 for var in Naming.exc_vars:
5035 code.put_goto(error_label)
5039 def annotate(self, code):
5040 self.body.annotate(code)
5041 self.finally_clause.annotate(code)
5044 class GILStatNode(TryFinallyStatNode):
5045 # 'with gil' or 'with nogil' statement
5047 # state string 'gil' or 'nogil'
5051 preserve_exception = 0
5053 def __init__(self, pos, state, body):
5055 TryFinallyStatNode.__init__(self, pos,
5057 finally_clause = GILExitNode(pos, state = state))
5059 def analyse_expressions(self, env):
5060 env.use_utility_code(force_init_threads_utility_code)
5061 was_nogil = env.nogil
5063 TryFinallyStatNode.analyse_expressions(self, env)
5064 env.nogil = was_nogil
5068 def generate_execution_code(self, code):
5069 code.mark_pos(self.pos)
5071 if self.state == 'gil':
5072 code.putln("#ifdef WITH_THREAD")
5073 code.putln("PyGILState_STATE _save = PyGILState_Ensure();")
5074 code.putln("#endif")
5076 code.putln("#ifdef WITH_THREAD")
5077 code.putln("PyThreadState *_save;")
5078 code.putln("#endif")
5079 code.putln("Py_UNBLOCK_THREADS")
5080 TryFinallyStatNode.generate_execution_code(self, code)
5084 class GILExitNode(StatNode):
5085 # Used as the 'finally' block in a GILStatNode
5087 # state string 'gil' or 'nogil'
5091 def analyse_expressions(self, env):
5094 def generate_execution_code(self, code):
5095 if self.state == 'gil':
5096 code.putln("#ifdef WITH_THREAD")
5097 code.putln("PyGILState_Release(_save);")
5098 code.putln("#endif")
5100 code.putln("Py_BLOCK_THREADS")
5103 class CImportStatNode(StatNode):
5106 # module_name string Qualified name of module being imported
5107 # as_name string or None Name specified in "as" clause, if any
5111 def analyse_declarations(self, env):
5112 if not env.is_module_scope:
5113 error(self.pos, "cimport only allowed at module level")
5115 module_scope = env.find_module(self.module_name, self.pos)
5116 if "." in self.module_name:
5117 names = [EncodedString(name) for name in self.module_name.split(".")]
5119 top_module_scope = env.context.find_submodule(top_name)
5120 module_scope = top_module_scope
5121 for name in names[1:]:
5122 submodule_scope = module_scope.find_submodule(name)
5123 module_scope.declare_module(name, submodule_scope, self.pos)
5124 module_scope = submodule_scope
5126 env.declare_module(self.as_name, module_scope, self.pos)
5128 env.declare_module(top_name, top_module_scope, self.pos)
5130 name = self.as_name or self.module_name
5131 env.declare_module(name, module_scope, self.pos)
5133 def analyse_expressions(self, env):
5136 def generate_execution_code(self, code):
5140 class FromCImportStatNode(StatNode):
5141 # from ... cimport statement
5143 # module_name string Qualified name of module
5144 # imported_names [(pos, name, as_name, kind)] Names to be imported
5148 def analyse_declarations(self, env):
5149 if not env.is_module_scope:
5150 error(self.pos, "cimport only allowed at module level")
5152 module_scope = env.find_module(self.module_name, self.pos)
5153 env.add_imported_module(module_scope)
5154 for pos, name, as_name, kind in self.imported_names:
5156 for local_name, entry in module_scope.entries.items():
5157 env.add_imported_entry(local_name, entry, pos)
5159 entry = module_scope.lookup(name)
5161 if kind and not self.declaration_matches(entry, kind):
5162 entry.redeclared(pos)
5164 if kind == 'struct' or kind == 'union':
5165 entry = module_scope.declare_struct_or_union(name,
5166 kind = kind, scope = None, typedef_flag = 0, pos = pos)
5167 elif kind == 'class':
5168 entry = module_scope.declare_c_class(name, pos = pos,
5169 module_name = self.module_name)
5171 submodule_scope = env.context.find_module(name, relative_to = module_scope, pos = self.pos)
5172 if submodule_scope.parent_module is module_scope:
5173 env.declare_module(as_name or name, submodule_scope, self.pos)
5175 error(pos, "Name '%s' not declared in module '%s'"
5176 % (name, self.module_name))
5179 local_name = as_name or name
5180 env.add_imported_entry(local_name, entry, pos)
5182 def declaration_matches(self, entry, kind):
5183 if not entry.is_type:
5187 if not type.is_extension_type:
5190 if not type.is_struct_or_union:
5192 if kind != type.kind:
5196 def analyse_expressions(self, env):
5199 def generate_execution_code(self, code):
5203 class FromImportStatNode(StatNode):
5204 # from ... import statement
5207 # items [(string, NameNode)]
5208 # interned_items [(string, NameNode, ExprNode)]
5209 # item PyTempNode used internally
5210 # import_star boolean used internally
5212 child_attrs = ["module"]
5215 def analyse_declarations(self, env):
5216 for name, target in self.items:
5218 if not env.is_module_scope:
5219 error(self.pos, "import * only allowed at module level")
5221 env.has_import_star = 1
5222 self.import_star = 1
5224 target.analyse_target_declaration(env)
5226 def analyse_expressions(self, env):
5228 self.module.analyse_expressions(env)
5229 self.item = ExprNodes.RawCNameExprNode(self.pos, py_object_type)
5230 self.interned_items = []
5231 for name, target in self.items:
5233 for _, entry in env.entries.items():
5234 if not entry.is_type and entry.type.is_extension_type:
5235 env.use_utility_code(ExprNodes.type_test_utility_code)
5238 entry = env.lookup(target.name)
5239 # check whether or not entry is already cimported
5240 if (entry.is_type and entry.type.name == name
5241 and hasattr(entry.type, 'module_name')):
5242 if entry.type.module_name == self.module.module_name.value:
5243 # cimported with absolute name
5246 # cimported with relative name
5247 module = env.find_module(self.module.module_name.value,
5249 if entry.type.module_name == module.qualified_name:
5251 except AttributeError:
5253 target.analyse_target_expression(env, None)
5254 if target.type is py_object_type:
5257 coerced_item = self.item.coerce_to(target.type, env)
5258 self.interned_items.append((name, target, coerced_item))
5260 def generate_execution_code(self, code):
5261 self.module.generate_evaluation_code(code)
5262 if self.import_star:
5264 'if (%s(%s) < 0) %s;' % (
5266 self.module.py_result(),
5267 code.error_goto(self.pos)))
5268 item_temp = code.funcstate.allocate_temp(py_object_type, manage_ref=True)
5269 self.item.set_cname(item_temp)
5270 for name, target, coerced_item in self.interned_items:
5271 cname = code.intern_identifier(name)
5273 '%s = PyObject_GetAttr(%s, %s); %s' % (
5275 self.module.py_result(),
5277 code.error_goto_if_null(item_temp, self.pos)))
5278 code.put_gotref(item_temp)
5279 if coerced_item is None:
5280 target.generate_assignment_code(self.item, code)
5282 coerced_item.allocate_temp_result(code)
5283 coerced_item.generate_result_code(code)
5284 target.generate_assignment_code(coerced_item, code)
5285 code.put_decref_clear(item_temp, py_object_type)
5286 code.funcstate.release_temp(item_temp)
5287 self.module.generate_disposal_code(code)
5288 self.module.free_temps(code)
5292 #------------------------------------------------------------------------------------
5294 # Runtime support code
5296 #------------------------------------------------------------------------------------
5298 utility_function_predeclarations = \
5300 /* inline attribute */
5301 #ifndef CYTHON_INLINE
5302 #if defined(__GNUC__)
5303 #define CYTHON_INLINE __inline__
5304 #elif defined(_MSC_VER)
5305 #define CYTHON_INLINE __inline
5306 #elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
5307 #define CYTHON_INLINE inline
5309 #define CYTHON_INLINE
5313 /* unused attribute */
5314 #ifndef CYTHON_UNUSED
5315 # if defined(__GNUC__)
5316 # if !(defined(__cplusplus)) || (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4))
5317 # define CYTHON_UNUSED __attribute__ ((__unused__))
5319 # define CYTHON_UNUSED
5321 # elif defined(__ICC) || defined(__INTEL_COMPILER)
5322 # define CYTHON_UNUSED __attribute__ ((__unused__))
5324 # define CYTHON_UNUSED
5328 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*/
5332 if Options.gcc_branch_hints:
5333 branch_prediction_macros = \
5336 /* Test for GCC > 2.95 */
5337 #if __GNUC__ > 2 || (__GNUC__ == 2 && (__GNUC_MINOR__ > 95))
5338 #define likely(x) __builtin_expect(!!(x), 1)
5339 #define unlikely(x) __builtin_expect(!!(x), 0)
5340 #else /* __GNUC__ > 2 ... */
5341 #define likely(x) (x)
5342 #define unlikely(x) (x)
5343 #endif /* __GNUC__ > 2 ... */
5344 #else /* __GNUC__ */
5345 #define likely(x) (x)
5346 #define unlikely(x) (x)
5347 #endif /* __GNUC__ */
5350 branch_prediction_macros = \
5352 #define likely(x) (x)
5353 #define unlikely(x) (x)
5356 #get_name_predeclaration = \
5357 #"static PyObject *__Pyx_GetName(PyObject *dict, char *name); /*proto*/"
5359 #get_name_interned_predeclaration = \
5360 #"static PyObject *__Pyx_GetName(PyObject *dict, PyObject *name); /*proto*/"
5362 #------------------------------------------------------------------------------------
5364 printing_utility_code = UtilityCode(
5366 static int __Pyx_Print(PyObject*, PyObject *, int); /*proto*/
5367 #if PY_MAJOR_VERSION >= 3
5368 static PyObject* %s = 0;
5369 static PyObject* %s = 0;
5371 """ % (Naming.print_function, Naming.print_function_kwargs),
5373 #if PY_MAJOR_VERSION >= 3
5377 """ % (Naming.print_function, Naming.print_function_kwargs),
5379 #if PY_MAJOR_VERSION < 3
5380 static PyObject *__Pyx_GetStdout(void) {
5381 PyObject *f = PySys_GetObject((char *)"stdout");
5383 PyErr_SetString(PyExc_RuntimeError, "lost sys.stdout");
5388 static int __Pyx_Print(PyObject* f, PyObject *arg_tuple, int newline) {
5393 if (!(f = __Pyx_GetStdout()))
5396 for (i=0; i < PyTuple_GET_SIZE(arg_tuple); i++) {
5397 if (PyFile_SoftSpace(f, 1)) {
5398 if (PyFile_WriteString(" ", f) < 0)
5401 v = PyTuple_GET_ITEM(arg_tuple, i);
5402 if (PyFile_WriteObject(v, f, Py_PRINT_RAW) < 0)
5404 if (PyString_Check(v)) {
5405 char *s = PyString_AsString(v);
5406 Py_ssize_t len = PyString_Size(v);
5408 isspace(Py_CHARMASK(s[len-1])) &&
5410 PyFile_SoftSpace(f, 0);
5414 if (PyFile_WriteString("\n", f) < 0)
5416 PyFile_SoftSpace(f, 0);
5421 #else /* Python 3 has a print function */
5423 static int __Pyx_Print(PyObject* stream, PyObject *arg_tuple, int newline) {
5424 PyObject* kwargs = 0;
5425 PyObject* result = 0;
5426 PyObject* end_string;
5427 if (unlikely(!%(PRINT_FUNCTION)s)) {
5428 %(PRINT_FUNCTION)s = __Pyx_GetAttrString(%(BUILTINS)s, "print");
5429 if (!%(PRINT_FUNCTION)s)
5433 kwargs = PyDict_New();
5434 if (unlikely(!kwargs))
5436 if (unlikely(PyDict_SetItemString(kwargs, "file", stream) < 0))
5439 end_string = PyUnicode_FromStringAndSize(" ", 1);
5440 if (unlikely(!end_string))
5442 if (PyDict_SetItemString(kwargs, "end", end_string) < 0) {
5443 Py_DECREF(end_string);
5446 Py_DECREF(end_string);
5448 } else if (!newline) {
5449 if (unlikely(!%(PRINT_KWARGS)s)) {
5450 %(PRINT_KWARGS)s = PyDict_New();
5451 if (unlikely(!%(PRINT_KWARGS)s))
5453 end_string = PyUnicode_FromStringAndSize(" ", 1);
5454 if (unlikely(!end_string))
5456 if (PyDict_SetItemString(%(PRINT_KWARGS)s, "end", end_string) < 0) {
5457 Py_DECREF(end_string);
5460 Py_DECREF(end_string);
5462 kwargs = %(PRINT_KWARGS)s;
5464 result = PyObject_Call(%(PRINT_FUNCTION)s, arg_tuple, kwargs);
5465 if (unlikely(kwargs) && (kwargs != %(PRINT_KWARGS)s))
5472 if (kwargs != %(PRINT_KWARGS)s)
5478 """ % {'BUILTINS' : Naming.builtins_cname,
5479 'PRINT_FUNCTION' : Naming.print_function,
5480 'PRINT_KWARGS' : Naming.print_function_kwargs}
5484 printing_one_utility_code = UtilityCode(
5486 static int __Pyx_PrintOne(PyObject* stream, PyObject *o); /*proto*/
5489 #if PY_MAJOR_VERSION < 3
5491 static int __Pyx_PrintOne(PyObject* f, PyObject *o) {
5493 if (!(f = __Pyx_GetStdout()))
5496 if (PyFile_SoftSpace(f, 0)) {
5497 if (PyFile_WriteString(" ", f) < 0)
5500 if (PyFile_WriteObject(o, f, Py_PRINT_RAW) < 0)
5502 if (PyFile_WriteString("\n", f) < 0)
5505 /* the line below is just to avoid compiler
5506 * compiler warnings about unused functions */
5507 return __Pyx_Print(f, NULL, 0);
5510 #else /* Python 3 has a print function */
5512 static int __Pyx_PrintOne(PyObject* stream, PyObject *o) {
5514 PyObject* arg_tuple = PyTuple_New(1);
5515 if (unlikely(!arg_tuple))
5518 PyTuple_SET_ITEM(arg_tuple, 0, o);
5519 res = __Pyx_Print(stream, arg_tuple, 1);
5520 Py_DECREF(arg_tuple);
5526 requires=[printing_utility_code])
5530 #------------------------------------------------------------------------------------
5532 # Exception raising code
5534 # Exceptions are raised by __Pyx_Raise() and stored as plain
5535 # type/value/tb in PyThreadState->curexc_*. When being caught by an
5536 # 'except' statement, curexc_* is moved over to exc_* by
5537 # __Pyx_GetException()
5539 restore_exception_utility_code = UtilityCode(
5541 static CYTHON_INLINE void __Pyx_ErrRestore(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
5542 static CYTHON_INLINE void __Pyx_ErrFetch(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
5545 static CYTHON_INLINE void __Pyx_ErrRestore(PyObject *type, PyObject *value, PyObject *tb) {
5546 PyObject *tmp_type, *tmp_value, *tmp_tb;
5547 PyThreadState *tstate = PyThreadState_GET();
5549 tmp_type = tstate->curexc_type;
5550 tmp_value = tstate->curexc_value;
5551 tmp_tb = tstate->curexc_traceback;
5552 tstate->curexc_type = type;
5553 tstate->curexc_value = value;
5554 tstate->curexc_traceback = tb;
5555 Py_XDECREF(tmp_type);
5556 Py_XDECREF(tmp_value);
5560 static CYTHON_INLINE void __Pyx_ErrFetch(PyObject **type, PyObject **value, PyObject **tb) {
5561 PyThreadState *tstate = PyThreadState_GET();
5562 *type = tstate->curexc_type;
5563 *value = tstate->curexc_value;
5564 *tb = tstate->curexc_traceback;
5566 tstate->curexc_type = 0;
5567 tstate->curexc_value = 0;
5568 tstate->curexc_traceback = 0;
5573 # The following function is based on do_raise() from ceval.c. There
5574 # are separate versions for Python2 and Python3 as exception handling
5575 # has changed quite a lot between the two versions.
5577 raise_utility_code = UtilityCode(
5579 static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
5582 #if PY_MAJOR_VERSION < 3
5583 static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb) {
5587 /* First, check the traceback argument, replacing None with NULL. */
5588 if (tb == Py_None) {
5592 else if (tb != NULL && !PyTraceBack_Check(tb)) {
5593 PyErr_SetString(PyExc_TypeError,
5594 "raise: arg 3 must be a traceback or None");
5597 /* Next, replace a missing value with None */
5598 if (value == NULL) {
5602 #if PY_VERSION_HEX < 0x02050000
5603 if (!PyClass_Check(type))
5605 if (!PyType_Check(type))
5608 /* Raising an instance. The value should be a dummy. */
5609 if (value != Py_None) {
5610 PyErr_SetString(PyExc_TypeError,
5611 "instance exception may not have a separate value");
5614 /* Normalize to raise <class>, <instance> */
5617 #if PY_VERSION_HEX < 0x02050000
5618 if (PyInstance_Check(type)) {
5619 type = (PyObject*) ((PyInstanceObject*)type)->in_class;
5624 PyErr_SetString(PyExc_TypeError,
5625 "raise: exception must be an old-style class or instance");
5629 type = (PyObject*) Py_TYPE(type);
5631 if (!PyType_IsSubtype((PyTypeObject *)type, (PyTypeObject *)PyExc_BaseException)) {
5632 PyErr_SetString(PyExc_TypeError,
5633 "raise: exception class must be a subclass of BaseException");
5639 __Pyx_ErrRestore(type, value, tb);
5648 #else /* Python 3+ */
5650 static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb) {
5651 if (tb == Py_None) {
5653 } else if (tb && !PyTraceBack_Check(tb)) {
5654 PyErr_SetString(PyExc_TypeError,
5655 "raise: arg 3 must be a traceback or None");
5658 if (value == Py_None)
5661 if (PyExceptionInstance_Check(type)) {
5663 PyErr_SetString(PyExc_TypeError,
5664 "instance exception may not have a separate value");
5668 type = (PyObject*) Py_TYPE(value);
5669 } else if (!PyExceptionClass_Check(type)) {
5670 PyErr_SetString(PyExc_TypeError,
5671 "raise: exception class must be a subclass of BaseException");
5675 PyErr_SetObject(type, value);
5678 PyThreadState *tstate = PyThreadState_GET();
5679 PyObject* tmp_tb = tstate->curexc_traceback;
5682 tstate->curexc_traceback = tb;
5692 requires=[restore_exception_utility_code])
5694 #------------------------------------------------------------------------------------
5696 get_exception_utility_code = UtilityCode(
5698 static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
5701 static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb) {
5702 PyObject *local_type, *local_value, *local_tb;
5703 PyObject *tmp_type, *tmp_value, *tmp_tb;
5704 PyThreadState *tstate = PyThreadState_GET();
5705 local_type = tstate->curexc_type;
5706 local_value = tstate->curexc_value;
5707 local_tb = tstate->curexc_traceback;
5708 tstate->curexc_type = 0;
5709 tstate->curexc_value = 0;
5710 tstate->curexc_traceback = 0;
5711 PyErr_NormalizeException(&local_type, &local_value, &local_tb);
5712 if (unlikely(tstate->curexc_type))
5714 #if PY_MAJOR_VERSION >= 3
5715 if (unlikely(PyException_SetTraceback(local_value, local_tb) < 0))
5719 *value = local_value;
5721 Py_INCREF(local_type);
5722 Py_INCREF(local_value);
5723 Py_INCREF(local_tb);
5724 tmp_type = tstate->exc_type;
5725 tmp_value = tstate->exc_value;
5726 tmp_tb = tstate->exc_traceback;
5727 tstate->exc_type = local_type;
5728 tstate->exc_value = local_value;
5729 tstate->exc_traceback = local_tb;
5730 /* Make sure tstate is in a consistent state when we XDECREF
5731 these objects (XDECREF may run arbitrary code). */
5732 Py_XDECREF(tmp_type);
5733 Py_XDECREF(tmp_value);
5740 Py_XDECREF(local_type);
5741 Py_XDECREF(local_value);
5742 Py_XDECREF(local_tb);
5748 #------------------------------------------------------------------------------------
5750 get_exception_tuple_utility_code = UtilityCode(proto="""
5751 static PyObject *__Pyx_GetExceptionTuple(void); /*proto*/
5753 # I doubt that calling __Pyx_GetException() here is correct as it moves
5754 # the exception from tstate->curexc_* to tstate->exc_*, which prevents
5755 # exception handlers later on from receiving it.
5757 static PyObject *__Pyx_GetExceptionTuple(void) {
5758 PyObject *type = NULL, *value = NULL, *tb = NULL;
5759 if (__Pyx_GetException(&type, &value, &tb) == 0) {
5760 PyObject* exc_info = PyTuple_New(3);
5765 PyTuple_SET_ITEM(exc_info, 0, type);
5766 PyTuple_SET_ITEM(exc_info, 1, value);
5767 PyTuple_SET_ITEM(exc_info, 2, tb);
5774 requires=[get_exception_utility_code])
5776 #------------------------------------------------------------------------------------
5778 reset_exception_utility_code = UtilityCode(
5780 static CYTHON_INLINE void __Pyx_ExceptionSave(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
5781 static void __Pyx_ExceptionReset(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
5784 static CYTHON_INLINE void __Pyx_ExceptionSave(PyObject **type, PyObject **value, PyObject **tb) {
5785 PyThreadState *tstate = PyThreadState_GET();
5786 *type = tstate->exc_type;
5787 *value = tstate->exc_value;
5788 *tb = tstate->exc_traceback;
5794 static void __Pyx_ExceptionReset(PyObject *type, PyObject *value, PyObject *tb) {
5795 PyObject *tmp_type, *tmp_value, *tmp_tb;
5796 PyThreadState *tstate = PyThreadState_GET();
5797 tmp_type = tstate->exc_type;
5798 tmp_value = tstate->exc_value;
5799 tmp_tb = tstate->exc_traceback;
5800 tstate->exc_type = type;
5801 tstate->exc_value = value;
5802 tstate->exc_traceback = tb;
5803 Py_XDECREF(tmp_type);
5804 Py_XDECREF(tmp_value);
5809 #------------------------------------------------------------------------------------
5811 arg_type_test_utility_code = UtilityCode(
5813 static int __Pyx_ArgTypeTest(PyObject *obj, PyTypeObject *type, int none_allowed,
5814 const char *name, int exact); /*proto*/
5817 static int __Pyx_ArgTypeTest(PyObject *obj, PyTypeObject *type, int none_allowed,
5818 const char *name, int exact)
5821 PyErr_Format(PyExc_SystemError, "Missing type object");
5824 if (none_allowed && obj == Py_None) return 1;
5826 if (Py_TYPE(obj) == type) return 1;
5829 if (PyObject_TypeCheck(obj, type)) return 1;
5831 PyErr_Format(PyExc_TypeError,
5832 "Argument '%s' has incorrect type (expected %s, got %s)",
5833 name, type->tp_name, Py_TYPE(obj)->tp_name);
5838 #------------------------------------------------------------------------------------
5840 # __Pyx_RaiseArgtupleInvalid raises the correct exception when too
5841 # many or too few positional arguments were found. This handles
5842 # Py_ssize_t formatting correctly.
5844 raise_argtuple_invalid_utility_code = UtilityCode(
5846 static void __Pyx_RaiseArgtupleInvalid(const char* func_name, int exact,
5847 Py_ssize_t num_min, Py_ssize_t num_max, Py_ssize_t num_found); /*proto*/
5850 static void __Pyx_RaiseArgtupleInvalid(
5851 const char* func_name,
5855 Py_ssize_t num_found)
5857 Py_ssize_t num_expected;
5858 const char *number, *more_or_less;
5860 if (num_found < num_min) {
5861 num_expected = num_min;
5862 more_or_less = "at least";
5864 num_expected = num_max;
5865 more_or_less = "at most";
5868 more_or_less = "exactly";
5870 number = (num_expected == 1) ? "" : "s";
5871 PyErr_Format(PyExc_TypeError,
5872 #if PY_VERSION_HEX < 0x02050000
5873 "%s() takes %s %d positional argument%s (%d given)",
5875 "%s() takes %s %zd positional argument%s (%zd given)",
5877 func_name, more_or_less, num_expected, number, num_found);
5881 raise_keyword_required_utility_code = UtilityCode(
5883 static CYTHON_INLINE void __Pyx_RaiseKeywordRequired(const char* func_name, PyObject* kw_name); /*proto*/
5886 static CYTHON_INLINE void __Pyx_RaiseKeywordRequired(
5887 const char* func_name,
5890 PyErr_Format(PyExc_TypeError,
5891 #if PY_MAJOR_VERSION >= 3
5892 "%s() needs keyword-only argument %U", func_name, kw_name);
5894 "%s() needs keyword-only argument %s", func_name,
5895 PyString_AS_STRING(kw_name));
5900 raise_double_keywords_utility_code = UtilityCode(
5902 static void __Pyx_RaiseDoubleKeywordsError(
5903 const char* func_name, PyObject* kw_name); /*proto*/
5906 static void __Pyx_RaiseDoubleKeywordsError(
5907 const char* func_name,
5910 PyErr_Format(PyExc_TypeError,
5911 #if PY_MAJOR_VERSION >= 3
5912 "%s() got multiple values for keyword argument '%U'", func_name, kw_name);
5914 "%s() got multiple values for keyword argument '%s'", func_name,
5915 PyString_AS_STRING(kw_name));
5920 #------------------------------------------------------------------------------------
5922 # __Pyx_CheckKeywordStrings raises an error if non-string keywords
5923 # were passed to a function, or if any keywords were passed to a
5924 # function that does not accept them.
5926 keyword_string_check_utility_code = UtilityCode(
5928 static CYTHON_INLINE int __Pyx_CheckKeywordStrings(PyObject *kwdict,
5929 const char* function_name, int kw_allowed); /*proto*/
5932 static CYTHON_INLINE int __Pyx_CheckKeywordStrings(
5934 const char* function_name,
5939 while (PyDict_Next(kwdict, &pos, &key, 0)) {
5940 #if PY_MAJOR_VERSION < 3
5941 if (unlikely(!PyString_CheckExact(key)) && unlikely(!PyString_Check(key)))
5943 if (unlikely(!PyUnicode_CheckExact(key)) && unlikely(!PyUnicode_Check(key)))
5945 goto invalid_keyword_type;
5947 if ((!kw_allowed) && unlikely(key))
5948 goto invalid_keyword;
5950 invalid_keyword_type:
5951 PyErr_Format(PyExc_TypeError,
5952 "%s() keywords must be strings", function_name);
5955 PyErr_Format(PyExc_TypeError,
5956 #if PY_MAJOR_VERSION < 3
5957 "%s() got an unexpected keyword argument '%s'",
5958 function_name, PyString_AsString(key));
5960 "%s() got an unexpected keyword argument '%U'",
5961 function_name, key);
5967 #------------------------------------------------------------------------------------
5969 # __Pyx_ParseOptionalKeywords copies the optional/unknown keyword
5970 # arguments from the kwds dict into kwds2. If kwds2 is NULL, unknown
5971 # keywords will raise an invalid keyword error.
5973 # Three kinds of errors are checked: 1) non-string keywords, 2)
5974 # unexpected keywords and 3) overlap with positional arguments.
5976 # If num_posargs is greater 0, it denotes the number of positional
5977 # arguments that were passed and that must therefore not appear
5978 # amongst the keywords as well.
5980 # This method does not check for required keyword arguments.
5983 parse_keywords_utility_code = UtilityCode(
5985 static int __Pyx_ParseOptionalKeywords(PyObject *kwds, PyObject **argnames[], \
5986 PyObject *kwds2, PyObject *values[], Py_ssize_t num_pos_args, \
5987 const char* function_name); /*proto*/
5990 static int __Pyx_ParseOptionalKeywords(
5992 PyObject **argnames[],
5995 Py_ssize_t num_pos_args,
5996 const char* function_name)
5998 PyObject *key = 0, *value = 0;
6001 PyObject*** first_kw_arg = argnames + num_pos_args;
6003 while (PyDict_Next(kwds, &pos, &key, &value)) {
6004 name = first_kw_arg;
6005 while (*name && (**name != key)) name++;
6007 values[name-argnames] = value;
6009 #if PY_MAJOR_VERSION < 3
6010 if (unlikely(!PyString_CheckExact(key)) && unlikely(!PyString_Check(key))) {
6012 if (unlikely(!PyUnicode_CheckExact(key)) && unlikely(!PyUnicode_Check(key))) {
6014 goto invalid_keyword_type;
6016 for (name = first_kw_arg; *name; name++) {
6017 #if PY_MAJOR_VERSION >= 3
6018 if (PyUnicode_GET_SIZE(**name) == PyUnicode_GET_SIZE(key) &&
6019 PyUnicode_Compare(**name, key) == 0) break;
6021 if (PyString_GET_SIZE(**name) == PyString_GET_SIZE(key) &&
6022 _PyString_Eq(**name, key)) break;
6026 values[name-argnames] = value;
6028 /* unexpected keyword found */
6029 for (name=argnames; name != first_kw_arg; name++) {
6030 if (**name == key) goto arg_passed_twice;
6031 #if PY_MAJOR_VERSION >= 3
6032 if (PyUnicode_GET_SIZE(**name) == PyUnicode_GET_SIZE(key) &&
6033 PyUnicode_Compare(**name, key) == 0) goto arg_passed_twice;
6035 if (PyString_GET_SIZE(**name) == PyString_GET_SIZE(key) &&
6036 _PyString_Eq(**name, key)) goto arg_passed_twice;
6040 if (unlikely(PyDict_SetItem(kwds2, key, value))) goto bad;
6042 goto invalid_keyword;
6050 __Pyx_RaiseDoubleKeywordsError(function_name, **name);
6052 invalid_keyword_type:
6053 PyErr_Format(PyExc_TypeError,
6054 "%s() keywords must be strings", function_name);
6057 PyErr_Format(PyExc_TypeError,
6058 #if PY_MAJOR_VERSION < 3
6059 "%s() got an unexpected keyword argument '%s'",
6060 function_name, PyString_AsString(key));
6062 "%s() got an unexpected keyword argument '%U'",
6063 function_name, key);
6070 #------------------------------------------------------------------------------------
6072 traceback_utility_code = UtilityCode(
6074 static void __Pyx_AddTraceback(const char *funcname); /*proto*/
6077 #include "compile.h"
6078 #include "frameobject.h"
6079 #include "traceback.h"
6081 static void __Pyx_AddTraceback(const char *funcname) {
6082 PyObject *py_srcfile = 0;
6083 PyObject *py_funcname = 0;
6084 PyObject *py_globals = 0;
6085 PyCodeObject *py_code = 0;
6086 PyFrameObject *py_frame = 0;
6088 #if PY_MAJOR_VERSION < 3
6089 py_srcfile = PyString_FromString(%(FILENAME)s);
6091 py_srcfile = PyUnicode_FromString(%(FILENAME)s);
6093 if (!py_srcfile) goto bad;
6095 #if PY_MAJOR_VERSION < 3
6096 py_funcname = PyString_FromFormat( "%%s (%%s:%%d)", funcname, %(CFILENAME)s, %(CLINENO)s);
6098 py_funcname = PyUnicode_FromFormat( "%%s (%%s:%%d)", funcname, %(CFILENAME)s, %(CLINENO)s);
6102 #if PY_MAJOR_VERSION < 3
6103 py_funcname = PyString_FromString(funcname);
6105 py_funcname = PyUnicode_FromString(funcname);
6108 if (!py_funcname) goto bad;
6109 py_globals = PyModule_GetDict(%(GLOBALS)s);
6110 if (!py_globals) goto bad;
6111 py_code = PyCode_New(
6112 0, /*int argcount,*/
6113 #if PY_MAJOR_VERSION >= 3
6114 0, /*int kwonlyargcount,*/
6117 0, /*int stacksize,*/
6119 %(EMPTY_BYTES)s, /*PyObject *code,*/
6120 %(EMPTY_TUPLE)s, /*PyObject *consts,*/
6121 %(EMPTY_TUPLE)s, /*PyObject *names,*/
6122 %(EMPTY_TUPLE)s, /*PyObject *varnames,*/
6123 %(EMPTY_TUPLE)s, /*PyObject *freevars,*/
6124 %(EMPTY_TUPLE)s, /*PyObject *cellvars,*/
6125 py_srcfile, /*PyObject *filename,*/
6126 py_funcname, /*PyObject *name,*/
6127 %(LINENO)s, /*int firstlineno,*/
6128 %(EMPTY_BYTES)s /*PyObject *lnotab*/
6130 if (!py_code) goto bad;
6131 py_frame = PyFrame_New(
6132 PyThreadState_GET(), /*PyThreadState *tstate,*/
6133 py_code, /*PyCodeObject *code,*/
6134 py_globals, /*PyObject *globals,*/
6135 0 /*PyObject *locals*/
6137 if (!py_frame) goto bad;
6138 py_frame->f_lineno = %(LINENO)s;
6139 PyTraceBack_Here(py_frame);
6141 Py_XDECREF(py_srcfile);
6142 Py_XDECREF(py_funcname);
6143 Py_XDECREF(py_code);
6144 Py_XDECREF(py_frame);
6147 'FILENAME': Naming.filename_cname,
6148 'LINENO': Naming.lineno_cname,
6149 'CFILENAME': Naming.cfilenm_cname,
6150 'CLINENO': Naming.clineno_cname,
6151 'GLOBALS': Naming.module_cname,
6152 'EMPTY_TUPLE' : Naming.empty_tuple,
6153 'EMPTY_BYTES' : Naming.empty_bytes,
6156 #------------------------------------------------------------------------------------
6158 unraisable_exception_utility_code = UtilityCode(
6160 static void __Pyx_WriteUnraisable(const char *name); /*proto*/
6163 static void __Pyx_WriteUnraisable(const char *name) {
6164 PyObject *old_exc, *old_val, *old_tb;
6166 __Pyx_ErrFetch(&old_exc, &old_val, &old_tb);
6167 #if PY_MAJOR_VERSION < 3
6168 ctx = PyString_FromString(name);
6170 ctx = PyUnicode_FromString(name);
6172 __Pyx_ErrRestore(old_exc, old_val, old_tb);
6174 PyErr_WriteUnraisable(Py_None);
6176 PyErr_WriteUnraisable(ctx);
6181 requires=[restore_exception_utility_code])
6183 #------------------------------------------------------------------------------------
6185 set_vtable_utility_code = UtilityCode(
6187 static int __Pyx_SetVtable(PyObject *dict, void *vtable); /*proto*/
6190 static int __Pyx_SetVtable(PyObject *dict, void *vtable) {
6191 #if PY_VERSION_HEX >= 0x02070000 && !(PY_MAJOR_VERSION==3&&PY_MINOR_VERSION==0)
6192 PyObject *ob = PyCapsule_New(vtable, 0, 0);
6194 PyObject *ob = PyCObject_FromVoidPtr(vtable, 0);
6198 if (PyDict_SetItemString(dict, "__pyx_vtable__", ob) < 0)
6208 #------------------------------------------------------------------------------------
6210 get_vtable_utility_code = UtilityCode(
6212 static int __Pyx_GetVtable(PyObject *dict, void *vtabptr); /*proto*/
6215 static int __Pyx_GetVtable(PyObject *dict, void *vtabptr) {
6216 PyObject *ob = PyMapping_GetItemString(dict, (char *)"__pyx_vtable__");
6219 #if PY_VERSION_HEX >= 0x02070000 && !(PY_MAJOR_VERSION==3&&PY_MINOR_VERSION==0)
6220 *(void **)vtabptr = PyCapsule_GetPointer(ob, 0);
6222 *(void **)vtabptr = PyCObject_AsVoidPtr(ob);
6224 if (!*(void **)vtabptr)
6234 #------------------------------------------------------------------------------------
6236 init_string_tab_utility_code = UtilityCode(
6238 static int __Pyx_InitStrings(__Pyx_StringTabEntry *t); /*proto*/
6241 static int __Pyx_InitStrings(__Pyx_StringTabEntry *t) {
6243 #if PY_MAJOR_VERSION < 3
6244 if (t->is_unicode) {
6245 *t->p = PyUnicode_DecodeUTF8(t->s, t->n - 1, NULL);
6246 } else if (t->intern) {
6247 *t->p = PyString_InternFromString(t->s);
6249 *t->p = PyString_FromStringAndSize(t->s, t->n - 1);
6251 #else /* Python 3+ has unicode identifiers */
6252 if (t->is_unicode | t->is_str) {
6254 *t->p = PyUnicode_InternFromString(t->s);
6255 } else if (t->encoding) {
6256 *t->p = PyUnicode_Decode(t->s, t->n - 1, t->encoding, NULL);
6258 *t->p = PyUnicode_FromStringAndSize(t->s, t->n - 1);
6261 *t->p = PyBytes_FromStringAndSize(t->s, t->n - 1);
6272 #------------------------------------------------------------------------------------
6274 force_init_threads_utility_code = UtilityCode(
6276 #ifndef __PYX_FORCE_INIT_THREADS
6277 #if PY_VERSION_HEX < 0x02040200
6278 #define __PYX_FORCE_INIT_THREADS 1
6280 #define __PYX_FORCE_INIT_THREADS 0
6285 #------------------------------------------------------------------------------------
6287 # Note that cPython ignores PyTrace_EXCEPTION,
6288 # but maybe some other profilers don't.
6290 profile_utility_code = UtilityCode(proto="""
6291 #ifndef CYTHON_PROFILE
6292 #define CYTHON_PROFILE 1
6295 #ifndef CYTHON_PROFILE_REUSE_FRAME
6296 #define CYTHON_PROFILE_REUSE_FRAME 0
6301 #include "compile.h"
6302 #include "frameobject.h"
6303 #include "traceback.h"
6305 #if CYTHON_PROFILE_REUSE_FRAME
6306 #define CYTHON_FRAME_MODIFIER static
6307 #define CYTHON_FRAME_DEL
6309 #define CYTHON_FRAME_MODIFIER
6310 #define CYTHON_FRAME_DEL Py_DECREF(%(FRAME)s)
6313 #define __Pyx_TraceDeclarations \\
6314 static PyCodeObject *%(FRAME_CODE)s = NULL; \\
6315 CYTHON_FRAME_MODIFIER PyFrameObject *%(FRAME)s = NULL; \\
6316 int __Pyx_use_tracing = 0;
6318 #define __Pyx_TraceCall(funcname, srcfile, firstlineno) \\
6319 if (unlikely(PyThreadState_GET()->use_tracing && PyThreadState_GET()->c_profilefunc)) { \\
6320 __Pyx_use_tracing = __Pyx_TraceSetupAndCall(&%(FRAME_CODE)s, &%(FRAME)s, funcname, srcfile, firstlineno); \\
6323 #define __Pyx_TraceException() \\
6324 if (unlikely(__Pyx_use_tracing( && PyThreadState_GET()->use_tracing && PyThreadState_GET()->c_profilefunc) { \\
6325 PyObject *exc_info = __Pyx_GetExceptionTuple(); \\
6327 PyThreadState_GET()->c_profilefunc( \\
6328 PyThreadState_GET()->c_profileobj, %(FRAME)s, PyTrace_EXCEPTION, exc_info); \\
6329 Py_DECREF(exc_info); \\
6333 #define __Pyx_TraceReturn(result) \\
6334 if (unlikely(__Pyx_use_tracing) && PyThreadState_GET()->use_tracing && PyThreadState_GET()->c_profilefunc) { \\
6335 PyThreadState_GET()->c_profilefunc( \\
6336 PyThreadState_GET()->c_profileobj, %(FRAME)s, PyTrace_RETURN, (PyObject*)result); \\
6337 CYTHON_FRAME_DEL; \\
6340 static PyCodeObject *__Pyx_createFrameCodeObject(const char *funcname, const char *srcfile, int firstlineno); /*proto*/
6341 static int __Pyx_TraceSetupAndCall(PyCodeObject** code, PyFrameObject** frame, const char *funcname, const char *srcfile, int firstlineno); /*proto*/
6345 #define __Pyx_TraceDeclarations
6346 #define __Pyx_TraceCall(funcname, srcfile, firstlineno)
6347 #define __Pyx_TraceException()
6348 #define __Pyx_TraceReturn(result)
6350 #endif /* CYTHON_PROFILE */
6353 "FRAME": Naming.frame_cname,
6354 "FRAME_CODE": Naming.frame_code_cname,
6360 static int __Pyx_TraceSetupAndCall(PyCodeObject** code,
6361 PyFrameObject** frame,
6362 const char *funcname,
6363 const char *srcfile,
6365 if (*frame == NULL || !CYTHON_PROFILE_REUSE_FRAME) {
6366 if (*code == NULL) {
6367 *code = __Pyx_createFrameCodeObject(funcname, srcfile, firstlineno);
6368 if (*code == NULL) return 0;
6370 *frame = PyFrame_New(
6371 PyThreadState_GET(), /*PyThreadState *tstate*/
6372 *code, /*PyCodeObject *code*/
6373 PyModule_GetDict(%(MODULE)s), /*PyObject *globals*/
6374 0 /*PyObject *locals*/
6376 if (*frame == NULL) return 0;
6379 (*frame)->f_tstate = PyThreadState_GET();
6381 return PyThreadState_GET()->c_profilefunc(PyThreadState_GET()->c_profileobj, *frame, PyTrace_CALL, NULL) == 0;
6384 static PyCodeObject *__Pyx_createFrameCodeObject(const char *funcname, const char *srcfile, int firstlineno) {
6385 PyObject *py_srcfile = 0;
6386 PyObject *py_funcname = 0;
6387 PyCodeObject *py_code = 0;
6389 #if PY_MAJOR_VERSION < 3
6390 py_funcname = PyString_FromString(funcname);
6391 py_srcfile = PyString_FromString(srcfile);
6393 py_funcname = PyUnicode_FromString(funcname);
6394 py_srcfile = PyUnicode_FromString(srcfile);
6396 if (!py_funcname | !py_srcfile) goto bad;
6398 py_code = PyCode_New(
6399 0, /*int argcount,*/
6400 #if PY_MAJOR_VERSION >= 3
6401 0, /*int kwonlyargcount,*/
6404 0, /*int stacksize,*/
6406 %(EMPTY_BYTES)s, /*PyObject *code,*/
6407 %(EMPTY_TUPLE)s, /*PyObject *consts,*/
6408 %(EMPTY_TUPLE)s, /*PyObject *names,*/
6409 %(EMPTY_TUPLE)s, /*PyObject *varnames,*/
6410 %(EMPTY_TUPLE)s, /*PyObject *freevars,*/
6411 %(EMPTY_TUPLE)s, /*PyObject *cellvars,*/
6412 py_srcfile, /*PyObject *filename,*/
6413 py_funcname, /*PyObject *name,*/
6414 firstlineno, /*int firstlineno,*/
6415 %(EMPTY_BYTES)s /*PyObject *lnotab*/
6419 Py_XDECREF(py_srcfile);
6420 Py_XDECREF(py_funcname);
6425 #endif /* CYTHON_PROFILE */
6427 'EMPTY_TUPLE' : Naming.empty_tuple,
6428 'EMPTY_BYTES' : Naming.empty_bytes,
6429 "MODULE": Naming.module_cname,