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 if self.exception_value.analyse_const_expression(env):
596 exc_val = self.exception_value.get_constant_c_result_code()
598 raise InternalError("get_constant_c_result_code not implemented for %s" %
599 self.exception_value.__class__.__name__)
600 if not return_type.assignable_from(self.exception_value.type):
601 error(self.exception_value.pos,
602 "Exception value incompatible with function return type")
603 exc_check = self.exception_check
604 if return_type.is_array:
606 "Function cannot return an array")
607 if return_type.is_cfunction:
609 "Function cannot return a function")
610 func_type = PyrexTypes.CFuncType(
611 return_type, func_type_args, self.has_varargs,
612 optional_arg_count = self.optional_arg_count,
613 exception_value = exc_val, exception_check = exc_check,
614 calling_convention = self.base.calling_convention,
615 nogil = self.nogil, with_gil = self.with_gil, is_overridable = self.overridable)
616 if self.optional_arg_count:
617 func_type.op_arg_struct = PyrexTypes.c_ptr_type(self.op_args_struct.type)
618 callspec = env.directives['callspec']
620 current = func_type.calling_convention
621 if current and current != callspec:
622 error(self.pos, "cannot have both '%s' and '%s' "
623 "calling conventions" % (current, callspec))
624 func_type.calling_convention = callspec
625 return self.base.analyse(func_type, env)
628 class CArgDeclNode(Node):
629 # Item in a function declaration argument list.
631 # base_type CBaseTypeNode
632 # declarator CDeclaratorNode
633 # not_none boolean Tagged with 'not None'
634 # or_none boolean Tagged with 'or None'
635 # accept_none boolean Resolved boolean for not_none/or_none
636 # default ExprNode or None
637 # default_value PyObjectConst constant for default value
638 # annotation ExprNode or None Py3 function arg annotation
639 # is_self_arg boolean Is the "self" arg of an extension type method
640 # is_type_arg boolean Is the "class" arg of an extension type classmethod
641 # is_kw_only boolean Is a keyword-only argument
643 child_attrs = ["base_type", "declarator", "default"]
649 name_declarator = None
653 def analyse(self, env, nonempty = 0, is_self_arg = False):
655 self.base_type.is_self_arg = self.is_self_arg = True
656 if self.type is None:
657 # The parser may missinterpret names as types...
659 if isinstance(self.declarator, CNameDeclaratorNode) and self.declarator.name == '':
661 self.declarator.name = self.base_type.name
662 self.base_type.name = None
663 self.base_type.is_basic_c_type = False
666 could_be_name = False
667 base_type = self.base_type.analyse(env, could_be_name = could_be_name)
668 if hasattr(self.base_type, 'arg_name') and self.base_type.arg_name:
669 self.declarator.name = self.base_type.arg_name
670 # The parser is unable to resolve the ambiguity of [] as part of the
671 # type (e.g. in buffers) or empty declarator (as with arrays).
672 # This is only arises for empty multi-dimensional arrays.
673 if (base_type.is_array
674 and isinstance(self.base_type, TemplatedTypeNode)
675 and isinstance(self.declarator, CArrayDeclaratorNode)):
676 declarator = self.declarator
677 while isinstance(declarator.base, CArrayDeclaratorNode):
678 declarator = declarator.base
679 declarator.base = self.base_type.array_declarator
680 base_type = base_type.base_type
681 return self.declarator.analyse(base_type, env, nonempty = nonempty)
683 return self.name_declarator, self.type
685 def calculate_default_value_code(self, code):
686 if self.default_value is None:
688 if self.default.is_literal:
689 # will not output any code, just assign the result_code
690 self.default.generate_evaluation_code(code)
691 return self.type.cast_code(self.default.result())
692 self.default_value = code.get_argument_default_const(self.type)
693 return self.default_value
695 def annotate(self, code):
697 self.default.annotate(code)
700 class CBaseTypeNode(Node):
701 # Abstract base class for C base type nodes.
703 # Processing during analyse_declarations phase:
710 def analyse_as_type(self, env):
711 return self.analyse(env)
713 class CAnalysedBaseTypeNode(Node):
718 def analyse(self, env, could_be_name = False):
721 class CSimpleBaseTypeNode(CBaseTypeNode):
723 # module_path [string] Qualifying name components
724 # is_basic_c_type boolean
728 # is_self_arg boolean Is self argument of C method
729 # ##is_type_arg boolean Is type argument of class method
732 arg_name = None # in case the argument name was interpreted as a type
734 def analyse(self, env, could_be_name = False):
735 # Return type descriptor.
736 #print "CSimpleBaseTypeNode.analyse: is_self_arg =", self.is_self_arg ###
738 if self.is_basic_c_type:
739 type = PyrexTypes.simple_c_type(self.signed, self.longness, self.name)
741 error(self.pos, "Unrecognised type modifier combination")
742 elif self.name == "object" and not self.module_path:
743 type = py_object_type
744 elif self.name is None:
745 if self.is_self_arg and env.is_c_class_scope:
746 #print "CSimpleBaseTypeNode.analyse: defaulting to parent type" ###
747 type = env.parent_type
748 ## elif self.is_type_arg and env.is_c_class_scope:
749 ## type = Builtin.type_type
751 type = py_object_type
754 scope = env.find_imported_module(self.module_path, self.pos)
758 if scope.is_c_class_scope:
759 scope = scope.global_scope()
760 entry = scope.lookup(self.name)
761 if entry and entry.is_type:
764 if self.is_self_arg and env.is_c_class_scope:
765 type = env.parent_type
766 ## elif self.is_type_arg and env.is_c_class_scope:
767 ## type = Builtin.type_type
769 type = py_object_type
770 self.arg_name = self.name
773 if not self.name in self.templates:
774 error(self.pos, "'%s' is not a type identifier" % self.name)
775 type = PyrexTypes.TemplatePlaceholderType(self.name)
777 error(self.pos, "'%s' is not a type identifier" % self.name)
779 if not type.is_numeric or type.is_complex:
780 error(self.pos, "can only complexify c numeric types")
781 type = PyrexTypes.CComplexType(type)
782 type.create_declaration_utility_code(env)
786 return PyrexTypes.error_type
788 class CNestedBaseTypeNode(CBaseTypeNode):
789 # For C++ classes that live inside other C++ classes.
792 # base_type CBaseTypeNode
794 child_attrs = ['base_type']
796 def analyse(self, env, could_be_name = None):
797 base_type = self.base_type.analyse(env)
798 if base_type is PyrexTypes.error_type:
799 return PyrexTypes.error_type
800 if not base_type.is_cpp_class:
801 error(self.pos, "'%s' is not a valid type scope" % base_type)
802 return PyrexTypes.error_type
803 type_entry = base_type.scope.lookup_here(self.name)
804 if not type_entry or not type_entry.is_type:
805 error(self.pos, "'%s.%s' is not a type identifier" % (base_type, self.name))
806 return PyrexTypes.error_type
807 return type_entry.type
809 class TemplatedTypeNode(CBaseTypeNode):
811 # positional_args [ExprNode] List of positional arguments
812 # keyword_args DictNode Keyword arguments
813 # base_type_node CBaseTypeNode
816 # type PyrexTypes.BufferType or PyrexTypes.CppClassType ...containing the right options
819 child_attrs = ["base_type_node", "positional_args",
820 "keyword_args", "dtype_node"]
826 def analyse(self, env, could_be_name = False, base_type = None):
827 if base_type is None:
828 base_type = self.base_type_node.analyse(env)
829 if base_type.is_error: return base_type
831 if base_type.is_cpp_class:
833 if self.keyword_args and self.keyword_args.key_value_pairs:
834 error(self.pos, "c++ templates cannot take keyword arguments");
835 self.type = PyrexTypes.error_type
838 for template_node in self.positional_args:
839 type = template_node.analyse_as_type(env)
841 error(template_node.pos, "unknown type in template argument")
843 template_types.append(type)
844 self.type = base_type.specialize_here(self.pos, template_types)
846 elif base_type.is_pyobject:
850 options = Buffer.analyse_buffer_options(
853 self.positional_args,
855 base_type.buffer_defaults)
857 if sys.version_info[0] < 3:
858 # Py 2.x enforces byte strings as keyword arguments ...
859 options = dict([ (name.encode('ASCII'), value)
860 for name, value in options.iteritems() ])
862 self.type = PyrexTypes.BufferType(base_type, **options)
866 empty_declarator = CNameDeclaratorNode(self.pos, name="", cname=None)
867 if len(self.positional_args) > 1 or self.keyword_args.key_value_pairs:
868 error(self.pos, "invalid array declaration")
869 self.type = PyrexTypes.error_type
871 # It would be nice to merge this class with CArrayDeclaratorNode,
872 # but arrays are part of the declaration, not the type...
873 if not self.positional_args:
876 dimension = self.positional_args[0]
877 self.array_declarator = CArrayDeclaratorNode(self.pos,
878 base = empty_declarator,
879 dimension = dimension)
880 self.type = self.array_declarator.analyse(base_type, env)[1]
884 class CComplexBaseTypeNode(CBaseTypeNode):
885 # base_type CBaseTypeNode
886 # declarator CDeclaratorNode
888 child_attrs = ["base_type", "declarator"]
890 def analyse(self, env, could_be_name = False):
891 base = self.base_type.analyse(env, could_be_name)
892 _, type = self.declarator.analyse(base, env)
896 class CVarDefNode(StatNode):
897 # C variable definition or forward/extern function declaration.
899 # visibility 'private' or 'public' or 'extern'
900 # base_type CBaseTypeNode
901 # declarators [CDeclaratorNode]
905 # decorators [cython.locals(...)] or None
906 # directive_locals { string : NameNode } locals defined by cython.locals(...)
908 child_attrs = ["base_type", "declarators"]
911 directive_locals = {}
913 def analyse_declarations(self, env, dest_scope = None):
916 self.dest_scope = dest_scope
917 base_type = self.base_type.analyse(env)
919 # If the field is an external typedef, we cannot be sure about the type,
920 # so do conversion ourself rather than rely on the CPython mechanism (through
921 # a property; made in AnalyseDeclarationsTransform).
922 if (dest_scope.is_c_class_scope
923 and self.visibility in ('public', 'readonly')):
926 need_property = False
927 visibility = self.visibility
929 for declarator in self.declarators:
930 name_declarator, type = declarator.analyse(base_type, env)
931 if not type.is_complete():
932 if not (self.visibility == 'extern' and type.is_array):
933 error(declarator.pos,
934 "Variable type '%s' is incomplete" % type)
935 if self.visibility == 'extern' and type.is_pyobject:
936 error(declarator.pos,
937 "Python object cannot be declared extern")
938 name = name_declarator.name
939 cname = name_declarator.cname
941 error(declarator.pos, "Missing name in declaration.")
943 if type.is_cfunction:
944 entry = dest_scope.declare_cfunction(name, type, declarator.pos,
945 cname = cname, visibility = self.visibility, in_pxd = self.in_pxd,
947 if entry is not None:
948 entry.directive_locals = self.directive_locals
950 if self.directive_locals:
951 s.error("Decorators can only be followed by functions")
952 if self.in_pxd and self.visibility != 'extern':
954 "Only 'extern' C variable declaration allowed in .pxd file")
955 entry = dest_scope.declare_var(name, type, declarator.pos,
956 cname = cname, visibility = visibility, is_cdef = 1)
957 entry.needs_property = need_property
960 class CStructOrUnionDefNode(StatNode):
962 # cname string or None
963 # kind "struct" or "union"
964 # typedef_flag boolean
965 # visibility "public" or "private"
967 # attributes [CVarDefNode] or None
971 child_attrs = ["attributes"]
973 def analyse_declarations(self, env):
975 if self.visibility == 'extern' and self.packed:
976 error(self.pos, "Cannot declare extern struct as 'packed'")
977 if self.attributes is not None:
978 scope = StructOrUnionScope(self.name)
979 self.entry = env.declare_struct_or_union(
980 self.name, self.kind, scope, self.typedef_flag, self.pos,
981 self.cname, visibility = self.visibility, packed = self.packed)
982 if self.attributes is not None:
983 if self.in_pxd and not env.in_cinclude:
984 self.entry.defined_in_pxd = 1
985 for attr in self.attributes:
986 attr.analyse_declarations(env, scope)
987 if self.visibility != 'extern':
988 need_typedef_indirection = False
989 for attr in scope.var_entries:
992 type = type.base_type
993 if type == self.entry.type:
994 error(attr.pos, "Struct cannot contain itself as a member.")
995 if self.typedef_flag:
997 type = type.base_type
998 if type == self.entry.type:
999 need_typedef_indirection = True
1000 if need_typedef_indirection:
1001 # C can't handle typedef structs that refer to themselves.
1002 struct_entry = self.entry
1003 self.entry = env.declare_typedef(
1004 self.name, struct_entry.type, self.pos,
1005 cname = self.cname, visibility='ignore')
1006 struct_entry.type.typedef_flag = False
1007 # FIXME: this might be considered a hack ;-)
1008 struct_entry.cname = struct_entry.type.cname = \
1009 '_' + self.entry.type.typedef_cname
1011 def analyse_expressions(self, env):
1014 def generate_execution_code(self, code):
1018 class CppClassNode(CStructOrUnionDefNode):
1021 # cname string or None
1022 # visibility "extern"
1024 # attributes [CVarDefNode] or None
1026 # base_classes [string]
1027 # templates [string] or None
1029 def analyse_declarations(self, env):
1031 if self.attributes is not None:
1032 scope = CppClassScope(self.name, env)
1033 base_class_types = []
1034 for base_class_name in self.base_classes:
1035 base_class_entry = env.lookup(base_class_name)
1036 if base_class_entry is None:
1037 error(self.pos, "'%s' not found" % base_class_name)
1038 elif not base_class_entry.is_type or not base_class_entry.type.is_cpp_class:
1039 error(self.pos, "'%s' is not a cpp class type" % base_class_name)
1041 base_class_types.append(base_class_entry.type)
1042 if self.templates is None:
1043 template_types = None
1045 template_types = [PyrexTypes.TemplatePlaceholderType(template_name) for template_name in self.templates]
1046 self.entry = env.declare_cpp_class(
1047 self.name, scope, self.pos,
1048 self.cname, base_class_types, visibility = self.visibility, templates = template_types)
1049 self.entry.is_cpp_class = 1
1050 if self.attributes is not None:
1051 if self.in_pxd and not env.in_cinclude:
1052 self.entry.defined_in_pxd = 1
1053 for attr in self.attributes:
1054 attr.analyse_declarations(scope)
1056 class CEnumDefNode(StatNode):
1057 # name string or None
1058 # cname string or None
1059 # items [CEnumDefItemNode]
1060 # typedef_flag boolean
1061 # visibility "public" or "private"
1065 child_attrs = ["items"]
1067 def analyse_declarations(self, env):
1068 self.entry = env.declare_enum(self.name, self.pos,
1069 cname = self.cname, typedef_flag = self.typedef_flag,
1070 visibility = self.visibility)
1071 if self.items is not None:
1072 if self.in_pxd and not env.in_cinclude:
1073 self.entry.defined_in_pxd = 1
1074 for item in self.items:
1075 item.analyse_declarations(env, self.entry)
1077 def analyse_expressions(self, env):
1080 def generate_execution_code(self, code):
1081 if self.visibility == 'public':
1082 temp = code.funcstate.allocate_temp(PyrexTypes.py_object_type, manage_ref=True)
1083 for item in self.entry.enum_values:
1084 code.putln("%s = PyInt_FromLong(%s); %s" % (
1087 code.error_goto_if_null(temp, item.pos)))
1088 code.put_gotref(temp)
1089 code.putln('if (__Pyx_SetAttrString(%s, "%s", %s) < 0) %s' % (
1090 Naming.module_cname,
1093 code.error_goto(item.pos)))
1094 code.put_decref_clear(temp, PyrexTypes.py_object_type)
1095 code.funcstate.release_temp(temp)
1098 class CEnumDefItemNode(StatNode):
1100 # cname string or None
1101 # value ExprNode or None
1103 child_attrs = ["value"]
1105 def analyse_declarations(self, env, enum_entry):
1107 self.value.analyse_const_expression(env)
1108 if not self.value.type.is_int:
1109 self.value = self.value.coerce_to(PyrexTypes.c_int_type, env)
1110 self.value.analyse_const_expression(env)
1111 entry = env.declare_const(self.name, enum_entry.type,
1112 self.value, self.pos, cname = self.cname,
1113 visibility = enum_entry.visibility)
1114 enum_entry.enum_values.append(entry)
1117 class CTypeDefNode(StatNode):
1118 # base_type CBaseTypeNode
1119 # declarator CDeclaratorNode
1120 # visibility "public" or "private"
1123 child_attrs = ["base_type", "declarator"]
1125 def analyse_declarations(self, env):
1126 base = self.base_type.analyse(env)
1127 name_declarator, type = self.declarator.analyse(base, env)
1128 name = name_declarator.name
1129 cname = name_declarator.cname
1130 entry = env.declare_typedef(name, type, self.pos,
1131 cname = cname, visibility = self.visibility)
1132 if self.in_pxd and not env.in_cinclude:
1133 entry.defined_in_pxd = 1
1135 def analyse_expressions(self, env):
1137 def generate_execution_code(self, code):
1141 class FuncDefNode(StatNode, BlockNode):
1142 # Base class for function definition nodes.
1144 # return_type PyrexType
1145 # #filename string C name of filename string const
1146 # entry Symtab.Entry
1147 # needs_closure boolean Whether or not this function has inner functions/classes/yield
1148 # directive_locals { string : NameNode } locals defined by cython.locals(...)
1152 needs_closure = False
1155 def analyse_default_values(self, env):
1156 genv = env.global_scope()
1158 for arg in self.args:
1162 arg.default.analyse_types(env)
1163 arg.default = arg.default.coerce_to(arg.type, genv)
1166 "This argument cannot have a default value")
1171 error(arg.pos, "Non-default argument following default argument")
1173 def need_gil_acquisition(self, lenv):
1176 def create_local_scope(self, env):
1178 while genv.is_py_class_scope or genv.is_c_class_scope:
1179 genv = env.outer_scope
1180 if self.needs_closure:
1181 lenv = ClosureScope(name=self.entry.name,
1183 scope_name=self.entry.cname)
1185 lenv = LocalScope(name=self.entry.name,
1188 lenv.return_type = self.return_type
1189 type = self.entry.type
1190 if type.is_cfunction:
1191 lenv.nogil = type.nogil and not type.with_gil
1192 self.local_scope = lenv
1193 lenv.directives = env.directives
1196 def generate_function_definitions(self, env, code):
1199 lenv = self.local_scope
1200 if lenv.is_closure_scope:
1201 outer_scope_cname = "%s->%s" % (Naming.cur_scope_cname,
1202 Naming.outer_scope_cname)
1204 outer_scope_cname = Naming.outer_scope_cname
1205 lenv.mangle_closure_cnames(outer_scope_cname)
1206 # Generate closure function definitions
1207 self.body.generate_function_definitions(lenv, code)
1208 # generate lambda function definitions
1209 for node in lenv.lambda_defs:
1210 node.generate_function_definitions(lenv, code)
1212 is_getbuffer_slot = (self.entry.name == "__getbuffer__" and
1213 self.entry.scope.is_c_class_scope)
1214 is_releasebuffer_slot = (self.entry.name == "__releasebuffer__" and
1215 self.entry.scope.is_c_class_scope)
1216 is_buffer_slot = is_getbuffer_slot or is_releasebuffer_slot
1218 if 'cython_unused' not in self.modifiers:
1219 self.modifiers = self.modifiers + ['cython_unused']
1221 preprocessor_guard = None
1222 if self.entry.is_special and not is_buffer_slot:
1223 slot = TypeSlots.method_name_to_slot.get(self.entry.name)
1225 preprocessor_guard = slot.preprocessor_guard_code()
1226 if (self.entry.name == '__long__' and
1227 not self.entry.scope.lookup_here('__int__')):
1228 preprocessor_guard = None
1230 profile = code.globalstate.directives['profile']
1233 error(self.pos, "Cannot profile nogil function.")
1234 code.globalstate.use_utility_code(profile_utility_code)
1236 # Generate C code for header and body of function
1237 code.enter_cfunc_scope()
1238 code.return_from_error_cleanup_label = code.new_label()
1240 # ----- Top-level constants used by this function
1241 code.mark_pos(self.pos)
1242 self.generate_cached_builtins_decls(lenv, code)
1243 # ----- Function header
1246 if preprocessor_guard:
1247 code.putln(preprocessor_guard)
1249 with_pymethdef = self.needs_assignment_synthesis(env, code)
1251 self.py_func.generate_function_header(code,
1252 with_pymethdef = with_pymethdef,
1254 self.generate_function_header(code,
1255 with_pymethdef = with_pymethdef)
1256 # ----- Local variable declarations
1257 if lenv.is_closure_scope:
1258 code.put(lenv.scope_class.type.declaration_code(Naming.cur_scope_cname))
1260 elif env.is_closure_scope:
1261 code.put(env.scope_class.type.declaration_code(Naming.outer_scope_cname))
1263 self.generate_argument_declarations(lenv, code)
1264 for entry in lenv.var_entries:
1265 if not entry.in_closure:
1266 code.put_var_declaration(entry)
1268 if not self.return_type.is_void:
1269 if self.return_type.is_pyobject:
1273 (self.return_type.declaration_code(Naming.retval_cname),
1275 tempvardecl_code = code.insertion_point()
1276 self.generate_keyword_list(code)
1278 code.put_trace_declarations()
1279 # ----- Extern library function declarations
1280 lenv.generate_library_function_declarations(code)
1281 # ----- GIL acquisition
1282 acquire_gil = self.acquire_gil
1284 env.use_utility_code(force_init_threads_utility_code)
1285 code.putln("#ifdef WITH_THREAD")
1286 code.putln("PyGILState_STATE _save = PyGILState_Ensure();")
1287 code.putln("#endif")
1288 # ----- set up refnanny
1290 code.put_setup_refcount_context(self.entry.name)
1291 # ----- Automatic lead-ins for certain special functions
1292 if is_getbuffer_slot:
1293 self.getbuffer_init(code)
1294 # ----- Create closure scope object
1295 if self.needs_closure:
1296 code.putln("%s = (%s)%s->tp_new(%s, %s, NULL);" % (
1297 Naming.cur_scope_cname,
1298 lenv.scope_class.type.declaration_code(''),
1299 lenv.scope_class.type.typeptr_cname,
1300 lenv.scope_class.type.typeptr_cname,
1301 Naming.empty_tuple))
1302 code.putln("if (unlikely(!%s)) {" % Naming.cur_scope_cname)
1303 if is_getbuffer_slot:
1304 self.getbuffer_error_cleanup(code)
1306 code.put_finish_refcount_context()
1307 # FIXME: what if the error return value is a Python value?
1308 code.putln("return %s;" % self.error_value())
1310 code.put_gotref(Naming.cur_scope_cname)
1311 # Note that it is unsafe to decref the scope at this point.
1312 if env.is_closure_scope:
1313 code.putln("%s = (%s)%s;" % (
1315 env.scope_class.type.declaration_code(''),
1317 if self.needs_closure:
1318 # inner closures own a reference to their outer parent
1319 code.put_incref(outer_scope_cname, env.scope_class.type)
1320 code.put_giveref(outer_scope_cname)
1321 # ----- Trace function call
1323 # this looks a bit late, but if we don't get here due to a
1324 # fatal error before hand, it's not really worth tracing
1325 code.put_trace_call(self.entry.name, self.pos)
1326 # ----- Fetch arguments
1327 self.generate_argument_parsing_code(env, code)
1328 # If an argument is assigned to in the body, we must
1329 # incref it to properly keep track of refcounts.
1330 for entry in lenv.arg_entries:
1331 if entry.type.is_pyobject:
1332 if entry.assignments and not entry.in_closure:
1333 code.put_var_incref(entry)
1334 # ----- Initialise local variables
1335 for entry in lenv.var_entries:
1336 if entry.type.is_pyobject and entry.init_to_none and entry.used:
1337 code.put_init_var_to_py_none(entry)
1338 # ----- Initialise local buffer auxiliary variables
1339 for entry in lenv.var_entries + lenv.arg_entries:
1340 if entry.type.is_buffer and entry.buffer_aux.buffer_info_var.used:
1341 code.putln("%s.buf = NULL;" %
1342 entry.buffer_aux.buffer_info_var.cname)
1343 # ----- Check and convert arguments
1344 self.generate_argument_type_tests(code)
1345 # ----- Acquire buffer arguments
1346 for entry in lenv.arg_entries:
1347 if entry.type.is_buffer:
1348 Buffer.put_acquire_arg_buffer(entry, code, self.pos)
1350 # -------------------------
1351 # ----- Function body -----
1352 # -------------------------
1353 self.body.generate_execution_code(code)
1355 # ----- Default return value
1357 if self.return_type.is_pyobject:
1358 #if self.return_type.is_extension_type:
1359 # lhs = "(PyObject *)%s" % Naming.retval_cname
1361 lhs = Naming.retval_cname
1362 code.put_init_to_py_none(lhs, self.return_type)
1364 val = self.return_type.default_value
1366 code.putln("%s = %s;" % (Naming.retval_cname, val))
1367 # ----- Error cleanup
1368 if code.error_label in code.labels_used:
1369 code.put_goto(code.return_label)
1370 code.put_label(code.error_label)
1371 for cname, type in code.funcstate.all_managed_temps():
1372 code.put_xdecref(cname, type)
1374 # Clean up buffers -- this calls a Python function
1375 # so need to save and restore error state
1376 buffers_present = len(lenv.buffer_entries) > 0
1378 code.globalstate.use_utility_code(restore_exception_utility_code)
1379 code.putln("{ PyObject *__pyx_type, *__pyx_value, *__pyx_tb;")
1380 code.putln("__Pyx_ErrFetch(&__pyx_type, &__pyx_value, &__pyx_tb);")
1381 for entry in lenv.buffer_entries:
1382 Buffer.put_release_buffer_code(code, entry)
1383 #code.putln("%s = 0;" % entry.cname)
1384 code.putln("__Pyx_ErrRestore(__pyx_type, __pyx_value, __pyx_tb);}")
1386 err_val = self.error_value()
1387 exc_check = self.caller_will_check_exceptions()
1388 if err_val is not None or exc_check:
1389 # TODO: Fix exception tracing (though currently unused by cProfile).
1390 # code.globalstate.use_utility_code(get_exception_tuple_utility_code)
1391 # code.put_trace_exception()
1392 code.putln('__Pyx_AddTraceback("%s");' % self.entry.qualified_name)
1394 warning(self.entry.pos, "Unraisable exception in function '%s'." \
1395 % self.entry.qualified_name, 0)
1397 '__Pyx_WriteUnraisable("%s");' %
1398 self.entry.qualified_name)
1399 env.use_utility_code(unraisable_exception_utility_code)
1400 env.use_utility_code(restore_exception_utility_code)
1401 default_retval = self.return_type.default_value
1402 if err_val is None and default_retval:
1403 err_val = default_retval
1404 if err_val is not None:
1405 code.putln("%s = %s;" % (Naming.retval_cname, err_val))
1407 if is_getbuffer_slot:
1408 self.getbuffer_error_cleanup(code)
1410 # If we are using the non-error cleanup section we should
1411 # jump past it if we have an error. The if-test below determine
1412 # whether this section is used.
1413 if buffers_present or is_getbuffer_slot:
1414 code.put_goto(code.return_from_error_cleanup_label)
1417 # ----- Non-error return cleanup
1418 code.put_label(code.return_label)
1419 for entry in lenv.buffer_entries:
1421 Buffer.put_release_buffer_code(code, entry)
1422 if is_getbuffer_slot:
1423 self.getbuffer_normal_cleanup(code)
1424 # ----- Return cleanup for both error and no-error return
1425 code.put_label(code.return_from_error_cleanup_label)
1426 if not Options.init_local_none:
1427 for entry in lenv.var_entries:
1428 if lenv.control_flow.get_state((entry.name, 'initialized')) is not True:
1429 entry.xdecref_cleanup = 1
1431 for entry in lenv.var_entries:
1432 if entry.type.is_pyobject:
1433 if entry.used and not entry.in_closure:
1434 code.put_var_decref(entry)
1435 elif entry.in_closure and self.needs_closure:
1436 code.put_giveref(entry.cname)
1437 # Decref any increfed args
1438 for entry in lenv.arg_entries:
1439 if entry.type.is_pyobject:
1440 if entry.in_closure:
1441 code.put_var_giveref(entry)
1442 elif entry.assignments:
1443 code.put_var_decref(entry)
1444 if self.needs_closure:
1445 code.put_decref(Naming.cur_scope_cname, lenv.scope_class.type)
1448 # This code is duplicated in ModuleNode.generate_module_init_func
1450 default_retval = self.return_type.default_value
1451 err_val = self.error_value()
1452 if err_val is None and default_retval:
1453 err_val = default_retval
1454 if self.return_type.is_pyobject:
1455 code.put_xgiveref(self.return_type.as_pyobject(Naming.retval_cname))
1457 if self.entry.is_special and self.entry.name == "__hash__":
1458 # Returning -1 for __hash__ is supposed to signal an error
1459 # We do as Python instances and coerce -1 into -2.
1460 code.putln("if (unlikely(%s == -1) && !PyErr_Occurred()) %s = -2;" % (
1461 Naming.retval_cname, Naming.retval_cname))
1464 if self.return_type.is_pyobject:
1465 code.put_trace_return(Naming.retval_cname)
1467 code.put_trace_return("Py_None")
1469 code.put_finish_refcount_context()
1472 code.putln("#ifdef WITH_THREAD")
1473 code.putln("PyGILState_Release(_save);")
1474 code.putln("#endif")
1476 if not self.return_type.is_void:
1477 code.putln("return %s;" % Naming.retval_cname)
1481 if preprocessor_guard:
1482 code.putln("#endif /*!(%s)*/" % preprocessor_guard)
1484 # ----- Go back and insert temp variable declarations
1485 tempvardecl_code.put_temp_declarations(code.funcstate)
1486 # ----- Python version
1487 code.exit_cfunc_scope()
1489 self.py_func.generate_function_definitions(env, code)
1490 self.generate_wrapper_functions(code)
1492 def declare_argument(self, env, arg):
1493 if arg.type.is_void:
1494 error(arg.pos, "Invalid use of 'void'")
1495 elif not arg.type.is_complete() and not arg.type.is_array:
1497 "Argument type '%s' is incomplete" % arg.type)
1498 return env.declare_arg(arg.name, arg.type, arg.pos)
1500 def generate_arg_type_test(self, arg, code):
1501 # Generate type test for one argument.
1502 if arg.type.typeobj_is_available():
1503 code.globalstate.use_utility_code(arg_type_test_utility_code)
1504 typeptr_cname = arg.type.typeptr_cname
1505 arg_code = "((PyObject *)%s)" % arg.entry.cname
1507 'if (unlikely(!__Pyx_ArgTypeTest(%s, %s, %d, "%s", %s))) %s' % (
1512 arg.type.is_builtin_type,
1513 code.error_goto(arg.pos)))
1515 error(arg.pos, "Cannot test type of extern C class "
1516 "without type object name specification")
1518 def generate_arg_none_check(self, arg, code):
1519 # Generate None check for one argument.
1520 code.globalstate.use_utility_code(arg_type_test_utility_code)
1521 code.putln('if (unlikely(((PyObject *)%s) == Py_None)) {' % arg.entry.cname)
1522 code.putln('''PyErr_Format(PyExc_TypeError, "Argument '%s' must not be None"); %s''' % (
1524 code.error_goto(arg.pos)))
1527 def generate_wrapper_functions(self, code):
1530 def generate_execution_code(self, code):
1531 # Evaluate and store argument default values
1532 for arg in self.args:
1533 default = arg.default
1535 if not default.is_literal:
1536 default.generate_evaluation_code(code)
1537 default.make_owned_reference(code)
1538 result = default.result_as(arg.type)
1541 arg.calculate_default_value_code(code),
1543 if arg.type.is_pyobject:
1544 code.put_giveref(default.result())
1545 default.generate_post_assignment_code(code)
1546 default.free_temps(code)
1547 # For Python class methods, create and store function object
1549 self.assmt.generate_execution_code(code)
1552 # Special code for the __getbuffer__ function
1554 def getbuffer_init(self, code):
1555 info = self.local_scope.arg_entries[1].cname
1556 # Python 3.0 betas have a bug in memoryview which makes it call
1557 # getbuffer with a NULL parameter. For now we work around this;
1558 # the following line should be removed when this bug is fixed.
1559 code.putln("if (%s == NULL) return 0;" % info)
1560 code.putln("%s->obj = Py_None; __Pyx_INCREF(Py_None);" % info)
1561 code.put_giveref("%s->obj" % info) # Do not refnanny object within structs
1563 def getbuffer_error_cleanup(self, code):
1564 info = self.local_scope.arg_entries[1].cname
1565 code.put_gotref("%s->obj" % info)
1566 code.putln("__Pyx_DECREF(%s->obj); %s->obj = NULL;" %
1569 def getbuffer_normal_cleanup(self, code):
1570 info = self.local_scope.arg_entries[1].cname
1571 code.putln("if (%s->obj == Py_None) {" % info)
1572 code.put_gotref("Py_None")
1573 code.putln("__Pyx_DECREF(Py_None); %s->obj = NULL;" % info)
1576 class CFuncDefNode(FuncDefNode):
1577 # C function definition.
1579 # modifiers ['inline']
1580 # visibility 'private' or 'public' or 'extern'
1581 # base_type CBaseTypeNode
1582 # declarator CDeclaratorNode
1585 # decorators [DecoratorNode] list of decorators
1587 # with_gil boolean Acquire GIL around body
1589 # py_func wrapper for calling from Python
1590 # overridable whether or not this is a cpdef function
1591 # inline_in_pxd whether this is an inline function in a pxd file
1593 child_attrs = ["base_type", "declarator", "body", "py_func"]
1595 inline_in_pxd = False
1597 directive_locals = {}
1599 def unqualified_name(self):
1600 return self.entry.name
1602 def analyse_declarations(self, env):
1603 self.directive_locals.update(env.directives['locals'])
1604 base_type = self.base_type.analyse(env)
1605 # The 2 here is because we need both function and argument names.
1606 name_declarator, type = self.declarator.analyse(base_type, env, nonempty = 2 * (self.body is not None))
1607 if not type.is_cfunction:
1609 "Suite attached to non-function declaration")
1610 # Remember the actual type according to the function header
1611 # written here, because the type in the symbol table entry
1612 # may be different if we're overriding a C method inherited
1613 # from the base type of an extension type.
1615 type.is_overridable = self.overridable
1616 declarator = self.declarator
1617 while not hasattr(declarator, 'args'):
1618 declarator = declarator.base
1619 self.args = declarator.args
1620 for formal_arg, type_arg in zip(self.args, type.args):
1621 formal_arg.type = type_arg.type
1622 formal_arg.name = type_arg.name
1623 formal_arg.cname = type_arg.cname
1624 name = name_declarator.name
1625 cname = name_declarator.cname
1626 self.entry = env.declare_cfunction(
1627 name, type, self.pos,
1628 cname = cname, visibility = self.visibility,
1629 defining = self.body is not None,
1630 api = self.api, modifiers = self.modifiers)
1631 self.entry.inline_func_in_pxd = self.inline_in_pxd
1632 self.return_type = type.return_type
1634 if self.overridable and not env.is_module_scope:
1635 if len(self.args) < 1 or not self.args[0].type.is_pyobject:
1636 # An error will be produced in the cdef function
1637 self.overridable = False
1639 if self.overridable:
1641 py_func_body = self.call_self_node(is_module_scope = env.is_module_scope)
1642 self.py_func = DefNode(pos = self.pos,
1643 name = self.entry.name,
1646 starstar_arg = None,
1648 body = py_func_body,
1650 self.py_func.is_module_scope = env.is_module_scope
1651 self.py_func.analyse_declarations(env)
1652 self.entry.as_variable = self.py_func.entry
1653 # Reset scope entry the above cfunction
1654 env.entries[name] = self.entry
1655 if not env.is_module_scope or Options.lookup_module_cpdef:
1656 self.override = OverrideCheckNode(self.pos, py_func = self.py_func)
1657 self.body = StatListNode(self.pos, stats=[self.override, self.body])
1658 self.create_local_scope(env)
1660 def call_self_node(self, omit_optional_args=0, is_module_scope=0):
1662 args = self.type.args
1663 if omit_optional_args:
1664 args = args[:len(args) - self.type.optional_arg_count]
1665 arg_names = [arg.name for arg in args]
1667 cfunc = ExprNodes.NameNode(self.pos, name=self.entry.name)
1669 self_arg = ExprNodes.NameNode(self.pos, name=arg_names[0])
1670 cfunc = ExprNodes.AttributeNode(self.pos, obj=self_arg, attribute=self.entry.name)
1671 skip_dispatch = not is_module_scope or Options.lookup_module_cpdef
1672 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)
1673 return ReturnStatNode(pos=self.pos, return_type=PyrexTypes.py_object_type, value=c_call)
1675 def declare_arguments(self, env):
1676 for arg in self.type.args:
1678 error(arg.pos, "Missing argument name")
1679 self.declare_argument(env, arg)
1681 def need_gil_acquisition(self, lenv):
1682 return self.type.with_gil
1684 def nogil_check(self, env):
1686 with_gil = type.with_gil
1687 if type.nogil and not with_gil:
1688 if type.return_type.is_pyobject:
1690 "Function with Python return type cannot be declared nogil")
1691 for entry in self.local_scope.var_entries:
1692 if entry.type.is_pyobject:
1693 error(self.pos, "Function declared nogil has Python locals or temporaries")
1695 def analyse_expressions(self, env):
1696 self.local_scope.directives = env.directives
1697 if self.py_func is not None:
1698 # this will also analyse the default values
1699 self.py_func.analyse_expressions(env)
1701 self.analyse_default_values(env)
1702 self.acquire_gil = self.need_gil_acquisition(self.local_scope)
1704 def needs_assignment_synthesis(self, env, code=None):
1707 def generate_function_header(self, code, with_pymethdef, with_opt_args = 1, with_dispatch = 1, cname = None):
1710 visibility = self.entry.visibility
1711 for arg in type.args[:len(type.args)-type.optional_arg_count]:
1712 arg_decls.append(arg.declaration_code())
1713 if with_dispatch and self.overridable:
1714 arg_decls.append(PyrexTypes.c_int_type.declaration_code(Naming.skip_dispatch_cname))
1715 if type.optional_arg_count and with_opt_args:
1716 arg_decls.append(type.op_arg_struct.declaration_code(Naming.optional_args_cname))
1717 if type.has_varargs:
1718 arg_decls.append("...")
1720 arg_decls = ["void"]
1722 cname = self.entry.func_cname
1723 entity = type.function_header_code(cname, ', '.join(arg_decls))
1724 if visibility == 'public':
1725 dll_linkage = "DL_EXPORT"
1728 header = self.return_type.declaration_code(entity,
1729 dll_linkage = dll_linkage)
1730 if visibility == 'extern':
1731 storage_class = "%s " % Naming.extern_c_macro
1732 elif visibility == 'public':
1735 storage_class = "static "
1736 if 'inline' in self.modifiers:
1737 self.modifiers[self.modifiers.index('inline')] = 'cython_inline'
1738 code.putln("%s%s %s {" % (
1740 ' '.join(self.modifiers).upper(), # macro forms
1743 def generate_argument_declarations(self, env, code):
1744 for arg in self.args:
1746 result = arg.calculate_default_value_code(code)
1747 code.putln('%s = %s;' % (
1748 arg.type.declaration_code(arg.cname), result))
1750 def generate_keyword_list(self, code):
1753 def generate_argument_parsing_code(self, env, code):
1755 if self.type.optional_arg_count:
1756 code.putln('if (%s) {' % Naming.optional_args_cname)
1757 for arg in self.args:
1759 code.putln('if (%s->%sn > %s) {' % (Naming.optional_args_cname, Naming.pyrex_prefix, i))
1760 declarator = arg.declarator
1761 while not hasattr(declarator, 'name'):
1762 declarator = declarator.base
1763 code.putln('%s = %s->%s;' % (arg.cname, Naming.optional_args_cname, self.type.opt_arg_cname(declarator.name)))
1765 for _ in range(self.type.optional_arg_count):
1769 def generate_argument_conversion_code(self, code):
1772 def generate_argument_type_tests(self, code):
1773 # Generate type tests for args whose type in a parent
1774 # class is a supertype of the declared type.
1775 for arg in self.type.args:
1776 if arg.needs_type_test:
1777 self.generate_arg_type_test(arg, code)
1778 elif arg.type.is_pyobject and not arg.accept_none:
1779 self.generate_arg_none_check(arg, code)
1781 def error_value(self):
1782 if self.return_type.is_pyobject:
1786 return self.entry.type.exception_value
1788 def caller_will_check_exceptions(self):
1789 return self.entry.type.exception_check
1791 def generate_wrapper_functions(self, code):
1792 # If the C signature of a function has changed, we need to generate
1793 # wrappers to put in the slots here.
1796 func_type = entry.type
1797 while entry.prev_entry is not None:
1799 entry = entry.prev_entry
1800 entry.func_cname = "%s%swrap_%s" % (self.entry.func_cname, Naming.pyrex_prefix, k)
1802 self.generate_function_header(code,
1804 with_dispatch = entry.type.is_overridable,
1805 with_opt_args = entry.type.optional_arg_count,
1806 cname = entry.func_cname)
1807 if not self.return_type.is_void:
1809 args = self.type.args
1810 arglist = [arg.cname for arg in args[:len(args)-self.type.optional_arg_count]]
1811 if entry.type.is_overridable:
1812 arglist.append(Naming.skip_dispatch_cname)
1813 elif func_type.is_overridable:
1815 if entry.type.optional_arg_count:
1816 arglist.append(Naming.optional_args_cname)
1817 elif func_type.optional_arg_count:
1818 arglist.append('NULL')
1819 code.putln('%s(%s);' % (self.entry.func_cname, ', '.join(arglist)))
1823 class PyArgDeclNode(Node):
1824 # Argument which must be a Python object (used
1825 # for * and ** arguments).
1828 # entry Symtab.Entry
1829 # annotation ExprNode or None Py3 argument annotation
1832 def generate_function_definitions(self, env, code):
1833 self.entry.generate_function_definitions(env, code)
1835 class DecoratorNode(Node):
1838 # decorator NameNode or CallNode or AttributeNode
1839 child_attrs = ['decorator']
1842 class DefNode(FuncDefNode):
1843 # A Python function definition.
1845 # name string the Python name of the function
1846 # lambda_name string the internal name of a lambda 'function'
1847 # decorators [DecoratorNode] list of decorators
1848 # args [CArgDeclNode] formal arguments
1849 # star_arg PyArgDeclNode or None * argument
1850 # starstar_arg PyArgDeclNode or None ** argument
1851 # doc EncodedString or None
1853 # return_type_annotation
1854 # ExprNode or None the Py3 return type annotation
1856 # The following subnode is constructed internally
1857 # when the def statement is inside a Python class definition.
1859 # assmt AssignmentNode Function construction/assignment
1861 child_attrs = ["args", "star_arg", "starstar_arg", "body", "decorators"]
1866 num_required_kw_args = 0
1867 reqd_kw_flags_cname = "0"
1870 return_type_annotation = None
1875 def __init__(self, pos, **kwds):
1876 FuncDefNode.__init__(self, pos, **kwds)
1878 for arg in self.args:
1885 self.num_kwonly_args = k
1886 self.num_required_kw_args = rk
1887 self.num_required_args = r
1889 def as_cfunction(self, cfunc=None, scope=None):
1891 error(self.star_arg.pos, "cdef function cannot have star argument")
1892 if self.starstar_arg:
1893 error(self.starstar_arg.pos, "cdef function cannot have starstar argument")
1896 for formal_arg in self.args:
1897 name_declarator, type = formal_arg.analyse(scope, nonempty=1)
1898 cfunc_args.append(PyrexTypes.CFuncTypeArg(name = name_declarator.name,
1900 type = py_object_type,
1901 pos = formal_arg.pos))
1902 cfunc_type = PyrexTypes.CFuncType(return_type = py_object_type,
1904 has_varargs = False,
1905 exception_value = None,
1906 exception_check = False,
1909 is_overridable = True)
1910 cfunc = CVarDefNode(self.pos, type=cfunc_type)
1914 cfunc_type = cfunc.type
1915 if len(self.args) != len(cfunc_type.args) or cfunc_type.has_varargs:
1916 error(self.pos, "wrong number of arguments")
1917 error(cfunc.pos, "previous declaration here")
1918 for i, (formal_arg, type_arg) in enumerate(zip(self.args, cfunc_type.args)):
1919 name_declarator, type = formal_arg.analyse(scope, nonempty=1,
1920 is_self_arg = (i == 0 and scope.is_c_class_scope))
1921 if type is None or type is PyrexTypes.py_object_type:
1922 formal_arg.type = type_arg.type
1923 formal_arg.name_declarator = name_declarator
1925 if cfunc_type.exception_value is None:
1926 exception_value = None
1928 exception_value = ExprNodes.ConstNode(self.pos, value=cfunc_type.exception_value, type=cfunc_type.return_type)
1929 declarator = CFuncDeclaratorNode(self.pos,
1930 base = CNameDeclaratorNode(self.pos, name=self.name, cname=None),
1932 has_varargs = False,
1933 exception_check = cfunc_type.exception_check,
1934 exception_value = exception_value,
1935 with_gil = cfunc_type.with_gil,
1936 nogil = cfunc_type.nogil)
1937 return CFuncDefNode(self.pos,
1939 base_type = CAnalysedBaseTypeNode(self.pos, type=cfunc_type.return_type),
1940 declarator = declarator,
1943 overridable = cfunc_type.is_overridable,
1945 with_gil = cfunc_type.with_gil,
1946 nogil = cfunc_type.nogil,
1947 visibility = 'private',
1949 directive_locals = getattr(cfunc, 'directive_locals', {}))
1951 def analyse_declarations(self, env):
1952 self.is_classmethod = self.is_staticmethod = False
1954 for decorator in self.decorators:
1955 func = decorator.decorator
1957 self.is_classmethod |= func.name == 'classmethod'
1958 self.is_staticmethod |= func.name == 'staticmethod'
1960 if self.is_classmethod and env.lookup_here('classmethod'):
1961 # classmethod() was overridden - not much we can do here ...
1962 self.is_classmethod = False
1963 if self.is_staticmethod and env.lookup_here('staticmethod'):
1964 # staticmethod() was overridden - not much we can do here ...
1965 self.is_staticmethod = False
1967 if self.name == '__new__':
1968 self.is_staticmethod = 1
1970 self.analyse_argument_types(env)
1971 if self.name == '<lambda>':
1972 self.declare_lambda_function(env)
1974 self.declare_pyfunction(env)
1975 self.analyse_signature(env)
1976 self.return_type = self.entry.signature.return_type()
1977 self.create_local_scope(env)
1979 def analyse_argument_types(self, env):
1980 directive_locals = self.directive_locals = env.directives['locals']
1981 allow_none_for_extension_args = env.directives['allow_none_for_extension_args']
1982 for arg in self.args:
1983 if hasattr(arg, 'name'):
1985 name_declarator = None
1987 base_type = arg.base_type.analyse(env)
1988 name_declarator, type = \
1989 arg.declarator.analyse(base_type, env)
1990 arg.name = name_declarator.name
1991 if arg.name in directive_locals:
1992 type_node = directive_locals[arg.name]
1993 other_type = type_node.analyse_as_type(env)
1994 if other_type is None:
1995 error(type_node.pos, "Not a type")
1996 elif (type is not PyrexTypes.py_object_type
1997 and not type.same_as(other_type)):
1998 error(arg.base_type.pos, "Signature does not agree with previous declaration")
1999 error(type_node.pos, "Previous declaration here")
2002 if name_declarator and name_declarator.cname:
2004 "Python function argument cannot have C name specification")
2005 arg.type = type.as_argument_type()
2007 arg.needs_conversion = 0
2008 arg.needs_type_test = 0
2010 if arg.type.is_pyobject:
2012 arg.accept_none = True
2014 arg.accept_none = False
2015 elif arg.type.is_extension_type or arg.type.is_builtin_type:
2016 if arg.default and arg.default.constant_result is None:
2017 # special case: def func(MyType obj = None)
2018 arg.accept_none = True
2020 # default depends on compiler directive
2021 arg.accept_none = allow_none_for_extension_args
2023 # probably just a plain 'object'
2024 arg.accept_none = True
2026 arg.accept_none = True # won't be used, but must be there
2028 error(arg.pos, "Only Python type arguments can have 'not None'")
2030 error(arg.pos, "Only Python type arguments can have 'or None'")
2032 def analyse_signature(self, env):
2033 if self.entry.is_special:
2034 self.entry.trivial_signature = len(self.args) == 1 and not (self.star_arg or self.starstar_arg)
2035 elif not env.directives['always_allow_keywords'] and not (self.star_arg or self.starstar_arg):
2036 # Use the simpler calling signature for zero- and one-argument functions.
2037 if self.entry.signature is TypeSlots.pyfunction_signature:
2038 if len(self.args) == 0:
2039 self.entry.signature = TypeSlots.pyfunction_noargs
2040 elif len(self.args) == 1:
2041 if self.args[0].default is None and not self.args[0].kw_only:
2042 self.entry.signature = TypeSlots.pyfunction_onearg
2043 elif self.entry.signature is TypeSlots.pymethod_signature:
2044 if len(self.args) == 1:
2045 self.entry.signature = TypeSlots.unaryfunc
2046 elif len(self.args) == 2:
2047 if self.args[1].default is None and not self.args[1].kw_only:
2048 self.entry.signature = TypeSlots.ibinaryfunc
2050 sig = self.entry.signature
2051 nfixed = sig.num_fixed_args()
2052 if sig is TypeSlots.pymethod_signature and nfixed == 1 \
2053 and len(self.args) == 0 and self.star_arg:
2054 # this is the only case where a diverging number of
2055 # arguments is not an error - when we have no explicit
2056 # 'self' parameter as in method(*args)
2057 sig = self.entry.signature = TypeSlots.pyfunction_signature # self is not 'really' used
2058 self.self_in_stararg = 1
2061 for i in range(min(nfixed, len(self.args))):
2064 if sig.is_self_arg(i) and not self.is_staticmethod:
2065 if self.is_classmethod:
2067 arg.hdr_type = arg.type = Builtin.type_type
2070 arg.hdr_type = arg.type = env.parent_type
2071 arg.needs_conversion = 0
2073 arg.hdr_type = sig.fixed_arg_type(i)
2074 if not arg.type.same_as(arg.hdr_type):
2075 if arg.hdr_type.is_pyobject and arg.type.is_pyobject:
2076 arg.needs_type_test = 1
2078 arg.needs_conversion = 1
2079 if arg.needs_conversion:
2080 arg.hdr_cname = Naming.arg_prefix + arg.name
2082 arg.hdr_cname = Naming.var_prefix + arg.name
2084 if nfixed > len(self.args):
2085 self.bad_signature()
2087 elif nfixed < len(self.args):
2088 if not sig.has_generic_args:
2089 self.bad_signature()
2090 for arg in self.args:
2091 if arg.is_generic and \
2092 (arg.type.is_extension_type or arg.type.is_builtin_type):
2093 arg.needs_type_test = 1
2095 def bad_signature(self):
2096 sig = self.entry.signature
2097 expected_str = "%d" % sig.num_fixed_args()
2098 if sig.has_generic_args:
2099 expected_str = expected_str + " or more"
2101 if name.startswith("__") and name.endswith("__"):
2102 desc = "Special method"
2106 "%s %s has wrong number of arguments "
2107 "(%d declared, %s expected)" % (
2108 desc, self.name, len(self.args), expected_str))
2110 def signature_has_nongeneric_args(self):
2111 argcount = len(self.args)
2112 if argcount == 0 or (
2113 argcount == 1 and (self.args[0].is_self_arg or
2114 self.args[0].is_type_arg)):
2118 def signature_has_generic_args(self):
2119 return self.entry.signature.has_generic_args
2121 def declare_pyfunction(self, env):
2122 #print "DefNode.declare_pyfunction:", self.name, "in", env ###
2124 entry = env.lookup_here(name)
2125 if entry and entry.type.is_cfunction and not self.is_wrapper:
2126 warning(self.pos, "Overriding cdef method with def method.", 5)
2127 entry = env.declare_pyfunction(name, self.pos)
2129 prefix = env.scope_prefix
2130 entry.func_cname = \
2131 Naming.pyfunc_prefix + prefix + name
2132 entry.pymethdef_cname = \
2133 Naming.pymethdef_prefix + prefix + name
2134 if Options.docstrings:
2135 entry.doc = embed_position(self.pos, self.doc)
2137 Naming.funcdoc_prefix + prefix + name
2138 if entry.is_special:
2139 if entry.name in TypeSlots.invisible or not entry.doc:
2140 entry.wrapperbase_cname = None
2142 entry.wrapperbase_cname = Naming.wrapperbase_prefix + prefix + name
2146 def declare_lambda_function(self, env):
2148 prefix = env.scope_prefix
2150 Naming.lambda_func_prefix + u'funcdef' + prefix + self.lambda_name
2151 entry = env.declare_lambda_function(func_cname, self.pos)
2152 entry.pymethdef_cname = \
2153 Naming.lambda_func_prefix + u'methdef' + prefix + self.lambda_name
2154 entry.qualified_name = env.qualify_name(self.lambda_name)
2158 def declare_arguments(self, env):
2159 for arg in self.args:
2161 error(arg.pos, "Missing argument name")
2163 env.control_flow.set_state((), (arg.name, 'source'), 'arg')
2164 env.control_flow.set_state((), (arg.name, 'initialized'), True)
2165 if arg.needs_conversion:
2166 arg.entry = env.declare_var(arg.name, arg.type, arg.pos)
2167 if arg.type.is_pyobject:
2168 arg.entry.init = "0"
2169 arg.entry.init_to_none = 0
2171 arg.entry = self.declare_argument(env, arg)
2173 arg.entry.is_self_arg = arg.is_self_arg
2175 if arg.is_self_arg or arg.is_type_arg or \
2176 (arg.type.is_extension_type and not arg.hdr_type.is_extension_type):
2177 arg.entry.is_declared_generic = 1
2178 self.declare_python_arg(env, self.star_arg)
2179 self.declare_python_arg(env, self.starstar_arg)
2181 def declare_python_arg(self, env, arg):
2183 if env.directives['infer_types'] != False:
2184 type = PyrexTypes.unspecified_type
2186 type = py_object_type
2187 entry = env.declare_var(arg.name, type, arg.pos)
2190 entry.init_to_none = 0
2191 entry.xdecref_cleanup = 1
2193 env.control_flow.set_state((), (arg.name, 'initialized'), True)
2195 def analyse_expressions(self, env):
2196 self.local_scope.directives = env.directives
2197 self.analyse_default_values(env)
2198 if self.needs_assignment_synthesis(env):
2199 # Shouldn't we be doing this at the module level too?
2200 self.synthesize_assignment_node(env)
2202 def needs_assignment_synthesis(self, env, code=None):
2203 # Should enable for module level as well, that will require more testing...
2204 if env.is_module_scope:
2206 return env.directives['binding']
2208 return code.globalstate.directives['binding']
2209 return env.is_py_class_scope or env.is_closure_scope
2211 def synthesize_assignment_node(self, env):
2213 if env.is_py_class_scope:
2214 rhs = ExprNodes.PyCFunctionNode(self.pos,
2215 pymethdef_cname = self.entry.pymethdef_cname)
2216 if not self.is_staticmethod and not self.is_classmethod:
2219 elif env.is_closure_scope:
2220 rhs = ExprNodes.InnerFunctionNode(
2221 self.pos, pymethdef_cname = self.entry.pymethdef_cname)
2223 rhs = ExprNodes.PyCFunctionNode(
2224 self.pos, pymethdef_cname = self.entry.pymethdef_cname, binding = env.directives['binding'])
2225 self.assmt = SingleAssignmentNode(self.pos,
2226 lhs = ExprNodes.NameNode(self.pos, name = self.name),
2228 self.assmt.analyse_declarations(env)
2229 self.assmt.analyse_expressions(env)
2231 def generate_function_header(self, code, with_pymethdef, proto_only=0):
2233 sig = self.entry.signature
2234 if sig.has_dummy_arg or self.self_in_stararg:
2235 arg_code_list.append(
2236 "PyObject *%s" % Naming.self_cname)
2237 for arg in self.args:
2238 if not arg.is_generic:
2239 if arg.is_self_arg or arg.is_type_arg:
2240 arg_code_list.append("PyObject *%s" % arg.hdr_cname)
2242 arg_code_list.append(
2243 arg.hdr_type.declaration_code(arg.hdr_cname))
2244 if not self.entry.is_special and sig.method_flags() == [TypeSlots.method_noargs]:
2245 arg_code_list.append("CYTHON_UNUSED PyObject *unused")
2246 if sig.has_generic_args:
2247 arg_code_list.append(
2248 "PyObject *%s, PyObject *%s"
2249 % (Naming.args_cname, Naming.kwds_cname))
2250 arg_code = ", ".join(arg_code_list)
2251 dc = self.return_type.declaration_code(self.entry.func_cname)
2252 mf = " ".join(self.modifiers).upper()
2254 header = "static %s%s(%s)" % (mf, dc, arg_code)
2255 code.putln("%s; /*proto*/" % header)
2258 if (Options.docstrings and self.entry.doc and
2259 not self.entry.scope.is_property_scope and
2260 (not self.entry.is_special or self.entry.wrapperbase_cname)):
2261 docstr = self.entry.doc
2262 if docstr.is_unicode:
2263 docstr = docstr.utf8encode()
2265 'static char %s[] = "%s";' % (
2266 self.entry.doc_cname,
2267 split_string_literal(escape_byte_string(docstr))))
2268 if self.entry.is_special:
2270 "struct wrapperbase %s;" % self.entry.wrapperbase_cname)
2273 "static PyMethodDef %s = " %
2274 self.entry.pymethdef_cname)
2275 code.put_pymethoddef(self.entry, ";", allow_skip=False)
2276 code.putln("%s {" % header)
2278 def generate_argument_declarations(self, env, code):
2279 for arg in self.args:
2280 if arg.is_generic: # or arg.needs_conversion:
2281 if arg.needs_conversion:
2282 code.putln("PyObject *%s = 0;" % arg.hdr_cname)
2283 elif not arg.entry.in_closure:
2284 code.put_var_declaration(arg.entry)
2286 def generate_keyword_list(self, code):
2287 if self.signature_has_generic_args() and \
2288 self.signature_has_nongeneric_args():
2290 "static PyObject **%s[] = {" %
2291 Naming.pykwdlist_cname)
2292 for arg in self.args:
2294 pystring_cname = code.intern_identifier(arg.name)
2295 code.put('&%s,' % pystring_cname)
2298 def generate_argument_parsing_code(self, env, code):
2299 # Generate PyArg_ParseTuple call for generic
2300 # arguments, if any.
2301 if self.entry.signature.has_dummy_arg and not self.self_in_stararg:
2302 # get rid of unused argument warning
2303 code.putln("%s = %s;" % (Naming.self_cname, Naming.self_cname))
2305 old_error_label = code.new_error_label()
2306 our_error_label = code.error_label
2307 end_label = code.new_label("argument_unpacking_done")
2309 has_kwonly_args = self.num_kwonly_args > 0
2310 has_star_or_kw_args = self.star_arg is not None \
2311 or self.starstar_arg is not None or has_kwonly_args
2313 for arg in self.args:
2314 if not arg.type.is_pyobject:
2315 done = arg.type.create_from_py_utility_code(env)
2316 if not done: pass # will fail later
2318 if not self.signature_has_generic_args():
2319 if has_star_or_kw_args:
2320 error(self.pos, "This method cannot have * or keyword arguments")
2321 self.generate_argument_conversion_code(code)
2323 elif not self.signature_has_nongeneric_args():
2324 # func(*args) or func(**kw) or func(*args, **kw)
2325 self.generate_stararg_copy_code(code)
2328 positional_args = []
2330 for arg in self.args:
2331 arg_entry = arg.entry
2334 if not arg.is_self_arg and not arg.is_type_arg:
2336 kw_only_args.append(arg)
2338 positional_args.append(arg)
2340 kw_only_args.append(arg)
2341 elif not arg.is_self_arg and not arg.is_type_arg:
2342 positional_args.append(arg)
2344 self.generate_tuple_and_keyword_parsing_code(
2345 positional_args, kw_only_args, end_label, code)
2347 code.error_label = old_error_label
2348 if code.label_used(our_error_label):
2349 if not code.label_used(end_label):
2350 code.put_goto(end_label)
2351 code.put_label(our_error_label)
2352 if has_star_or_kw_args:
2353 self.generate_arg_decref(self.star_arg, code)
2354 if self.starstar_arg:
2355 if self.starstar_arg.entry.xdecref_cleanup:
2356 code.put_var_xdecref(self.starstar_arg.entry)
2358 code.put_var_decref(self.starstar_arg.entry)
2359 code.putln('__Pyx_AddTraceback("%s");' % self.entry.qualified_name)
2360 # The arguments are put into the closure one after the
2361 # other, so when type errors are found, all references in
2362 # the closure instance must be properly ref-counted to
2363 # facilitate generic closure instance deallocation. In
2364 # the case of an argument type error, it's best to just
2365 # DECREF+clear the already handled references, as this
2366 # frees their references as early as possible.
2367 for arg in self.args:
2368 if arg.type.is_pyobject and arg.entry.in_closure:
2369 code.put_var_xdecref_clear(arg.entry)
2370 if self.needs_closure:
2371 code.put_decref(Naming.cur_scope_cname, self.local_scope.scope_class.type)
2372 code.put_finish_refcount_context()
2373 code.putln("return %s;" % self.error_value())
2374 if code.label_used(end_label):
2375 code.put_label(end_label)
2377 def generate_arg_assignment(self, arg, item, code):
2378 if arg.type.is_pyobject:
2380 item = PyrexTypes.typecast(arg.type, PyrexTypes.py_object_type, item)
2382 code.putln("%s = %s;" % (entry.cname, item))
2383 if entry.in_closure:
2384 code.put_var_incref(entry)
2386 func = arg.type.from_py_function
2388 code.putln("%s = %s(%s); %s" % (
2392 code.error_goto_if(arg.type.error_condition(arg.entry.cname), arg.pos)))
2394 error(arg.pos, "Cannot convert Python object argument to type '%s'" % arg.type)
2396 def generate_arg_xdecref(self, arg, code):
2398 code.put_var_xdecref(arg.entry)
2400 def generate_arg_decref(self, arg, code):
2402 code.put_var_decref(arg.entry)
2404 def generate_stararg_copy_code(self, code):
2405 if not self.star_arg:
2406 code.globalstate.use_utility_code(raise_argtuple_invalid_utility_code)
2407 code.putln("if (unlikely(PyTuple_GET_SIZE(%s) > 0)) {" %
2409 code.put('__Pyx_RaiseArgtupleInvalid("%s", 1, 0, 0, PyTuple_GET_SIZE(%s)); return %s;' % (
2410 self.name, Naming.args_cname, self.error_value()))
2413 code.globalstate.use_utility_code(keyword_string_check_utility_code)
2415 if self.starstar_arg:
2417 kwarg_check = "unlikely(%s)" % Naming.kwds_cname
2419 kwarg_check = "%s" % Naming.kwds_cname
2421 kwarg_check = "unlikely(%s) && unlikely(PyDict_Size(%s) > 0)" % (
2422 Naming.kwds_cname, Naming.kwds_cname)
2424 "if (%s && unlikely(!__Pyx_CheckKeywordStrings(%s, \"%s\", %d))) return %s;" % (
2425 kwarg_check, Naming.kwds_cname, self.name,
2426 bool(self.starstar_arg), self.error_value()))
2428 if self.starstar_arg:
2429 code.putln("%s = (%s) ? PyDict_Copy(%s) : PyDict_New();" % (
2430 self.starstar_arg.entry.cname,
2433 code.putln("if (unlikely(!%s)) return %s;" % (
2434 self.starstar_arg.entry.cname, self.error_value()))
2435 self.starstar_arg.entry.xdecref_cleanup = 0
2436 code.put_gotref(self.starstar_arg.entry.cname)
2438 if self.self_in_stararg:
2439 # need to create a new tuple with 'self' inserted as first item
2440 code.put("%s = PyTuple_New(PyTuple_GET_SIZE(%s)+1); if (unlikely(!%s)) " % (
2441 self.star_arg.entry.cname,
2443 self.star_arg.entry.cname))
2444 if self.starstar_arg:
2446 code.put_decref_clear(self.starstar_arg.entry.cname, py_object_type)
2447 code.putln("return %s;" % self.error_value())
2450 code.putln("return %s;" % self.error_value())
2451 code.put_gotref(self.star_arg.entry.cname)
2452 code.put_incref(Naming.self_cname, py_object_type)
2453 code.put_giveref(Naming.self_cname)
2454 code.putln("PyTuple_SET_ITEM(%s, 0, %s);" % (
2455 self.star_arg.entry.cname, Naming.self_cname))
2456 temp = code.funcstate.allocate_temp(PyrexTypes.c_py_ssize_t_type, manage_ref=False)
2457 code.putln("for (%s=0; %s < PyTuple_GET_SIZE(%s); %s++) {" % (
2458 temp, temp, Naming.args_cname, temp))
2459 code.putln("PyObject* item = PyTuple_GET_ITEM(%s, %s);" % (
2460 Naming.args_cname, temp))
2461 code.put_incref("item", py_object_type)
2462 code.put_giveref("item")
2463 code.putln("PyTuple_SET_ITEM(%s, %s+1, item);" % (
2464 self.star_arg.entry.cname, temp))
2466 code.funcstate.release_temp(temp)
2467 self.star_arg.entry.xdecref_cleanup = 0
2469 code.put_incref(Naming.args_cname, py_object_type)
2470 code.putln("%s = %s;" % (
2471 self.star_arg.entry.cname,
2473 self.star_arg.entry.xdecref_cleanup = 0
2475 def generate_tuple_and_keyword_parsing_code(self, positional_args,
2476 kw_only_args, success_label, code):
2477 argtuple_error_label = code.new_label("argtuple_error")
2479 min_positional_args = self.num_required_args - self.num_required_kw_args
2480 if len(self.args) > 0 and (self.args[0].is_self_arg or self.args[0].is_type_arg):
2481 min_positional_args -= 1
2482 max_positional_args = len(positional_args)
2483 has_fixed_positional_count = not self.star_arg and \
2484 min_positional_args == max_positional_args
2486 code.globalstate.use_utility_code(raise_double_keywords_utility_code)
2487 code.globalstate.use_utility_code(raise_argtuple_invalid_utility_code)
2488 if self.num_required_kw_args:
2489 code.globalstate.use_utility_code(raise_keyword_required_utility_code)
2491 if self.starstar_arg or self.star_arg:
2492 self.generate_stararg_init_code(max_positional_args, code)
2494 # --- optimised code when we receive keyword arguments
2495 if self.num_required_kw_args:
2496 likely_hint = "likely"
2498 likely_hint = "unlikely"
2499 code.putln("if (%s(%s)) {" % (likely_hint, Naming.kwds_cname))
2500 self.generate_keyword_unpacking_code(
2501 min_positional_args, max_positional_args,
2502 has_fixed_positional_count,
2503 positional_args, kw_only_args, argtuple_error_label, code)
2505 # --- optimised code when we do not receive any keyword arguments
2506 if (self.num_required_kw_args and min_positional_args > 0) or min_positional_args == max_positional_args:
2507 # Python raises arg tuple related errors first, so we must
2508 # check the length here
2509 if min_positional_args == max_positional_args and not self.star_arg:
2513 code.putln('} else if (PyTuple_GET_SIZE(%s) %s %d) {' % (
2514 Naming.args_cname, compare, min_positional_args))
2515 code.put_goto(argtuple_error_label)
2517 if self.num_required_kw_args:
2518 # pure error case: keywords required but not passed
2519 if max_positional_args > min_positional_args and not self.star_arg:
2520 code.putln('} else if (PyTuple_GET_SIZE(%s) > %d) {' % (
2521 Naming.args_cname, max_positional_args))
2522 code.put_goto(argtuple_error_label)
2523 code.putln('} else {')
2524 for i, arg in enumerate(kw_only_args):
2526 pystring_cname = code.intern_identifier(arg.name)
2527 # required keyword-only argument missing
2528 code.put('__Pyx_RaiseKeywordRequired("%s", %s); ' % (
2531 code.putln(code.error_goto(self.pos))
2534 elif min_positional_args == max_positional_args:
2535 # parse the exact number of positional arguments from the
2537 code.putln('} else {')
2538 for i, arg in enumerate(positional_args):
2539 item = "PyTuple_GET_ITEM(%s, %d)" % (Naming.args_cname, i)
2540 self.generate_arg_assignment(arg, item, code)
2541 self.generate_arg_default_assignments(code)
2544 # parse the positional arguments from the variable length
2546 code.putln('} else {')
2547 self.generate_arg_default_assignments(code)
2548 code.putln('switch (PyTuple_GET_SIZE(%s)) {' % Naming.args_cname)
2550 code.putln('default:')
2551 reversed_args = list(enumerate(positional_args))[::-1]
2552 for i, arg in reversed_args:
2553 if i >= min_positional_args-1:
2554 if min_positional_args > 1:
2555 code.putln('case %2d:' % (i+1)) # pure code beautification
2557 code.put('case %2d: ' % (i+1))
2558 item = "PyTuple_GET_ITEM(%s, %d)" % (Naming.args_cname, i)
2559 self.generate_arg_assignment(arg, item, code)
2560 if min_positional_args == 0:
2561 code.put('case 0: ')
2562 code.putln('break;')
2564 if min_positional_args:
2565 for i in range(min_positional_args-1, -1, -1):
2566 code.putln('case %2d:' % i)
2567 code.put_goto(argtuple_error_label)
2569 code.put('default: ')
2570 code.put_goto(argtuple_error_label)
2575 if code.label_used(argtuple_error_label):
2576 code.put_goto(success_label)
2577 code.put_label(argtuple_error_label)
2578 code.put('__Pyx_RaiseArgtupleInvalid("%s", %d, %d, %d, PyTuple_GET_SIZE(%s)); ' % (
2579 self.name, has_fixed_positional_count,
2580 min_positional_args, max_positional_args,
2582 code.putln(code.error_goto(self.pos))
2584 def generate_arg_default_assignments(self, code):
2585 for arg in self.args:
2586 if arg.is_generic and arg.default:
2590 arg.calculate_default_value_code(code)))
2592 def generate_stararg_init_code(self, max_positional_args, code):
2593 if self.starstar_arg:
2594 self.starstar_arg.entry.xdecref_cleanup = 0
2595 code.putln('%s = PyDict_New(); if (unlikely(!%s)) return %s;' % (
2596 self.starstar_arg.entry.cname,
2597 self.starstar_arg.entry.cname,
2598 self.error_value()))
2599 code.put_gotref(self.starstar_arg.entry.cname)
2601 self.star_arg.entry.xdecref_cleanup = 0
2602 code.putln('if (PyTuple_GET_SIZE(%s) > %d) {' % (
2604 max_positional_args))
2605 code.put('%s = PyTuple_GetSlice(%s, %d, PyTuple_GET_SIZE(%s)); ' % (
2606 self.star_arg.entry.cname, Naming.args_cname,
2607 max_positional_args, Naming.args_cname))
2608 code.put_gotref(self.star_arg.entry.cname)
2609 if self.starstar_arg:
2611 code.putln("if (unlikely(!%s)) {" % self.star_arg.entry.cname)
2612 code.put_decref(self.starstar_arg.entry.cname, py_object_type)
2613 code.putln('return %s;' % self.error_value())
2616 code.putln("if (unlikely(!%s)) return %s;" % (
2617 self.star_arg.entry.cname, self.error_value()))
2618 code.putln('} else {')
2619 code.put("%s = %s; " % (self.star_arg.entry.cname, Naming.empty_tuple))
2620 code.put_incref(Naming.empty_tuple, py_object_type)
2623 def generate_keyword_unpacking_code(self, min_positional_args, max_positional_args,
2624 has_fixed_positional_count, positional_args,
2625 kw_only_args, argtuple_error_label, code):
2626 all_args = tuple(positional_args) + tuple(kw_only_args)
2627 max_args = len(all_args)
2629 code.putln("Py_ssize_t kw_args = PyDict_Size(%s);" %
2631 # the 'values' array collects borrowed references to arguments
2632 # before doing any type coercion etc.
2633 code.putln("PyObject* values[%d] = {%s};" % (
2634 max_args, ','.join('0'*max_args)))
2636 # assign borrowed Python default values to the values array,
2637 # so that they can be overwritten by received arguments below
2638 for i, arg in enumerate(all_args):
2639 if arg.default and arg.type.is_pyobject:
2640 default_value = arg.calculate_default_value_code(code)
2641 code.putln('values[%d] = %s;' % (i, arg.type.as_pyobject(default_value)))
2643 # parse the args tuple and check that it's not too long
2644 code.putln('switch (PyTuple_GET_SIZE(%s)) {' % Naming.args_cname)
2646 code.putln('default:')
2647 for i in range(max_positional_args-1, -1, -1):
2648 code.put('case %2d: ' % (i+1))
2649 code.putln("values[%d] = PyTuple_GET_ITEM(%s, %d);" % (
2650 i, Naming.args_cname, i))
2651 code.putln('case 0: break;')
2652 if not self.star_arg:
2653 code.put('default: ') # more arguments than allowed
2654 code.put_goto(argtuple_error_label)
2657 # now fill up the positional/required arguments with values
2659 if self.num_required_args or max_positional_args > 0:
2660 last_required_arg = -1
2661 for i, arg in enumerate(all_args):
2663 last_required_arg = i
2664 if last_required_arg < max_positional_args:
2665 last_required_arg = max_positional_args-1
2666 num_required_args = self.num_required_args
2667 if max_positional_args > 0:
2668 code.putln('switch (PyTuple_GET_SIZE(%s)) {' % Naming.args_cname)
2669 for i, arg in enumerate(all_args[:last_required_arg+1]):
2670 if max_positional_args > 0 and i <= max_positional_args:
2671 if self.star_arg and i == max_positional_args:
2672 code.putln('default:')
2674 code.putln('case %2d:' % i)
2675 pystring_cname = code.intern_identifier(arg.name)
2678 # handled separately below
2680 code.putln('if (kw_args > 0) {')
2681 code.putln('PyObject* value = PyDict_GetItem(%s, %s);' % (
2682 Naming.kwds_cname, pystring_cname))
2683 code.putln('if (value) { values[%d] = value; kw_args--; }' % i)
2686 num_required_args -= 1
2687 code.putln('values[%d] = PyDict_GetItem(%s, %s);' % (
2688 i, Naming.kwds_cname, pystring_cname))
2689 code.putln('if (likely(values[%d])) kw_args--;' % i);
2690 if i < min_positional_args:
2692 # special case: we know arg 0 is missing
2694 code.put_goto(argtuple_error_label)
2696 # print the correct number of values (args or
2697 # kwargs) that were passed into positional
2698 # arguments up to this point
2699 code.putln('else {')
2700 code.put('__Pyx_RaiseArgtupleInvalid("%s", %d, %d, %d, %d); ' % (
2701 self.name, has_fixed_positional_count,
2702 min_positional_args, max_positional_args, i))
2703 code.putln(code.error_goto(self.pos))
2706 code.putln('else {')
2707 code.put('__Pyx_RaiseKeywordRequired("%s", %s); ' %(
2708 self.name, pystring_cname))
2709 code.putln(code.error_goto(self.pos))
2711 if max_positional_args > 0:
2714 if kw_only_args and not self.starstar_arg:
2715 # unpack optional keyword-only arguments
2716 # checking for interned strings in a dict is faster than iterating
2717 # but it's too likely that we must iterate if we expect **kwargs
2719 for i, arg in enumerate(all_args[max_positional_args:]):
2720 if not arg.kw_only or not arg.default:
2722 optional_args.append((i+max_positional_args, arg))
2724 # this mimics an unrolled loop so that we can "break" out of it
2725 code.putln('while (kw_args > 0) {')
2726 code.putln('PyObject* value;')
2727 for i, arg in optional_args:
2728 pystring_cname = code.intern_identifier(arg.name)
2730 'value = PyDict_GetItem(%s, %s);' % (
2731 Naming.kwds_cname, pystring_cname))
2733 'if (value) { values[%d] = value; if (!(--kw_args)) break; }' % i)
2734 code.putln('break;')
2737 code.putln('if (unlikely(kw_args > 0)) {')
2738 # non-positional/-required kw args left in dict: default args,
2739 # kw-only args, **kwargs or error
2741 # This is sort of a catch-all: except for checking required
2742 # arguments, this will always do the right thing for unpacking
2743 # keyword arguments, so that we can concentrate on optimising
2744 # common cases above.
2745 if max_positional_args == 0:
2748 code.putln("const Py_ssize_t used_pos_args = (PyTuple_GET_SIZE(%s) < %d) ? PyTuple_GET_SIZE(%s) : %d;" % (
2749 Naming.args_cname, max_positional_args,
2750 Naming.args_cname, max_positional_args))
2751 pos_arg_count = "used_pos_args"
2753 pos_arg_count = "PyTuple_GET_SIZE(%s)" % Naming.args_cname
2754 code.globalstate.use_utility_code(parse_keywords_utility_code)
2756 'if (unlikely(__Pyx_ParseOptionalKeywords(%s, %s, %s, values, %s, "%s") < 0)) ' % (
2758 Naming.pykwdlist_cname,
2759 self.starstar_arg and self.starstar_arg.entry.cname or '0',
2762 code.putln(code.error_goto(self.pos))
2765 # convert arg values to their final type and assign them
2766 for i, arg in enumerate(all_args):
2767 if arg.default and not arg.type.is_pyobject:
2768 code.putln("if (values[%d]) {" % i)
2769 self.generate_arg_assignment(arg, "values[%d]" % i, code)
2770 if arg.default and not arg.type.is_pyobject:
2771 code.putln('} else {')
2775 arg.calculate_default_value_code(code)))
2778 def generate_argument_conversion_code(self, code):
2779 # Generate code to convert arguments from signature type to
2780 # declared type, if needed. Also copies signature arguments
2781 # into closure fields.
2782 for arg in self.args:
2783 if arg.needs_conversion:
2784 self.generate_arg_conversion(arg, code)
2785 elif arg.entry.in_closure:
2786 code.putln('%s = %s;' % (arg.entry.cname, arg.hdr_cname))
2787 if arg.type.is_pyobject:
2788 code.put_var_incref(arg.entry)
2790 def generate_arg_conversion(self, arg, code):
2791 # Generate conversion code for one argument.
2792 old_type = arg.hdr_type
2794 if old_type.is_pyobject:
2796 code.putln("if (%s) {" % arg.hdr_cname)
2798 code.putln("assert(%s); {" % arg.hdr_cname)
2799 self.generate_arg_conversion_from_pyobject(arg, code)
2801 elif new_type.is_pyobject:
2802 self.generate_arg_conversion_to_pyobject(arg, code)
2804 if new_type.assignable_from(old_type):
2806 "%s = %s;" % (arg.entry.cname, arg.hdr_cname))
2809 "Cannot convert 1 argument from '%s' to '%s'" %
2810 (old_type, new_type))
2812 def generate_arg_conversion_from_pyobject(self, arg, code):
2814 func = new_type.from_py_function
2815 # copied from CoerceFromPyTypeNode
2817 lhs = arg.entry.cname
2818 rhs = "%s(%s)" % (func, arg.hdr_cname)
2819 if new_type.is_enum:
2820 rhs = PyrexTypes.typecast(new_type, PyrexTypes.c_long_type, rhs)
2821 code.putln("%s = %s; %s" % (
2824 code.error_goto_if(new_type.error_condition(arg.entry.cname), arg.pos)))
2827 "Cannot convert Python object argument to type '%s'"
2830 def generate_arg_conversion_to_pyobject(self, arg, code):
2831 old_type = arg.hdr_type
2832 func = old_type.to_py_function
2834 code.putln("%s = %s(%s); %s" % (
2838 code.error_goto_if_null(arg.entry.cname, arg.pos)))
2839 code.put_var_gotref(arg.entry)
2842 "Cannot convert argument of type '%s' to Python object"
2845 def generate_argument_type_tests(self, code):
2846 # Generate type tests for args whose signature
2847 # type is PyObject * and whose declared type is
2848 # a subtype thereof.
2849 for arg in self.args:
2850 if arg.needs_type_test:
2851 self.generate_arg_type_test(arg, code)
2852 elif not arg.accept_none and arg.type.is_pyobject:
2853 self.generate_arg_none_check(arg, code)
2855 def error_value(self):
2856 return self.entry.signature.error_value
2858 def caller_will_check_exceptions(self):
2861 class OverrideCheckNode(StatNode):
2862 # A Node for dispatching to the def method if it
2871 child_attrs = ['body']
2875 def analyse_expressions(self, env):
2876 self.args = env.arg_entries
2877 if self.py_func.is_module_scope:
2882 self.func_node = ExprNodes.RawCNameExprNode(self.pos, py_object_type)
2883 call_tuple = ExprNodes.TupleNode(self.pos, args=[ExprNodes.NameNode(self.pos, name=arg.name) for arg in self.args[first_arg:]])
2884 call_node = ExprNodes.SimpleCallNode(self.pos,
2885 function=self.func_node,
2886 args=[ExprNodes.NameNode(self.pos, name=arg.name) for arg in self.args[first_arg:]])
2887 self.body = ReturnStatNode(self.pos, value=call_node)
2888 self.body.analyse_expressions(env)
2890 def generate_execution_code(self, code):
2891 interned_attr_cname = code.intern_identifier(self.py_func.entry.name)
2892 # Check to see if we are an extension type
2893 if self.py_func.is_module_scope:
2894 self_arg = "((PyObject *)%s)" % Naming.module_cname
2896 self_arg = "((PyObject *)%s)" % self.args[0].cname
2897 code.putln("/* Check if called by wrapper */")
2898 code.putln("if (unlikely(%s)) ;" % Naming.skip_dispatch_cname)
2899 code.putln("/* Check if overriden in Python */")
2900 if self.py_func.is_module_scope:
2901 code.putln("else {")
2903 code.putln("else if (unlikely(Py_TYPE(%s)->tp_dictoffset != 0)) {" % self_arg)
2904 func_node_temp = code.funcstate.allocate_temp(py_object_type, manage_ref=True)
2905 self.func_node.set_cname(func_node_temp)
2906 # need to get attribute manually--scope would return cdef method
2907 err = code.error_goto_if_null(func_node_temp, self.pos)
2908 code.putln("%s = PyObject_GetAttr(%s, %s); %s" % (
2909 func_node_temp, self_arg, interned_attr_cname, err))
2910 code.put_gotref(func_node_temp)
2911 is_builtin_function_or_method = "PyCFunction_Check(%s)" % func_node_temp
2912 is_overridden = "(PyCFunction_GET_FUNCTION(%s) != (void *)&%s)" % (
2913 func_node_temp, self.py_func.entry.func_cname)
2914 code.putln("if (!%s || %s) {" % (is_builtin_function_or_method, is_overridden))
2915 self.body.generate_execution_code(code)
2917 code.put_decref_clear(func_node_temp, PyrexTypes.py_object_type)
2918 code.funcstate.release_temp(func_node_temp)
2921 class ClassDefNode(StatNode, BlockNode):
2924 class PyClassDefNode(ClassDefNode):
2925 # A Python class definition.
2927 # name EncodedString Name of the class
2928 # doc string or None
2929 # body StatNode Attribute definition code
2930 # entry Symtab.Entry
2931 # scope PyClassScope
2932 # decorators [DecoratorNode] list of decorators or None
2934 # The following subnodes are constructed internally:
2936 # dict DictNode Class dictionary
2937 # classobj ClassNode Class object
2938 # target NameNode Variable to assign class object to
2940 child_attrs = ["body", "dict", "classobj", "target"]
2943 def __init__(self, pos, name, bases, doc, body, decorators = None,
2944 keyword_args = None, starstar_arg = None):
2945 StatNode.__init__(self, pos)
2949 self.decorators = decorators
2951 self.dict = ExprNodes.DictNode(pos, key_value_pairs = [])
2952 if self.doc and Options.docstrings:
2953 doc = embed_position(self.pos, self.doc)
2954 # FIXME: correct string node?
2955 doc_node = ExprNodes.StringNode(pos, value = doc)
2958 self.classobj = ExprNodes.ClassNode(pos, name = name,
2959 bases = bases, dict = self.dict, doc = doc_node,
2960 keyword_args = keyword_args, starstar_arg = starstar_arg)
2961 self.target = ExprNodes.NameNode(pos, name = name)
2963 def as_cclass(self):
2965 Return this node as if it were declared as an extension class
2967 bases = self.classobj.bases.args
2969 base_class_name = None
2970 base_class_module = None
2971 elif len(bases) == 1:
2974 from ExprNodes import AttributeNode, NameNode
2975 while isinstance(base, AttributeNode):
2976 path.insert(0, base.attribute)
2978 if isinstance(base, NameNode):
2979 path.insert(0, base.name)
2980 base_class_name = path[-1]
2982 base_class_module = u'.'.join(path[:-1])
2984 base_class_module = None
2986 error(self.classobj.bases.args.pos, "Invalid base class")
2988 error(self.classobj.bases.args.pos, "C class may only have one base class")
2991 return CClassDefNode(self.pos,
2992 visibility = 'private',
2994 class_name = self.name,
2995 base_class_module = base_class_module,
2996 base_class_name = base_class_name,
2997 decorators = self.decorators,
3002 def create_scope(self, env):
3004 while env.is_py_class_scope or env.is_c_class_scope:
3005 env = env.outer_scope
3006 cenv = self.scope = PyClassScope(name = self.name, outer_scope = genv)
3009 def analyse_declarations(self, env):
3010 self.target.analyse_target_declaration(env)
3011 cenv = self.create_scope(env)
3012 cenv.directives = env.directives
3013 cenv.class_obj_cname = self.target.entry.cname
3014 self.body.analyse_declarations(cenv)
3016 def analyse_expressions(self, env):
3017 self.dict.analyse_expressions(env)
3018 self.classobj.analyse_expressions(env)
3019 genv = env.global_scope()
3021 self.body.analyse_expressions(cenv)
3022 self.target.analyse_target_expression(env, self.classobj)
3024 def generate_function_definitions(self, env, code):
3025 self.body.generate_function_definitions(self.scope, code)
3027 def generate_execution_code(self, code):
3028 code.pyclass_stack.append(self)
3030 self.dict.generate_evaluation_code(code)
3031 cenv.namespace_cname = cenv.class_obj_cname = self.dict.result()
3032 self.body.generate_execution_code(code)
3033 self.classobj.generate_evaluation_code(code)
3034 cenv.namespace_cname = cenv.class_obj_cname = self.classobj.result()
3035 self.target.generate_assignment_code(self.classobj, code)
3036 self.dict.generate_disposal_code(code)
3037 self.dict.free_temps(code)
3038 code.pyclass_stack.pop()
3041 class CClassDefNode(ClassDefNode):
3042 # An extension type definition.
3044 # visibility 'private' or 'public' or 'extern'
3045 # typedef_flag boolean
3047 # module_name string or None For import of extern type objects
3048 # class_name string Unqualified name of class
3049 # as_name string or None Name to declare as in this scope
3050 # base_class_module string or None Module containing the base class
3051 # base_class_name string or None Name of the base class
3052 # objstruct_name string or None Specified C name of object struct
3053 # typeobj_name string or None Specified C name of type object
3054 # in_pxd boolean Is in a .pxd file
3055 # decorators [DecoratorNode] list of decorators or None
3056 # doc string or None
3057 # body StatNode or None
3058 # entry Symtab.Entry
3059 # base_type PyExtensionType or None
3060 # buffer_defaults_node DictNode or None Declares defaults for a buffer
3061 # buffer_defaults_pos
3063 child_attrs = ["body"]
3064 buffer_defaults_node = None
3065 buffer_defaults_pos = None
3066 typedef_flag = False
3068 objstruct_name = None
3072 def analyse_declarations(self, env):
3073 #print "CClassDefNode.analyse_declarations:", self.class_name
3074 #print "...visibility =", self.visibility
3075 #print "...module_name =", self.module_name
3078 if self.buffer_defaults_node:
3079 buffer_defaults = Buffer.analyse_buffer_options(self.buffer_defaults_pos,
3080 env, [], self.buffer_defaults_node,
3081 need_complete=False)
3083 buffer_defaults = None
3085 if env.in_cinclude and not self.objstruct_name:
3086 error(self.pos, "Object struct name specification required for "
3087 "C class defined in 'extern from' block")
3088 self.base_type = None
3089 # Now that module imports are cached, we need to
3090 # import the modules for extern classes.
3091 if self.module_name:
3093 for module in env.cimported_modules:
3094 if module.name == self.module_name:
3095 self.module = module
3096 if self.module is None:
3097 self.module = ModuleScope(self.module_name, None, env.context)
3098 self.module.has_extern_class = 1
3099 env.add_imported_module(self.module)
3101 if self.base_class_name:
3102 if self.base_class_module:
3103 base_class_scope = env.find_module(self.base_class_module, self.pos)
3105 base_class_scope = env
3106 if self.base_class_name == 'object':
3107 # extension classes are special and don't need to inherit from object
3108 if base_class_scope is None or base_class_scope.lookup('object') is None:
3109 self.base_class_name = None
3110 self.base_class_module = None
3111 base_class_scope = None
3112 if base_class_scope:
3113 base_class_entry = base_class_scope.find(self.base_class_name, self.pos)
3114 if base_class_entry:
3115 if not base_class_entry.is_type:
3116 error(self.pos, "'%s' is not a type name" % self.base_class_name)
3117 elif not base_class_entry.type.is_extension_type:
3118 error(self.pos, "'%s' is not an extension type" % self.base_class_name)
3119 elif not base_class_entry.type.is_complete():
3120 error(self.pos, "Base class '%s' of type '%s' is incomplete" % (
3121 self.base_class_name, self.class_name))
3122 elif base_class_entry.type.scope and base_class_entry.type.scope.directives and \
3123 base_class_entry.type.scope.directives['final']:
3124 error(self.pos, "Base class '%s' of type '%s' is final" % (
3125 self.base_class_name, self.class_name))
3127 self.base_type = base_class_entry.type
3128 has_body = self.body is not None
3129 if self.module_name and self.visibility != 'extern':
3130 module_path = self.module_name.split(".")
3131 home_scope = env.find_imported_module(module_path, self.pos)
3137 if self.visibility == 'extern':
3138 if self.module_name == '__builtin__' and self.class_name in Builtin.builtin_types:
3139 warning(self.pos, "%s already a builtin Cython type" % self.class_name, 1)
3141 self.entry = home_scope.declare_c_class(
3142 name = self.class_name,
3144 defining = has_body and self.in_pxd,
3145 implementing = has_body and not self.in_pxd,
3146 module_name = self.module_name,
3147 base_type = self.base_type,
3148 objstruct_cname = self.objstruct_name,
3149 typeobj_cname = self.typeobj_name,
3150 visibility = self.visibility,
3151 typedef_flag = self.typedef_flag,
3153 buffer_defaults = buffer_defaults)
3154 if home_scope is not env and self.visibility == 'extern':
3155 env.add_imported_entry(self.class_name, self.entry, pos)
3156 self.scope = scope = self.entry.type.scope
3157 if scope is not None:
3158 scope.directives = env.directives
3160 if self.doc and Options.docstrings:
3161 scope.doc = embed_position(self.pos, self.doc)
3164 self.body.analyse_declarations(scope)
3168 scope.implemented = 1
3169 env.allocate_vtable_names(self.entry)
3171 def analyse_expressions(self, env):
3173 scope = self.entry.type.scope
3174 self.body.analyse_expressions(scope)
3176 def generate_function_definitions(self, env, code):
3178 self.body.generate_function_definitions(
3179 self.entry.type.scope, code)
3181 def generate_execution_code(self, code):
3182 # This is needed to generate evaluation code for
3183 # default values of method arguments.
3185 self.body.generate_execution_code(code)
3187 def annotate(self, code):
3189 self.body.annotate(code)
3192 class PropertyNode(StatNode):
3193 # Definition of a property in an extension type.
3196 # doc EncodedString or None Doc string
3199 child_attrs = ["body"]
3201 def analyse_declarations(self, env):
3202 entry = env.declare_property(self.name, self.doc, self.pos)
3204 entry.scope.directives = env.directives
3205 self.body.analyse_declarations(entry.scope)
3207 def analyse_expressions(self, env):
3208 self.body.analyse_expressions(env)
3210 def generate_function_definitions(self, env, code):
3211 self.body.generate_function_definitions(env, code)
3213 def generate_execution_code(self, code):
3216 def annotate(self, code):
3217 self.body.annotate(code)
3220 class GlobalNode(StatNode):
3221 # Global variable declaration.
3227 def analyse_declarations(self, env):
3228 for name in self.names:
3229 env.declare_global(name, self.pos)
3231 def analyse_expressions(self, env):
3234 def generate_execution_code(self, code):
3238 class ExprStatNode(StatNode):
3239 # Expression used as a statement.
3243 child_attrs = ["expr"]
3245 def analyse_declarations(self, env):
3247 if isinstance(self.expr, ExprNodes.GeneralCallNode):
3248 func = self.expr.function.as_cython_attribute()
3249 if func == u'declare':
3250 args, kwds = self.expr.explicit_args_kwds()
3252 error(self.expr.pos, "Variable names must be specified.")
3253 for var, type_node in kwds.key_value_pairs:
3254 type = type_node.analyse_as_type(env)
3256 error(type_node.pos, "Unknown type")
3258 env.declare_var(var.value, type, var.pos, is_cdef = True)
3259 self.__class__ = PassStatNode
3261 def analyse_expressions(self, env):
3262 self.expr.analyse_expressions(env)
3264 def generate_execution_code(self, code):
3265 self.expr.generate_evaluation_code(code)
3266 if not self.expr.is_temp and self.expr.result():
3267 code.putln("%s;" % self.expr.result())
3268 self.expr.generate_disposal_code(code)
3269 self.expr.free_temps(code)
3271 def generate_function_definitions(self, env, code):
3272 self.expr.generate_function_definitions(env, code)
3274 def annotate(self, code):
3275 self.expr.annotate(code)
3278 class AssignmentNode(StatNode):
3279 # Abstract base class for assignment nodes.
3281 # The analyse_expressions and generate_execution_code
3282 # phases of assignments are split into two sub-phases
3283 # each, to enable all the right hand sides of a
3284 # parallel assignment to be evaluated before assigning
3285 # to any of the left hand sides.
3287 def analyse_expressions(self, env):
3288 self.analyse_types(env)
3290 # def analyse_expressions(self, env):
3291 # self.analyse_expressions_1(env)
3292 # self.analyse_expressions_2(env)
3294 def generate_execution_code(self, code):
3295 self.generate_rhs_evaluation_code(code)
3296 self.generate_assignment_code(code)
3299 class SingleAssignmentNode(AssignmentNode):
3300 # The simplest case:
3304 # lhs ExprNode Left hand side
3305 # rhs ExprNode Right hand side
3306 # first bool Is this guaranteed the first assignment to lhs?
3308 child_attrs = ["lhs", "rhs"]
3310 declaration_only = False
3312 def analyse_declarations(self, env):
3315 # handle declarations of the form x = cython.foo()
3316 if isinstance(self.rhs, ExprNodes.CallNode):
3317 func_name = self.rhs.function.as_cython_attribute()
3319 args, kwds = self.rhs.explicit_args_kwds()
3321 if func_name in ['declare', 'typedef']:
3322 if len(args) > 2 or kwds is not None:
3323 error(rhs.pos, "Can only declare one type at a time.")
3325 type = args[0].analyse_as_type(env)
3327 error(args[0].pos, "Unknown type")
3330 if func_name == 'declare':
3331 if isinstance(lhs, ExprNodes.NameNode):
3332 vars = [(lhs.name, lhs.pos)]
3333 elif isinstance(lhs, ExprNodes.TupleNode):
3334 vars = [(var.name, var.pos) for var in lhs.args]
3336 error(lhs.pos, "Invalid declaration")
3338 for var, pos in vars:
3339 env.declare_var(var, type, pos, is_cdef = True)
3344 self.declaration_only = True
3346 self.declaration_only = True
3347 if not isinstance(lhs, ExprNodes.NameNode):
3348 error(lhs.pos, "Invalid declaration.")
3349 env.declare_typedef(lhs.name, type, self.pos, visibility='private')
3351 elif func_name in ['struct', 'union']:
3352 self.declaration_only = True
3353 if len(args) > 0 or kwds is None:
3354 error(rhs.pos, "Struct or union members must be given by name.")
3357 for member, type_node in kwds.key_value_pairs:
3358 type = type_node.analyse_as_type(env)
3360 error(type_node.pos, "Unknown type")
3362 members.append((member.value, type, member.pos))
3363 if len(members) < len(kwds.key_value_pairs):
3365 if not isinstance(self.lhs, ExprNodes.NameNode):
3366 error(self.lhs.pos, "Invalid declaration.")
3367 name = self.lhs.name
3368 scope = StructOrUnionScope(name)
3369 env.declare_struct_or_union(name, func_name, scope, False, self.rhs.pos)
3370 for member, type, pos in members:
3371 scope.declare_var(member, type, pos)
3373 if self.declaration_only:
3376 self.lhs.analyse_target_declaration(env)
3378 def analyse_types(self, env, use_temp = 0):
3379 self.rhs.analyse_types(env)
3380 self.lhs.analyse_target_types(env)
3381 self.lhs.gil_assignment_check(env)
3382 self.rhs = self.rhs.coerce_to(self.lhs.type, env)
3384 self.rhs = self.rhs.coerce_to_temp(env)
3386 def generate_rhs_evaluation_code(self, code):
3387 self.rhs.generate_evaluation_code(code)
3389 def generate_assignment_code(self, code):
3390 self.lhs.generate_assignment_code(self.rhs, code)
3392 def generate_function_definitions(self, env, code):
3393 self.rhs.generate_function_definitions(env, code)
3395 def annotate(self, code):
3396 self.lhs.annotate(code)
3397 self.rhs.annotate(code)
3400 class CascadedAssignmentNode(AssignmentNode):
3401 # An assignment with multiple left hand sides:
3405 # lhs_list [ExprNode] Left hand sides
3406 # rhs ExprNode Right hand sides
3410 # coerced_rhs_list [ExprNode] RHS coerced to type of each LHS
3412 child_attrs = ["lhs_list", "rhs", "coerced_rhs_list"]
3413 coerced_rhs_list = None
3415 def analyse_declarations(self, env):
3416 for lhs in self.lhs_list:
3417 lhs.analyse_target_declaration(env)
3419 def analyse_types(self, env, use_temp = 0):
3420 self.rhs.analyse_types(env)
3421 if not self.rhs.is_simple():
3423 self.rhs = self.rhs.coerce_to_temp(env)
3425 self.rhs = self.rhs.coerce_to_simple(env)
3426 from ExprNodes import CloneNode
3427 self.coerced_rhs_list = []
3428 for lhs in self.lhs_list:
3429 lhs.analyse_target_types(env)
3430 lhs.gil_assignment_check(env)
3431 rhs = CloneNode(self.rhs)
3432 rhs = rhs.coerce_to(lhs.type, env)
3433 self.coerced_rhs_list.append(rhs)
3435 def generate_rhs_evaluation_code(self, code):
3436 self.rhs.generate_evaluation_code(code)
3438 def generate_assignment_code(self, code):
3439 for i in range(len(self.lhs_list)):
3440 lhs = self.lhs_list[i]
3441 rhs = self.coerced_rhs_list[i]
3442 rhs.generate_evaluation_code(code)
3443 lhs.generate_assignment_code(rhs, code)
3444 # Assignment has disposed of the cloned RHS
3445 self.rhs.generate_disposal_code(code)
3446 self.rhs.free_temps(code)
3448 def generate_function_definitions(self, env, code):
3449 self.rhs.generate_function_definitions(env, code)
3451 def annotate(self, code):
3452 for i in range(len(self.lhs_list)):
3453 lhs = self.lhs_list[i].annotate(code)
3454 rhs = self.coerced_rhs_list[i].annotate(code)
3455 self.rhs.annotate(code)
3458 class ParallelAssignmentNode(AssignmentNode):
3459 # A combined packing/unpacking assignment:
3463 # This has been rearranged by the parser into
3465 # a = d ; b = e ; c = f
3467 # but we must evaluate all the right hand sides
3468 # before assigning to any of the left hand sides.
3470 # stats [AssignmentNode] The constituent assignments
3472 child_attrs = ["stats"]
3474 def analyse_declarations(self, env):
3475 for stat in self.stats:
3476 stat.analyse_declarations(env)
3478 def analyse_expressions(self, env):
3479 for stat in self.stats:
3480 stat.analyse_types(env, use_temp = 1)
3482 # def analyse_expressions(self, env):
3483 # for stat in self.stats:
3484 # stat.analyse_expressions_1(env, use_temp = 1)
3485 # for stat in self.stats:
3486 # stat.analyse_expressions_2(env)
3488 def generate_execution_code(self, code):
3489 for stat in self.stats:
3490 stat.generate_rhs_evaluation_code(code)
3491 for stat in self.stats:
3492 stat.generate_assignment_code(code)
3494 def generate_function_definitions(self, env, code):
3495 for stat in self.stats:
3496 stat.generate_function_definitions(env, code)
3498 def annotate(self, code):
3499 for stat in self.stats:
3503 class InPlaceAssignmentNode(AssignmentNode):
3504 # An in place arithmetic operand:
3510 # lhs ExprNode Left hand side
3511 # rhs ExprNode Right hand side
3512 # op char one of "+-*/%^&|"
3513 # dup (ExprNode) copy of lhs used for operation (auto-generated)
3515 # This code is a bit tricky because in order to obey Python
3516 # semantics the sub-expressions (e.g. indices) of the lhs must
3517 # not be evaluated twice. So we must re-use the values calculated
3518 # in evaluation phase for the assignment phase as well.
3519 # Fortunately, the type of the lhs node is fairly constrained
3520 # (it must be a NameNode, AttributeNode, or IndexNode).
3522 child_attrs = ["lhs", "rhs"]
3524 def analyse_declarations(self, env):
3525 self.lhs.analyse_target_declaration(env)
3527 def analyse_types(self, env):
3528 self.rhs.analyse_types(env)
3529 self.lhs.analyse_target_types(env)
3531 def generate_execution_code(self, code):
3533 self.rhs.generate_evaluation_code(code)
3534 self.lhs.generate_subexpr_evaluation_code(code)
3535 c_op = self.operator
3539 error(self.pos, "No C inplace power operator")
3540 if isinstance(self.lhs, ExprNodes.IndexNode) and self.lhs.is_buffer_access:
3541 if self.lhs.type.is_pyobject:
3542 error(self.pos, "In-place operators not allowed on object buffers in this release.")
3543 if c_op in ('/', '%') and self.lhs.type.is_int and not code.directives['cdivision']:
3544 error(self.pos, "In-place non-c divide operators not allowed on int buffers.")
3545 self.lhs.generate_buffer_setitem_code(self.rhs, code, c_op)
3548 # TODO: make sure overload is declared
3549 code.putln("%s %s= %s;" % (self.lhs.result(), c_op, self.rhs.result()))
3550 self.lhs.generate_subexpr_disposal_code(code)
3551 self.lhs.free_subexpr_temps(code)
3552 self.rhs.generate_disposal_code(code)
3553 self.rhs.free_temps(code)
3556 "|": "PyNumber_InPlaceOr",
3557 "^": "PyNumber_InPlaceXor",
3558 "&": "PyNumber_InPlaceAnd",
3559 "+": "PyNumber_InPlaceAdd",
3560 "-": "PyNumber_InPlaceSubtract",
3561 "*": "PyNumber_InPlaceMultiply",
3562 "/": "__Pyx_PyNumber_InPlaceDivide",
3563 "%": "PyNumber_InPlaceRemainder",
3564 "<<": "PyNumber_InPlaceLshift",
3565 ">>": "PyNumber_InPlaceRshift",
3566 "**": "PyNumber_InPlacePower",
3567 "//": "PyNumber_InPlaceFloorDivide",
3570 def annotate(self, code):
3571 self.lhs.annotate(code)
3572 self.rhs.annotate(code)
3574 def create_binop_node(self):
3576 return ExprNodes.binop_node(self.pos, self.operator, self.lhs, self.rhs)
3579 class PrintStatNode(StatNode):
3582 # arg_tuple TupleNode
3583 # stream ExprNode or None (stdout)
3584 # append_newline boolean
3586 child_attrs = ["arg_tuple", "stream"]
3588 def analyse_expressions(self, env):
3590 self.stream.analyse_expressions(env)
3591 self.stream = self.stream.coerce_to_pyobject(env)
3592 self.arg_tuple.analyse_expressions(env)
3593 self.arg_tuple = self.arg_tuple.coerce_to_pyobject(env)
3594 env.use_utility_code(printing_utility_code)
3595 if len(self.arg_tuple.args) == 1 and self.append_newline:
3596 env.use_utility_code(printing_one_utility_code)
3598 nogil_check = Node.gil_error
3599 gil_message = "Python print statement"
3601 def generate_execution_code(self, code):
3603 self.stream.generate_evaluation_code(code)
3604 stream_result = self.stream.py_result()
3607 if len(self.arg_tuple.args) == 1 and self.append_newline:
3608 arg = self.arg_tuple.args[0]
3609 arg.generate_evaluation_code(code)
3612 "if (__Pyx_PrintOne(%s, %s) < 0) %s" % (
3615 code.error_goto(self.pos)))
3616 arg.generate_disposal_code(code)
3617 arg.free_temps(code)
3619 self.arg_tuple.generate_evaluation_code(code)
3621 "if (__Pyx_Print(%s, %s, %d) < 0) %s" % (
3623 self.arg_tuple.py_result(),
3624 self.append_newline,
3625 code.error_goto(self.pos)))
3626 self.arg_tuple.generate_disposal_code(code)
3627 self.arg_tuple.free_temps(code)
3630 self.stream.generate_disposal_code(code)
3631 self.stream.free_temps(code)
3633 def generate_function_definitions(self, env, code):
3635 self.stream.generate_function_definitions(env, code)
3636 self.arg_tuple.generate_function_definitions(env, code)
3638 def annotate(self, code):
3640 self.stream.annotate(code)
3641 self.arg_tuple.annotate(code)
3644 class ExecStatNode(StatNode):
3649 child_attrs = ["args"]
3651 def analyse_expressions(self, env):
3652 for i, arg in enumerate(self.args):
3653 arg.analyse_expressions(env)
3654 arg = arg.coerce_to_pyobject(env)
3656 env.use_utility_code(Builtin.pyexec_utility_code)
3658 nogil_check = Node.gil_error
3659 gil_message = "Python exec statement"
3661 def generate_execution_code(self, code):
3663 for arg in self.args:
3664 arg.generate_evaluation_code(code)
3665 args.append( arg.py_result() )
3666 args = tuple(args + ['0', '0'][:3-len(args)])
3667 temp_result = code.funcstate.allocate_temp(PyrexTypes.py_object_type, manage_ref=True)
3668 code.putln("%s = __Pyx_PyRun(%s, %s, %s);" % (
3669 (temp_result,) + args))
3670 for arg in self.args:
3671 arg.generate_disposal_code(code)
3672 arg.free_temps(code)
3674 code.error_goto_if_null(temp_result, self.pos))
3675 code.put_gotref(temp_result)
3676 code.put_decref_clear(temp_result, py_object_type)
3677 code.funcstate.release_temp(temp_result)
3679 def annotate(self, code):
3680 for arg in self.args:
3684 class DelStatNode(StatNode):
3689 child_attrs = ["args"]
3691 def analyse_declarations(self, env):
3692 for arg in self.args:
3693 arg.analyse_target_declaration(env)
3695 def analyse_expressions(self, env):
3696 for arg in self.args:
3697 arg.analyse_target_expression(env, None)
3698 if arg.type.is_pyobject:
3700 elif arg.type.is_ptr and arg.type.base_type.is_cpp_class:
3702 elif arg.type.is_cpp_class:
3703 error(arg.pos, "Deletion of non-heap C++ object")
3705 error(arg.pos, "Deletion of non-Python, non-C++ object")
3706 #arg.release_target_temp(env)
3708 def nogil_check(self, env):
3709 for arg in self.args:
3710 if arg.type.is_pyobject:
3713 gil_message = "Deleting Python object"
3715 def generate_execution_code(self, code):
3716 for arg in self.args:
3717 if arg.type.is_pyobject:
3718 arg.generate_deletion_code(code)
3719 elif arg.type.is_ptr and arg.type.base_type.is_cpp_class:
3720 arg.generate_result_code(code)
3721 code.putln("delete %s;" % arg.result())
3722 # else error reported earlier
3724 def annotate(self, code):
3725 for arg in self.args:
3729 class PassStatNode(StatNode):
3734 def analyse_expressions(self, env):
3737 def generate_execution_code(self, code):
3741 class BreakStatNode(StatNode):
3745 def analyse_expressions(self, env):
3748 def generate_execution_code(self, code):
3749 if not code.break_label:
3750 error(self.pos, "break statement not inside loop")
3752 code.put_goto(code.break_label)
3755 class ContinueStatNode(StatNode):
3759 def analyse_expressions(self, env):
3762 def generate_execution_code(self, code):
3763 if code.funcstate.in_try_finally:
3764 error(self.pos, "continue statement inside try of try...finally")
3765 elif not code.continue_label:
3766 error(self.pos, "continue statement not inside loop")
3768 code.put_goto(code.continue_label)
3771 class ReturnStatNode(StatNode):
3774 # value ExprNode or None
3775 # return_type PyrexType
3777 child_attrs = ["value"]
3779 def analyse_expressions(self, env):
3780 return_type = env.return_type
3781 self.return_type = return_type
3783 error(self.pos, "Return not inside a function body")
3786 self.value.analyse_types(env)
3787 if return_type.is_void or return_type.is_returncode:
3788 error(self.value.pos,
3789 "Return with value in void function")
3791 self.value = self.value.coerce_to(env.return_type, env)
3793 if (not return_type.is_void
3794 and not return_type.is_pyobject
3795 and not return_type.is_returncode):
3796 error(self.pos, "Return value required")
3798 def nogil_check(self, env):
3799 if self.return_type.is_pyobject:
3802 gil_message = "Returning Python object"
3804 def generate_execution_code(self, code):
3805 code.mark_pos(self.pos)
3806 if not self.return_type:
3807 # error reported earlier
3809 if self.return_type.is_pyobject:
3810 code.put_xdecref(Naming.retval_cname,
3813 self.value.generate_evaluation_code(code)
3814 self.value.make_owned_reference(code)
3817 Naming.retval_cname,
3818 self.value.result_as(self.return_type)))
3819 self.value.generate_post_assignment_code(code)
3820 self.value.free_temps(code)
3822 if self.return_type.is_pyobject:
3823 code.put_init_to_py_none(Naming.retval_cname, self.return_type)
3824 elif self.return_type.is_returncode:
3827 Naming.retval_cname,
3828 self.return_type.default_value))
3829 for cname, type in code.funcstate.temps_holding_reference():
3830 code.put_decref_clear(cname, type)
3831 code.put_goto(code.return_label)
3833 def generate_function_definitions(self, env, code):
3834 if self.value is not None:
3835 self.value.generate_function_definitions(env, code)
3837 def annotate(self, code):
3839 self.value.annotate(code)
3842 class RaiseStatNode(StatNode):
3845 # exc_type ExprNode or None
3846 # exc_value ExprNode or None
3847 # exc_tb ExprNode or None
3849 child_attrs = ["exc_type", "exc_value", "exc_tb"]
3851 def analyse_expressions(self, env):
3853 self.exc_type.analyse_types(env)
3854 self.exc_type = self.exc_type.coerce_to_pyobject(env)
3856 self.exc_value.analyse_types(env)
3857 self.exc_value = self.exc_value.coerce_to_pyobject(env)
3859 self.exc_tb.analyse_types(env)
3860 self.exc_tb = self.exc_tb.coerce_to_pyobject(env)
3861 env.use_utility_code(raise_utility_code)
3863 nogil_check = Node.gil_error
3864 gil_message = "Raising exception"
3866 def generate_execution_code(self, code):
3868 self.exc_type.generate_evaluation_code(code)
3869 type_code = self.exc_type.py_result()
3873 self.exc_value.generate_evaluation_code(code)
3874 value_code = self.exc_value.py_result()
3878 self.exc_tb.generate_evaluation_code(code)
3879 tb_code = self.exc_tb.py_result()
3883 "__Pyx_Raise(%s, %s, %s);" % (
3887 for obj in (self.exc_type, self.exc_value, self.exc_tb):
3889 obj.generate_disposal_code(code)
3890 obj.free_temps(code)
3892 code.error_goto(self.pos))
3894 def generate_function_definitions(self, env, code):
3895 if self.exc_type is not None:
3896 self.exc_type.generate_function_definitions(env, code)
3897 if self.exc_value is not None:
3898 self.exc_value.generate_function_definitions(env, code)
3899 if self.exc_tb is not None:
3900 self.exc_tb.generate_function_definitions(env, code)
3902 def annotate(self, code):
3904 self.exc_type.annotate(code)
3906 self.exc_value.annotate(code)
3908 self.exc_tb.annotate(code)
3911 class ReraiseStatNode(StatNode):
3915 def analyse_expressions(self, env):
3916 env.use_utility_code(restore_exception_utility_code)
3918 nogil_check = Node.gil_error
3919 gil_message = "Raising exception"
3921 def generate_execution_code(self, code):
3922 vars = code.funcstate.exc_vars
3924 for varname in vars:
3925 code.put_giveref(varname)
3926 code.putln("__Pyx_ErrRestore(%s, %s, %s);" % tuple(vars))
3927 for varname in vars:
3928 code.put("%s = 0; " % varname)
3930 code.putln(code.error_goto(self.pos))
3932 error(self.pos, "Reraise not inside except clause")
3935 class AssertStatNode(StatNode):
3939 # value ExprNode or None
3941 child_attrs = ["cond", "value"]
3943 def analyse_expressions(self, env):
3944 self.cond = self.cond.analyse_boolean_expression(env)
3946 self.value.analyse_types(env)
3947 self.value = self.value.coerce_to_pyobject(env)
3949 nogil_check = Node.gil_error
3950 gil_message = "Raising exception"
3952 def generate_execution_code(self, code):
3953 code.putln("#ifndef PYREX_WITHOUT_ASSERTIONS")
3954 self.cond.generate_evaluation_code(code)
3956 "if (unlikely(!%s)) {" %
3959 self.value.generate_evaluation_code(code)
3961 "PyErr_SetObject(PyExc_AssertionError, %s);" %
3962 self.value.py_result())
3963 self.value.generate_disposal_code(code)
3964 self.value.free_temps(code)
3967 "PyErr_SetNone(PyExc_AssertionError);")
3969 code.error_goto(self.pos))
3972 self.cond.generate_disposal_code(code)
3973 self.cond.free_temps(code)
3974 code.putln("#endif")
3976 def generate_function_definitions(self, env, code):
3977 self.cond.generate_function_definitions(env, code)
3978 if self.value is not None:
3979 self.value.generate_function_definitions(env, code)
3981 def annotate(self, code):
3982 self.cond.annotate(code)
3984 self.value.annotate(code)
3987 class IfStatNode(StatNode):
3990 # if_clauses [IfClauseNode]
3991 # else_clause StatNode or None
3993 child_attrs = ["if_clauses", "else_clause"]
3995 def analyse_control_flow(self, env):
3996 env.start_branching(self.pos)
3997 for if_clause in self.if_clauses:
3998 if_clause.analyse_control_flow(env)
3999 env.next_branch(if_clause.end_pos())
4000 if self.else_clause:
4001 self.else_clause.analyse_control_flow(env)
4002 env.finish_branching(self.end_pos())
4004 def analyse_declarations(self, env):
4005 for if_clause in self.if_clauses:
4006 if_clause.analyse_declarations(env)
4007 if self.else_clause:
4008 self.else_clause.analyse_declarations(env)
4010 def analyse_expressions(self, env):
4011 for if_clause in self.if_clauses:
4012 if_clause.analyse_expressions(env)
4013 if self.else_clause:
4014 self.else_clause.analyse_expressions(env)
4016 def generate_execution_code(self, code):
4017 code.mark_pos(self.pos)
4018 end_label = code.new_label()
4019 for if_clause in self.if_clauses:
4020 if_clause.generate_execution_code(code, end_label)
4021 if self.else_clause:
4022 code.putln("/*else*/ {")
4023 self.else_clause.generate_execution_code(code)
4025 code.put_label(end_label)
4027 def generate_function_definitions(self, env, code):
4028 for clause in self.if_clauses:
4029 clause.generate_function_definitions(env, code)
4030 if self.else_clause is not None:
4031 self.else_clause.generate_function_definitions(env, code)
4033 def annotate(self, code):
4034 for if_clause in self.if_clauses:
4035 if_clause.annotate(code)
4036 if self.else_clause:
4037 self.else_clause.annotate(code)
4040 class IfClauseNode(Node):
4041 # if or elif clause in an if statement
4043 # condition ExprNode
4046 child_attrs = ["condition", "body"]
4048 def analyse_control_flow(self, env):
4049 self.body.analyse_control_flow(env)
4051 def analyse_declarations(self, env):
4052 self.condition.analyse_declarations(env)
4053 self.body.analyse_declarations(env)
4055 def analyse_expressions(self, env):
4057 self.condition.analyse_temp_boolean_expression(env)
4058 self.body.analyse_expressions(env)
4060 def get_constant_condition_result(self):
4061 if self.condition.has_constant_result():
4062 return bool(self.condition.constant_result)
4066 def generate_execution_code(self, code, end_label):
4067 self.condition.generate_evaluation_code(code)
4070 self.condition.result())
4071 self.condition.generate_disposal_code(code)
4072 self.condition.free_temps(code)
4073 self.body.generate_execution_code(code)
4074 code.put_goto(end_label)
4077 def generate_function_definitions(self, env, code):
4078 self.condition.generate_function_definitions(env, code)
4079 self.body.generate_function_definitions(env, code)
4081 def annotate(self, code):
4082 self.condition.annotate(code)
4083 self.body.annotate(code)
4086 class SwitchCaseNode(StatNode):
4087 # Generated in the optimization of an if-elif-else node
4089 # conditions [ExprNode]
4092 child_attrs = ['conditions', 'body']
4094 def generate_execution_code(self, code):
4095 for cond in self.conditions:
4096 code.mark_pos(cond.pos)
4097 cond.generate_evaluation_code(code)
4098 code.putln("case %s:" % cond.result())
4099 self.body.generate_execution_code(code)
4100 code.putln("break;")
4102 def generate_function_definitions(self, env, code):
4103 for cond in self.conditions:
4104 cond.generate_function_definitions(env, code)
4105 self.body.generate_function_definitions(env, code)
4107 def annotate(self, code):
4108 for cond in self.conditions:
4110 self.body.annotate(code)
4112 class SwitchStatNode(StatNode):
4113 # Generated in the optimization of an if-elif-else node
4116 # cases [SwitchCaseNode]
4117 # else_clause StatNode or None
4119 child_attrs = ['test', 'cases', 'else_clause']
4121 def generate_execution_code(self, code):
4122 code.putln("switch (%s) {" % self.test.result())
4123 for case in self.cases:
4124 case.generate_execution_code(code)
4125 if self.else_clause is not None:
4126 code.putln("default:")
4127 self.else_clause.generate_execution_code(code)
4128 code.putln("break;")
4131 def generate_function_definitions(self, env, code):
4132 self.test.generate_function_definitions(env, code)
4133 for case in self.cases:
4134 case.generate_function_definitions(env, code)
4135 if self.else_clause is not None:
4136 self.else_clause.generate_function_definitions(env, code)
4138 def annotate(self, code):
4139 self.test.annotate(code)
4140 for case in self.cases:
4142 if self.else_clause is not None:
4143 self.else_clause.annotate(code)
4145 class LoopNode(object):
4147 def analyse_control_flow(self, env):
4148 env.start_branching(self.pos)
4149 self.body.analyse_control_flow(env)
4150 env.next_branch(self.body.end_pos())
4151 if self.else_clause:
4152 self.else_clause.analyse_control_flow(env)
4153 env.finish_branching(self.end_pos())
4156 class WhileStatNode(LoopNode, StatNode):
4159 # condition ExprNode
4161 # else_clause StatNode
4163 child_attrs = ["condition", "body", "else_clause"]
4165 def analyse_declarations(self, env):
4166 self.body.analyse_declarations(env)
4167 if self.else_clause:
4168 self.else_clause.analyse_declarations(env)
4170 def analyse_expressions(self, env):
4172 self.condition.analyse_temp_boolean_expression(env)
4173 self.body.analyse_expressions(env)
4174 if self.else_clause:
4175 self.else_clause.analyse_expressions(env)
4177 def generate_execution_code(self, code):
4178 old_loop_labels = code.new_loop_labels()
4181 self.condition.generate_evaluation_code(code)
4182 self.condition.generate_disposal_code(code)
4185 self.condition.result())
4186 self.condition.free_temps(code)
4187 self.body.generate_execution_code(code)
4188 code.put_label(code.continue_label)
4190 break_label = code.break_label
4191 code.set_loop_labels(old_loop_labels)
4192 if self.else_clause:
4193 code.putln("/*else*/ {")
4194 self.else_clause.generate_execution_code(code)
4196 code.put_label(break_label)
4198 def generate_function_definitions(self, env, code):
4199 self.condition.generate_function_definitions(env, code)
4200 self.body.generate_function_definitions(env, code)
4201 if self.else_clause is not None:
4202 self.else_clause.generate_function_definitions(env, code)
4204 def annotate(self, code):
4205 self.condition.annotate(code)
4206 self.body.annotate(code)
4207 if self.else_clause:
4208 self.else_clause.annotate(code)
4211 def ForStatNode(pos, **kw):
4212 if 'iterator' in kw:
4213 return ForInStatNode(pos, **kw)
4215 return ForFromStatNode(pos, **kw)
4217 class ForInStatNode(LoopNode, StatNode):
4221 # iterator IteratorNode
4223 # else_clause StatNode
4224 # item NextNode used internally
4226 child_attrs = ["target", "iterator", "body", "else_clause"]
4229 def analyse_declarations(self, env):
4230 self.target.analyse_target_declaration(env)
4231 self.body.analyse_declarations(env)
4232 if self.else_clause:
4233 self.else_clause.analyse_declarations(env)
4235 def analyse_expressions(self, env):
4237 self.target.analyse_target_types(env)
4238 self.iterator.analyse_expressions(env)
4239 self.item = ExprNodes.NextNode(self.iterator, env)
4240 self.item = self.item.coerce_to(self.target.type, env)
4241 self.body.analyse_expressions(env)
4242 if self.else_clause:
4243 self.else_clause.analyse_expressions(env)
4245 def generate_execution_code(self, code):
4246 old_loop_labels = code.new_loop_labels()
4247 self.iterator.allocate_counter_temp(code)
4248 self.iterator.generate_evaluation_code(code)
4251 self.item.generate_evaluation_code(code)
4252 self.target.generate_assignment_code(self.item, code)
4253 self.body.generate_execution_code(code)
4254 code.put_label(code.continue_label)
4257 break_label = code.break_label
4258 code.set_loop_labels(old_loop_labels)
4260 if self.else_clause:
4261 # in nested loops, the 'else' block can contain a
4262 # 'continue' statement for the outer loop, but we may need
4263 # to generate cleanup code before taking that path, so we
4265 orig_continue_label = code.continue_label
4266 code.continue_label = code.new_label('outer_continue')
4268 code.putln("/*else*/ {")
4269 self.else_clause.generate_execution_code(code)
4272 if code.label_used(code.continue_label):
4273 code.put_goto(break_label)
4274 code.put_label(code.continue_label)
4275 self.iterator.generate_disposal_code(code)
4276 code.put_goto(orig_continue_label)
4277 code.set_loop_labels(old_loop_labels)
4279 if code.label_used(break_label):
4280 code.put_label(break_label)
4281 self.iterator.release_counter_temp(code)
4282 self.iterator.generate_disposal_code(code)
4283 self.iterator.free_temps(code)
4285 def generate_function_definitions(self, env, code):
4286 self.target.generate_function_definitions(env, code)
4287 self.iterator.generate_function_definitions(env, code)
4288 self.body.generate_function_definitions(env, code)
4289 if self.else_clause is not None:
4290 self.else_clause.generate_function_definitions(env, code)
4292 def annotate(self, code):
4293 self.target.annotate(code)
4294 self.iterator.annotate(code)
4295 self.body.annotate(code)
4296 if self.else_clause:
4297 self.else_clause.annotate(code)
4298 self.item.annotate(code)
4301 class ForFromStatNode(LoopNode, StatNode):
4302 # for name from expr rel name rel expr
4309 # step ExprNode or None
4311 # else_clause StatNode or None
4317 # loopvar_node ExprNode (usually a NameNode or temp node)
4318 # py_loopvar_node PyTempNode or None
4319 child_attrs = ["target", "bound1", "bound2", "step", "body", "else_clause"]
4321 is_py_target = False
4323 py_loopvar_node = None
4326 gil_message = "For-loop using object bounds or target"
4328 def nogil_check(self, env):
4329 for x in (self.target, self.bound1, self.bound2):
4330 if x.type.is_pyobject:
4333 def analyse_declarations(self, env):
4334 self.target.analyse_target_declaration(env)
4335 self.body.analyse_declarations(env)
4336 if self.else_clause:
4337 self.else_clause.analyse_declarations(env)
4339 def analyse_expressions(self, env):
4341 self.target.analyse_target_types(env)
4342 self.bound1.analyse_types(env)
4343 self.bound2.analyse_types(env)
4344 if self.step is not None:
4345 if isinstance(self.step, ExprNodes.UnaryMinusNode):
4346 warning(self.step.pos, "Probable infinite loop in for-from-by statment. Consider switching the directions of the relations.", 2)
4347 self.step.analyse_types(env)
4349 target_type = self.target.type
4350 if self.target.type.is_numeric:
4351 loop_type = self.target.type
4353 loop_type = PyrexTypes.c_int_type
4354 if not self.bound1.type.is_pyobject:
4355 loop_type = PyrexTypes.widest_numeric_type(loop_type, self.bound1.type)
4356 if not self.bound2.type.is_pyobject:
4357 loop_type = PyrexTypes.widest_numeric_type(loop_type, self.bound2.type)
4358 if self.step is not None and not self.step.type.is_pyobject:
4359 loop_type = PyrexTypes.widest_numeric_type(loop_type, self.step.type)
4360 self.bound1 = self.bound1.coerce_to(loop_type, env)
4361 self.bound2 = self.bound2.coerce_to(loop_type, env)
4362 if not self.bound2.is_literal:
4363 self.bound2 = self.bound2.coerce_to_temp(env)
4364 if self.step is not None:
4365 self.step = self.step.coerce_to(loop_type, env)
4366 if not self.step.is_literal:
4367 self.step = self.step.coerce_to_temp(env)
4369 target_type = self.target.type
4370 if not (target_type.is_pyobject or target_type.is_numeric):
4371 error(self.target.pos,
4372 "for-from loop variable must be c numeric type or Python object")
4373 if target_type.is_numeric:
4374 self.is_py_target = False
4375 if isinstance(self.target, ExprNodes.IndexNode) and self.target.is_buffer_access:
4376 raise error(self.pos, "Buffer indexing not allowed as for loop target.")
4377 self.loopvar_node = self.target
4378 self.py_loopvar_node = None
4380 self.is_py_target = True
4381 c_loopvar_node = ExprNodes.TempNode(self.pos, loop_type, env)
4382 self.loopvar_node = c_loopvar_node
4383 self.py_loopvar_node = \
4384 ExprNodes.CloneNode(c_loopvar_node).coerce_to_pyobject(env)
4385 self.body.analyse_expressions(env)
4386 if self.else_clause:
4387 self.else_clause.analyse_expressions(env)
4389 def generate_execution_code(self, code):
4390 old_loop_labels = code.new_loop_labels()
4391 from_range = self.from_range
4392 self.bound1.generate_evaluation_code(code)
4393 self.bound2.generate_evaluation_code(code)
4394 offset, incop = self.relation_table[self.relation1]
4395 if self.step is not None:
4396 self.step.generate_evaluation_code(code)
4397 step = self.step.result()
4398 incop = "%s=%s" % (incop[0], step)
4400 if isinstance(self.loopvar_node, ExprNodes.TempNode):
4401 self.loopvar_node.allocate(code)
4402 if isinstance(self.py_loopvar_node, ExprNodes.TempNode):
4403 self.py_loopvar_node.allocate(code)
4405 loopvar_name = code.funcstate.allocate_temp(self.target.type, False)
4407 loopvar_name = self.loopvar_node.result()
4409 "for (%s = %s%s; %s %s %s; %s%s) {" % (
4411 self.bound1.result(), offset,
4412 loopvar_name, self.relation2, self.bound2.result(),
4413 loopvar_name, incop))
4414 if self.py_loopvar_node:
4415 self.py_loopvar_node.generate_evaluation_code(code)
4416 self.target.generate_assignment_code(self.py_loopvar_node, code)
4418 code.putln("%s = %s;" % (
4419 self.target.result(), loopvar_name))
4420 self.body.generate_execution_code(code)
4421 code.put_label(code.continue_label)
4422 if self.py_loopvar_node:
4423 # This mess is to make for..from loops with python targets behave
4424 # exactly like those with C targets with regards to re-assignment
4425 # of the loop variable.
4427 if self.target.entry.is_pyglobal:
4428 # We know target is a NameNode, this is the only ugly case.
4429 target_node = ExprNodes.PyTempNode(self.target.pos, None)
4430 target_node.allocate(code)
4431 interned_cname = code.intern_identifier(self.target.entry.name)
4432 code.globalstate.use_utility_code(ExprNodes.get_name_interned_utility_code)
4433 code.putln("%s = __Pyx_GetName(%s, %s); %s" % (
4434 target_node.result(),
4435 Naming.module_cname,
4437 code.error_goto_if_null(target_node.result(), self.target.pos)))
4438 code.put_gotref(target_node.result())
4440 target_node = self.target
4441 from_py_node = ExprNodes.CoerceFromPyTypeNode(self.loopvar_node.type, target_node, None)
4442 from_py_node.temp_code = loopvar_name
4443 from_py_node.generate_result_code(code)
4444 if self.target.entry.is_pyglobal:
4445 code.put_decref(target_node.result(), target_node.type)
4446 target_node.release(code)
4448 if self.py_loopvar_node:
4449 # This is potentially wasteful, but we don't want the semantics to
4450 # depend on whether or not the loop is a python type.
4451 self.py_loopvar_node.generate_evaluation_code(code)
4452 self.target.generate_assignment_code(self.py_loopvar_node, code)
4454 code.funcstate.release_temp(loopvar_name)
4455 break_label = code.break_label
4456 code.set_loop_labels(old_loop_labels)
4457 if self.else_clause:
4458 code.putln("/*else*/ {")
4459 self.else_clause.generate_execution_code(code)
4461 code.put_label(break_label)
4462 self.bound1.generate_disposal_code(code)
4463 self.bound1.free_temps(code)
4464 self.bound2.generate_disposal_code(code)
4465 self.bound2.free_temps(code)
4466 if isinstance(self.loopvar_node, ExprNodes.TempNode):
4467 self.loopvar_node.release(code)
4468 if isinstance(self.py_loopvar_node, ExprNodes.TempNode):
4469 self.py_loopvar_node.release(code)
4470 if self.step is not None:
4471 self.step.generate_disposal_code(code)
4472 self.step.free_temps(code)
4475 # {relop : (initial offset, increment op)}
4482 def generate_function_definitions(self, env, code):
4483 self.target.generate_function_definitions(env, code)
4484 self.bound1.generate_function_definitions(env, code)
4485 self.bound2.generate_function_definitions(env, code)
4486 if self.step is not None:
4487 self.step.generate_function_definitions(env, code)
4488 self.body.generate_function_definitions(env, code)
4489 if self.else_clause is not None:
4490 self.else_clause.generate_function_definitions(env, code)
4492 def annotate(self, code):
4493 self.target.annotate(code)
4494 self.bound1.annotate(code)
4495 self.bound2.annotate(code)
4497 self.step.annotate(code)
4498 self.body.annotate(code)
4499 if self.else_clause:
4500 self.else_clause.annotate(code)
4503 class WithStatNode(StatNode):
4505 Represents a Python with statement.
4507 This is only used at parse tree level; and is not present in
4508 analysis or generation phases.
4510 # manager The with statement manager object
4511 # target Node (lhs expression)
4513 child_attrs = ["manager", "target", "body"]
4515 class TryExceptStatNode(StatNode):
4516 # try .. except statement
4519 # except_clauses [ExceptClauseNode]
4520 # else_clause StatNode or None
4522 child_attrs = ["body", "except_clauses", "else_clause"]
4524 def analyse_control_flow(self, env):
4525 env.start_branching(self.pos)
4526 self.body.analyse_control_flow(env)
4527 successful_try = env.control_flow # grab this for later
4528 env.next_branch(self.body.end_pos())
4529 env.finish_branching(self.body.end_pos())
4531 env.start_branching(self.except_clauses[0].pos)
4532 for except_clause in self.except_clauses:
4533 except_clause.analyse_control_flow(env)
4534 env.next_branch(except_clause.end_pos())
4536 # the else cause it executed only when the try clause finishes
4537 env.control_flow.incoming = successful_try
4538 if self.else_clause:
4539 self.else_clause.analyse_control_flow(env)
4540 env.finish_branching(self.end_pos())
4542 def analyse_declarations(self, env):
4543 self.body.analyse_declarations(env)
4544 for except_clause in self.except_clauses:
4545 except_clause.analyse_declarations(env)
4546 if self.else_clause:
4547 self.else_clause.analyse_declarations(env)
4548 env.use_utility_code(reset_exception_utility_code)
4550 def analyse_expressions(self, env):
4551 self.body.analyse_expressions(env)
4552 default_clause_seen = 0
4553 for except_clause in self.except_clauses:
4554 except_clause.analyse_expressions(env)
4555 if default_clause_seen:
4556 error(except_clause.pos, "default 'except:' must be last")
4557 if not except_clause.pattern:
4558 default_clause_seen = 1
4559 self.has_default_clause = default_clause_seen
4560 if self.else_clause:
4561 self.else_clause.analyse_expressions(env)
4563 nogil_check = Node.gil_error
4564 gil_message = "Try-except statement"
4566 def generate_execution_code(self, code):
4567 old_return_label = code.return_label
4568 old_break_label = code.break_label
4569 old_continue_label = code.continue_label
4570 old_error_label = code.new_error_label()
4571 our_error_label = code.error_label
4572 except_end_label = code.new_label('exception_handled')
4573 except_error_label = code.new_label('except_error')
4574 except_return_label = code.new_label('except_return')
4575 try_return_label = code.new_label('try_return')
4576 try_break_label = code.new_label('try_break')
4577 try_continue_label = code.new_label('try_continue')
4578 try_end_label = code.new_label('try_end')
4581 code.putln("PyObject %s;" %
4582 ', '.join(['*%s' % var for var in Naming.exc_save_vars]))
4583 code.putln("__Pyx_ExceptionSave(%s);" %
4584 ', '.join(['&%s' % var for var in Naming.exc_save_vars]))
4585 for var in Naming.exc_save_vars:
4586 code.put_xgotref(var)
4589 code.return_label = try_return_label
4590 code.break_label = try_break_label
4591 code.continue_label = try_continue_label
4592 self.body.generate_execution_code(code)
4595 temps_to_clean_up = code.funcstate.all_free_managed_temps()
4596 code.error_label = except_error_label
4597 code.return_label = except_return_label
4598 if self.else_clause:
4601 self.else_clause.generate_execution_code(code)
4604 for var in Naming.exc_save_vars:
4605 code.put_xdecref_clear(var, py_object_type)
4606 code.put_goto(try_end_label)
4607 if code.label_used(try_return_label):
4608 code.put_label(try_return_label)
4609 for var in Naming.exc_save_vars: code.put_xgiveref(var)
4610 code.putln("__Pyx_ExceptionReset(%s);" %
4611 ', '.join(Naming.exc_save_vars))
4612 code.put_goto(old_return_label)
4613 code.put_label(our_error_label)
4614 for temp_name, type in temps_to_clean_up:
4615 code.put_xdecref_clear(temp_name, type)
4616 for except_clause in self.except_clauses:
4617 except_clause.generate_handling_code(code, except_end_label)
4619 error_label_used = code.label_used(except_error_label)
4620 if error_label_used or not self.has_default_clause:
4621 if error_label_used:
4622 code.put_label(except_error_label)
4623 for var in Naming.exc_save_vars: code.put_xgiveref(var)
4624 code.putln("__Pyx_ExceptionReset(%s);" %
4625 ', '.join(Naming.exc_save_vars))
4626 code.put_goto(old_error_label)
4628 for exit_label, old_label in zip(
4629 [try_break_label, try_continue_label, except_return_label],
4630 [old_break_label, old_continue_label, old_return_label]):
4632 if code.label_used(exit_label):
4633 code.put_label(exit_label)
4634 for var in Naming.exc_save_vars: code.put_xgiveref(var)
4635 code.putln("__Pyx_ExceptionReset(%s);" %
4636 ', '.join(Naming.exc_save_vars))
4637 code.put_goto(old_label)
4639 if code.label_used(except_end_label):
4640 code.put_label(except_end_label)
4641 for var in Naming.exc_save_vars: code.put_xgiveref(var)
4642 code.putln("__Pyx_ExceptionReset(%s);" %
4643 ', '.join(Naming.exc_save_vars))
4644 code.put_label(try_end_label)
4647 code.return_label = old_return_label
4648 code.break_label = old_break_label
4649 code.continue_label = old_continue_label
4650 code.error_label = old_error_label
4652 def generate_function_definitions(self, env, code):
4653 self.body.generate_function_definitions(env, code)
4654 for except_clause in self.except_clauses:
4655 except_clause.generate_function_definitions(env, code)
4656 if self.else_clause is not None:
4657 self.else_clause.generate_function_definitions(env, code)
4659 def annotate(self, code):
4660 self.body.annotate(code)
4661 for except_node in self.except_clauses:
4662 except_node.annotate(code)
4663 if self.else_clause:
4664 self.else_clause.annotate(code)
4667 class ExceptClauseNode(Node):
4668 # Part of try ... except statement.
4670 # pattern [ExprNode]
4671 # target ExprNode or None
4673 # excinfo_target NameNode or None optional target for exception info
4674 # match_flag string result of exception match
4675 # exc_value ExcValueNode used internally
4676 # function_name string qualified name of enclosing function
4677 # exc_vars (string * 3) local exception variables
4679 # excinfo_target is never set by the parser, but can be set by a transform
4680 # in order to extract more extensive information about the exception as a
4681 # sys.exc_info()-style tuple into a target variable
4683 child_attrs = ["pattern", "target", "body", "exc_value", "excinfo_target"]
4686 excinfo_target = None
4688 def analyse_declarations(self, env):
4690 self.target.analyse_target_declaration(env)
4691 if self.excinfo_target is not None:
4692 self.excinfo_target.analyse_target_declaration(env)
4693 self.body.analyse_declarations(env)
4695 def analyse_expressions(self, env):
4697 genv = env.global_scope()
4698 self.function_name = env.qualified_name
4700 # normalise/unpack self.pattern into a list
4701 for i, pattern in enumerate(self.pattern):
4702 pattern.analyse_expressions(env)
4703 self.pattern[i] = pattern.coerce_to_pyobject(env)
4706 self.exc_value = ExprNodes.ExcValueNode(self.pos, env)
4707 self.target.analyse_target_expression(env, self.exc_value)
4708 if self.excinfo_target is not None:
4710 self.excinfo_tuple = ExprNodes.TupleNode(pos=self.pos, args=[
4711 ExprNodes.ExcValueNode(pos=self.pos, env=env) for x in range(3)])
4712 self.excinfo_tuple.analyse_expressions(env)
4713 self.excinfo_target.analyse_target_expression(env, self.excinfo_tuple)
4715 self.body.analyse_expressions(env)
4717 def generate_handling_code(self, code, end_label):
4718 code.mark_pos(self.pos)
4721 for pattern in self.pattern:
4722 pattern.generate_evaluation_code(code)
4723 exc_tests.append("PyErr_ExceptionMatches(%s)" % pattern.py_result())
4725 match_flag = code.funcstate.allocate_temp(PyrexTypes.c_int_type, False)
4727 "%s = %s;" % (match_flag, ' || '.join(exc_tests)))
4728 for pattern in self.pattern:
4729 pattern.generate_disposal_code(code)
4730 pattern.free_temps(code)
4734 code.funcstate.release_temp(match_flag)
4736 code.putln("/*except:*/ {")
4738 if not getattr(self.body, 'stats', True) and \
4739 self.excinfo_target is None and self.target is None:
4740 # most simple case: no exception variable, empty body (pass)
4741 # => reset the exception state, done
4742 code.putln("PyErr_Restore(0,0,0);")
4743 code.put_goto(end_label)
4747 exc_vars = [code.funcstate.allocate_temp(py_object_type,
4750 code.putln('__Pyx_AddTraceback("%s");' % self.function_name)
4751 # We always have to fetch the exception value even if
4752 # there is no target, because this also normalises the
4753 # exception and stores it in the thread state.
4754 code.globalstate.use_utility_code(get_exception_utility_code)
4755 exc_args = "&%s, &%s, &%s" % tuple(exc_vars)
4756 code.putln("if (__Pyx_GetException(%s) < 0) %s" % (exc_args,
4757 code.error_goto(self.pos)))
4761 self.exc_value.set_var(exc_vars[1])
4762 self.exc_value.generate_evaluation_code(code)
4763 self.target.generate_assignment_code(self.exc_value, code)
4764 if self.excinfo_target is not None:
4765 for tempvar, node in zip(exc_vars, self.excinfo_tuple.args):
4766 node.set_var(tempvar)
4767 self.excinfo_tuple.generate_evaluation_code(code)
4768 self.excinfo_target.generate_assignment_code(self.excinfo_tuple, code)
4770 old_break_label, old_continue_label = code.break_label, code.continue_label
4771 code.break_label = code.new_label('except_break')
4772 code.continue_label = code.new_label('except_continue')
4774 old_exc_vars = code.funcstate.exc_vars
4775 code.funcstate.exc_vars = exc_vars
4776 self.body.generate_execution_code(code)
4777 code.funcstate.exc_vars = old_exc_vars
4778 for var in exc_vars:
4779 code.putln("__Pyx_DECREF(%s); %s = 0;" % (var, var))
4780 code.put_goto(end_label)
4782 if code.label_used(code.break_label):
4783 code.put_label(code.break_label)
4784 for var in exc_vars:
4785 code.putln("__Pyx_DECREF(%s); %s = 0;" % (var, var))
4786 code.put_goto(old_break_label)
4787 code.break_label = old_break_label
4789 if code.label_used(code.continue_label):
4790 code.put_label(code.continue_label)
4791 for var in exc_vars:
4792 code.putln("__Pyx_DECREF(%s); %s = 0;" % (var, var))
4793 code.put_goto(old_continue_label)
4794 code.continue_label = old_continue_label
4796 for temp in exc_vars:
4797 code.funcstate.release_temp(temp)
4802 def generate_function_definitions(self, env, code):
4803 if self.target is not None:
4804 self.target.generate_function_definitions(env, code)
4805 self.body.generate_function_definitions(env, code)
4807 def annotate(self, code):
4809 for pattern in self.pattern:
4810 pattern.annotate(code)
4812 self.target.annotate(code)
4813 self.body.annotate(code)
4816 class TryFinallyStatNode(StatNode):
4817 # try ... finally statement
4820 # finally_clause StatNode
4822 # The plan is that we funnel all continue, break
4823 # return and error gotos into the beginning of the
4824 # finally block, setting a variable to remember which
4825 # one we're doing. At the end of the finally block, we
4826 # switch on the variable to figure out where to go.
4827 # In addition, if we're doing an error, we save the
4828 # exception on entry to the finally block and restore
4831 child_attrs = ["body", "finally_clause"]
4833 preserve_exception = 1
4835 disallow_continue_in_try_finally = 0
4836 # There doesn't seem to be any point in disallowing
4837 # continue in the try block, since we have no problem
4840 def create_analysed(pos, env, body, finally_clause):
4841 node = TryFinallyStatNode(pos, body=body, finally_clause=finally_clause)
4843 create_analysed = staticmethod(create_analysed)
4845 def analyse_control_flow(self, env):
4846 env.start_branching(self.pos)
4847 self.body.analyse_control_flow(env)
4848 env.next_branch(self.body.end_pos())
4849 env.finish_branching(self.body.end_pos())
4850 self.finally_clause.analyse_control_flow(env)
4852 def analyse_declarations(self, env):
4853 self.body.analyse_declarations(env)
4854 self.finally_clause.analyse_declarations(env)
4856 def analyse_expressions(self, env):
4857 self.body.analyse_expressions(env)
4858 self.finally_clause.analyse_expressions(env)
4860 nogil_check = Node.gil_error
4861 gil_message = "Try-finally statement"
4863 def generate_execution_code(self, code):
4864 old_error_label = code.error_label
4865 old_labels = code.all_new_labels()
4866 new_labels = code.get_all_labels()
4867 new_error_label = code.error_label
4868 catch_label = code.new_label()
4871 if self.disallow_continue_in_try_finally:
4872 was_in_try_finally = code.funcstate.in_try_finally
4873 code.funcstate.in_try_finally = 1
4874 self.body.generate_execution_code(code)
4875 if self.disallow_continue_in_try_finally:
4876 code.funcstate.in_try_finally = was_in_try_finally
4879 temps_to_clean_up = code.funcstate.all_free_managed_temps()
4880 code.mark_pos(self.finally_clause.pos)
4884 error_label_used = 0
4885 for i, new_label in enumerate(new_labels):
4886 if new_label in code.labels_used:
4887 cases_used.append(i)
4888 if new_label == new_error_label:
4889 error_label_used = 1
4890 error_label_case = i
4894 if error_label_used and self.preserve_exception:
4896 "PyObject *%s, *%s, *%s;" % Naming.exc_vars)
4898 "int %s;" % Naming.exc_lineno_name)
4899 exc_var_init_zero = ''.join(["%s = 0; " % var for var in Naming.exc_vars])
4900 exc_var_init_zero += '%s = 0;' % Naming.exc_lineno_name
4901 code.putln(exc_var_init_zero)
4903 exc_var_init_zero = None
4904 code.use_label(catch_label)
4906 "__pyx_why = 0; goto %s;" % catch_label)
4907 for i in cases_used:
4908 new_label = new_labels[i]
4909 #if new_label and new_label != "<try>":
4910 if new_label == new_error_label and self.preserve_exception:
4911 self.put_error_catcher(code,
4912 new_error_label, i+1, catch_label, temps_to_clean_up)
4914 code.put('%s: ' % new_label)
4915 if exc_var_init_zero:
4916 code.putln(exc_var_init_zero)
4917 code.putln("__pyx_why = %s; goto %s;" % (
4920 code.put_label(catch_label)
4921 code.set_all_labels(old_labels)
4922 if error_label_used:
4923 code.new_error_label()
4924 finally_error_label = code.error_label
4925 self.finally_clause.generate_execution_code(code)
4926 if error_label_used:
4927 if finally_error_label in code.labels_used and self.preserve_exception:
4928 over_label = code.new_label()
4929 code.put_goto(over_label);
4930 code.put_label(finally_error_label)
4931 code.putln("if (__pyx_why == %d) {" % (error_label_case + 1))
4932 for var in Naming.exc_vars:
4933 code.putln("Py_XDECREF(%s);" % var)
4935 code.put_goto(old_error_label)
4936 code.put_label(over_label)
4937 code.error_label = old_error_label
4940 "switch (__pyx_why) {")
4941 for i in cases_used:
4942 old_label = old_labels[i]
4943 if old_label == old_error_label and self.preserve_exception:
4944 self.put_error_uncatcher(code, i+1, old_error_label)
4946 code.use_label(old_label)
4948 "case %s: goto %s;" % (
4956 def generate_function_definitions(self, env, code):
4957 self.body.generate_function_definitions(env, code)
4958 self.finally_clause.generate_function_definitions(env, code)
4960 def put_error_catcher(self, code, error_label, i, catch_label, temps_to_clean_up):
4961 code.globalstate.use_utility_code(restore_exception_utility_code)
4968 for temp_name, type in temps_to_clean_up:
4969 code.put_xdecref_clear(temp_name, type)
4971 "__Pyx_ErrFetch(&%s, &%s, &%s);" %
4975 Naming.exc_lineno_name, Naming.lineno_cname))
4976 code.put_goto(catch_label)
4979 def put_error_uncatcher(self, code, i, error_label):
4980 code.globalstate.use_utility_code(restore_exception_utility_code)
4985 "__Pyx_ErrRestore(%s, %s, %s);" %
4989 Naming.lineno_cname, Naming.exc_lineno_name))
4990 for var in Naming.exc_vars:
4994 code.put_goto(error_label)
4998 def annotate(self, code):
4999 self.body.annotate(code)
5000 self.finally_clause.annotate(code)
5003 class GILStatNode(TryFinallyStatNode):
5004 # 'with gil' or 'with nogil' statement
5006 # state string 'gil' or 'nogil'
5010 preserve_exception = 0
5012 def __init__(self, pos, state, body):
5014 TryFinallyStatNode.__init__(self, pos,
5016 finally_clause = GILExitNode(pos, state = state))
5018 def analyse_expressions(self, env):
5019 env.use_utility_code(force_init_threads_utility_code)
5020 was_nogil = env.nogil
5022 TryFinallyStatNode.analyse_expressions(self, env)
5023 env.nogil = was_nogil
5027 def generate_execution_code(self, code):
5028 code.mark_pos(self.pos)
5030 if self.state == 'gil':
5031 code.putln("#ifdef WITH_THREAD")
5032 code.putln("PyGILState_STATE _save = PyGILState_Ensure();")
5033 code.putln("#endif")
5035 code.putln("#ifdef WITH_THREAD")
5036 code.putln("PyThreadState *_save;")
5037 code.putln("#endif")
5038 code.putln("Py_UNBLOCK_THREADS")
5039 TryFinallyStatNode.generate_execution_code(self, code)
5043 class GILExitNode(StatNode):
5044 # Used as the 'finally' block in a GILStatNode
5046 # state string 'gil' or 'nogil'
5050 def analyse_expressions(self, env):
5053 def generate_execution_code(self, code):
5054 if self.state == 'gil':
5055 code.putln("#ifdef WITH_THREAD")
5056 code.putln("PyGILState_Release(_save);")
5057 code.putln("#endif")
5059 code.putln("Py_BLOCK_THREADS")
5062 class CImportStatNode(StatNode):
5065 # module_name string Qualified name of module being imported
5066 # as_name string or None Name specified in "as" clause, if any
5070 def analyse_declarations(self, env):
5071 if not env.is_module_scope:
5072 error(self.pos, "cimport only allowed at module level")
5074 module_scope = env.find_module(self.module_name, self.pos)
5075 if "." in self.module_name:
5076 names = [EncodedString(name) for name in self.module_name.split(".")]
5078 top_module_scope = env.context.find_submodule(top_name)
5079 module_scope = top_module_scope
5080 for name in names[1:]:
5081 submodule_scope = module_scope.find_submodule(name)
5082 module_scope.declare_module(name, submodule_scope, self.pos)
5083 module_scope = submodule_scope
5085 env.declare_module(self.as_name, module_scope, self.pos)
5087 env.declare_module(top_name, top_module_scope, self.pos)
5089 name = self.as_name or self.module_name
5090 env.declare_module(name, module_scope, self.pos)
5092 def analyse_expressions(self, env):
5095 def generate_execution_code(self, code):
5099 class FromCImportStatNode(StatNode):
5100 # from ... cimport statement
5102 # module_name string Qualified name of module
5103 # imported_names [(pos, name, as_name, kind)] Names to be imported
5107 def analyse_declarations(self, env):
5108 if not env.is_module_scope:
5109 error(self.pos, "cimport only allowed at module level")
5111 module_scope = env.find_module(self.module_name, self.pos)
5112 env.add_imported_module(module_scope)
5113 for pos, name, as_name, kind in self.imported_names:
5115 for local_name, entry in module_scope.entries.items():
5116 env.add_imported_entry(local_name, entry, pos)
5118 entry = module_scope.lookup(name)
5120 if kind and not self.declaration_matches(entry, kind):
5121 entry.redeclared(pos)
5123 if kind == 'struct' or kind == 'union':
5124 entry = module_scope.declare_struct_or_union(name,
5125 kind = kind, scope = None, typedef_flag = 0, pos = pos)
5126 elif kind == 'class':
5127 entry = module_scope.declare_c_class(name, pos = pos,
5128 module_name = self.module_name)
5130 submodule_scope = env.context.find_module(name, relative_to = module_scope, pos = self.pos)
5131 if submodule_scope.parent_module is module_scope:
5132 env.declare_module(as_name or name, submodule_scope, self.pos)
5134 error(pos, "Name '%s' not declared in module '%s'"
5135 % (name, self.module_name))
5138 local_name = as_name or name
5139 env.add_imported_entry(local_name, entry, pos)
5141 def declaration_matches(self, entry, kind):
5142 if not entry.is_type:
5146 if not type.is_extension_type:
5149 if not type.is_struct_or_union:
5151 if kind != type.kind:
5155 def analyse_expressions(self, env):
5158 def generate_execution_code(self, code):
5162 class FromImportStatNode(StatNode):
5163 # from ... import statement
5166 # items [(string, NameNode)]
5167 # interned_items [(string, NameNode, ExprNode)]
5168 # item PyTempNode used internally
5169 # import_star boolean used internally
5171 child_attrs = ["module"]
5174 def analyse_declarations(self, env):
5175 for name, target in self.items:
5177 if not env.is_module_scope:
5178 error(self.pos, "import * only allowed at module level")
5180 env.has_import_star = 1
5181 self.import_star = 1
5183 target.analyse_target_declaration(env)
5185 def analyse_expressions(self, env):
5187 self.module.analyse_expressions(env)
5188 self.item = ExprNodes.RawCNameExprNode(self.pos, py_object_type)
5189 self.interned_items = []
5190 for name, target in self.items:
5192 for _, entry in env.entries.items():
5193 if not entry.is_type and entry.type.is_extension_type:
5194 env.use_utility_code(ExprNodes.type_test_utility_code)
5197 entry = env.lookup(target.name)
5198 # check whether or not entry is already cimported
5199 if (entry.is_type and entry.type.name == name
5200 and hasattr(entry.type, 'module_name')):
5201 if entry.type.module_name == self.module.module_name.value:
5202 # cimported with absolute name
5205 # cimported with relative name
5206 module = env.find_module(self.module.module_name.value,
5208 if entry.type.module_name == module.qualified_name:
5210 except AttributeError:
5212 target.analyse_target_expression(env, None)
5213 if target.type is py_object_type:
5216 coerced_item = self.item.coerce_to(target.type, env)
5217 self.interned_items.append((name, target, coerced_item))
5219 def generate_execution_code(self, code):
5220 self.module.generate_evaluation_code(code)
5221 if self.import_star:
5223 'if (%s(%s) < 0) %s;' % (
5225 self.module.py_result(),
5226 code.error_goto(self.pos)))
5227 item_temp = code.funcstate.allocate_temp(py_object_type, manage_ref=True)
5228 self.item.set_cname(item_temp)
5229 for name, target, coerced_item in self.interned_items:
5230 cname = code.intern_identifier(name)
5232 '%s = PyObject_GetAttr(%s, %s); %s' % (
5234 self.module.py_result(),
5236 code.error_goto_if_null(item_temp, self.pos)))
5237 code.put_gotref(item_temp)
5238 if coerced_item is None:
5239 target.generate_assignment_code(self.item, code)
5241 coerced_item.allocate_temp_result(code)
5242 coerced_item.generate_result_code(code)
5243 target.generate_assignment_code(coerced_item, code)
5244 code.put_decref_clear(item_temp, py_object_type)
5245 code.funcstate.release_temp(item_temp)
5246 self.module.generate_disposal_code(code)
5247 self.module.free_temps(code)
5251 #------------------------------------------------------------------------------------
5253 # Runtime support code
5255 #------------------------------------------------------------------------------------
5257 utility_function_predeclarations = \
5259 /* inline attribute */
5260 #ifndef CYTHON_INLINE
5261 #if defined(__GNUC__)
5262 #define CYTHON_INLINE __inline__
5263 #elif defined(_MSC_VER)
5264 #define CYTHON_INLINE __inline
5265 #elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
5266 #define CYTHON_INLINE inline
5268 #define CYTHON_INLINE
5272 /* unused attribute */
5273 #ifndef CYTHON_UNUSED
5274 # if defined(__GNUC__)
5275 # if !(defined(__cplusplus)) || (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4))
5276 # define CYTHON_UNUSED __attribute__ ((__unused__))
5278 # define CYTHON_UNUSED
5280 # elif defined(__ICC) || defined(__INTEL_COMPILER)
5281 # define CYTHON_UNUSED __attribute__ ((__unused__))
5283 # define CYTHON_UNUSED
5287 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*/
5291 if Options.gcc_branch_hints:
5292 branch_prediction_macros = \
5295 /* Test for GCC > 2.95 */
5296 #if __GNUC__ > 2 || (__GNUC__ == 2 && (__GNUC_MINOR__ > 95))
5297 #define likely(x) __builtin_expect(!!(x), 1)
5298 #define unlikely(x) __builtin_expect(!!(x), 0)
5299 #else /* __GNUC__ > 2 ... */
5300 #define likely(x) (x)
5301 #define unlikely(x) (x)
5302 #endif /* __GNUC__ > 2 ... */
5303 #else /* __GNUC__ */
5304 #define likely(x) (x)
5305 #define unlikely(x) (x)
5306 #endif /* __GNUC__ */
5309 branch_prediction_macros = \
5311 #define likely(x) (x)
5312 #define unlikely(x) (x)
5315 #get_name_predeclaration = \
5316 #"static PyObject *__Pyx_GetName(PyObject *dict, char *name); /*proto*/"
5318 #get_name_interned_predeclaration = \
5319 #"static PyObject *__Pyx_GetName(PyObject *dict, PyObject *name); /*proto*/"
5321 #------------------------------------------------------------------------------------
5323 printing_utility_code = UtilityCode(
5325 static int __Pyx_Print(PyObject*, PyObject *, int); /*proto*/
5326 #if PY_MAJOR_VERSION >= 3
5327 static PyObject* %s = 0;
5328 static PyObject* %s = 0;
5330 """ % (Naming.print_function, Naming.print_function_kwargs),
5332 #if PY_MAJOR_VERSION >= 3
5336 """ % (Naming.print_function, Naming.print_function_kwargs),
5338 #if PY_MAJOR_VERSION < 3
5339 static PyObject *__Pyx_GetStdout(void) {
5340 PyObject *f = PySys_GetObject((char *)"stdout");
5342 PyErr_SetString(PyExc_RuntimeError, "lost sys.stdout");
5347 static int __Pyx_Print(PyObject* f, PyObject *arg_tuple, int newline) {
5352 if (!(f = __Pyx_GetStdout()))
5355 for (i=0; i < PyTuple_GET_SIZE(arg_tuple); i++) {
5356 if (PyFile_SoftSpace(f, 1)) {
5357 if (PyFile_WriteString(" ", f) < 0)
5360 v = PyTuple_GET_ITEM(arg_tuple, i);
5361 if (PyFile_WriteObject(v, f, Py_PRINT_RAW) < 0)
5363 if (PyString_Check(v)) {
5364 char *s = PyString_AsString(v);
5365 Py_ssize_t len = PyString_Size(v);
5367 isspace(Py_CHARMASK(s[len-1])) &&
5369 PyFile_SoftSpace(f, 0);
5373 if (PyFile_WriteString("\n", f) < 0)
5375 PyFile_SoftSpace(f, 0);
5380 #else /* Python 3 has a print function */
5382 static int __Pyx_Print(PyObject* stream, PyObject *arg_tuple, int newline) {
5383 PyObject* kwargs = 0;
5384 PyObject* result = 0;
5385 PyObject* end_string;
5386 if (unlikely(!%(PRINT_FUNCTION)s)) {
5387 %(PRINT_FUNCTION)s = __Pyx_GetAttrString(%(BUILTINS)s, "print");
5388 if (!%(PRINT_FUNCTION)s)
5392 kwargs = PyDict_New();
5393 if (unlikely(!kwargs))
5395 if (unlikely(PyDict_SetItemString(kwargs, "file", stream) < 0))
5398 end_string = PyUnicode_FromStringAndSize(" ", 1);
5399 if (unlikely(!end_string))
5401 if (PyDict_SetItemString(kwargs, "end", end_string) < 0) {
5402 Py_DECREF(end_string);
5405 Py_DECREF(end_string);
5407 } else if (!newline) {
5408 if (unlikely(!%(PRINT_KWARGS)s)) {
5409 %(PRINT_KWARGS)s = PyDict_New();
5410 if (unlikely(!%(PRINT_KWARGS)s))
5412 end_string = PyUnicode_FromStringAndSize(" ", 1);
5413 if (unlikely(!end_string))
5415 if (PyDict_SetItemString(%(PRINT_KWARGS)s, "end", end_string) < 0) {
5416 Py_DECREF(end_string);
5419 Py_DECREF(end_string);
5421 kwargs = %(PRINT_KWARGS)s;
5423 result = PyObject_Call(%(PRINT_FUNCTION)s, arg_tuple, kwargs);
5424 if (unlikely(kwargs) && (kwargs != %(PRINT_KWARGS)s))
5431 if (kwargs != %(PRINT_KWARGS)s)
5437 """ % {'BUILTINS' : Naming.builtins_cname,
5438 'PRINT_FUNCTION' : Naming.print_function,
5439 'PRINT_KWARGS' : Naming.print_function_kwargs}
5443 printing_one_utility_code = UtilityCode(
5445 static int __Pyx_PrintOne(PyObject* stream, PyObject *o); /*proto*/
5448 #if PY_MAJOR_VERSION < 3
5450 static int __Pyx_PrintOne(PyObject* f, PyObject *o) {
5452 if (!(f = __Pyx_GetStdout()))
5455 if (PyFile_SoftSpace(f, 0)) {
5456 if (PyFile_WriteString(" ", f) < 0)
5459 if (PyFile_WriteObject(o, f, Py_PRINT_RAW) < 0)
5461 if (PyFile_WriteString("\n", f) < 0)
5464 /* the line below is just to avoid compiler
5465 * compiler warnings about unused functions */
5466 return __Pyx_Print(f, NULL, 0);
5469 #else /* Python 3 has a print function */
5471 static int __Pyx_PrintOne(PyObject* stream, PyObject *o) {
5473 PyObject* arg_tuple = PyTuple_New(1);
5474 if (unlikely(!arg_tuple))
5477 PyTuple_SET_ITEM(arg_tuple, 0, o);
5478 res = __Pyx_Print(stream, arg_tuple, 1);
5479 Py_DECREF(arg_tuple);
5485 requires=[printing_utility_code])
5489 #------------------------------------------------------------------------------------
5491 # Exception raising code
5493 # Exceptions are raised by __Pyx_Raise() and stored as plain
5494 # type/value/tb in PyThreadState->curexc_*. When being caught by an
5495 # 'except' statement, curexc_* is moved over to exc_* by
5496 # __Pyx_GetException()
5498 restore_exception_utility_code = UtilityCode(
5500 static CYTHON_INLINE void __Pyx_ErrRestore(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
5501 static CYTHON_INLINE void __Pyx_ErrFetch(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
5504 static CYTHON_INLINE void __Pyx_ErrRestore(PyObject *type, PyObject *value, PyObject *tb) {
5505 PyObject *tmp_type, *tmp_value, *tmp_tb;
5506 PyThreadState *tstate = PyThreadState_GET();
5508 tmp_type = tstate->curexc_type;
5509 tmp_value = tstate->curexc_value;
5510 tmp_tb = tstate->curexc_traceback;
5511 tstate->curexc_type = type;
5512 tstate->curexc_value = value;
5513 tstate->curexc_traceback = tb;
5514 Py_XDECREF(tmp_type);
5515 Py_XDECREF(tmp_value);
5519 static CYTHON_INLINE void __Pyx_ErrFetch(PyObject **type, PyObject **value, PyObject **tb) {
5520 PyThreadState *tstate = PyThreadState_GET();
5521 *type = tstate->curexc_type;
5522 *value = tstate->curexc_value;
5523 *tb = tstate->curexc_traceback;
5525 tstate->curexc_type = 0;
5526 tstate->curexc_value = 0;
5527 tstate->curexc_traceback = 0;
5532 # The following function is based on do_raise() from ceval.c. There
5533 # are separate versions for Python2 and Python3 as exception handling
5534 # has changed quite a lot between the two versions.
5536 raise_utility_code = UtilityCode(
5538 static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
5541 #if PY_MAJOR_VERSION < 3
5542 static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb) {
5546 /* First, check the traceback argument, replacing None with NULL. */
5547 if (tb == Py_None) {
5551 else if (tb != NULL && !PyTraceBack_Check(tb)) {
5552 PyErr_SetString(PyExc_TypeError,
5553 "raise: arg 3 must be a traceback or None");
5556 /* Next, replace a missing value with None */
5557 if (value == NULL) {
5561 #if PY_VERSION_HEX < 0x02050000
5562 if (!PyClass_Check(type))
5564 if (!PyType_Check(type))
5567 /* Raising an instance. The value should be a dummy. */
5568 if (value != Py_None) {
5569 PyErr_SetString(PyExc_TypeError,
5570 "instance exception may not have a separate value");
5573 /* Normalize to raise <class>, <instance> */
5576 #if PY_VERSION_HEX < 0x02050000
5577 if (PyInstance_Check(type)) {
5578 type = (PyObject*) ((PyInstanceObject*)type)->in_class;
5583 PyErr_SetString(PyExc_TypeError,
5584 "raise: exception must be an old-style class or instance");
5588 type = (PyObject*) Py_TYPE(type);
5590 if (!PyType_IsSubtype((PyTypeObject *)type, (PyTypeObject *)PyExc_BaseException)) {
5591 PyErr_SetString(PyExc_TypeError,
5592 "raise: exception class must be a subclass of BaseException");
5598 __Pyx_ErrRestore(type, value, tb);
5607 #else /* Python 3+ */
5609 static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb) {
5610 if (tb == Py_None) {
5612 } else if (tb && !PyTraceBack_Check(tb)) {
5613 PyErr_SetString(PyExc_TypeError,
5614 "raise: arg 3 must be a traceback or None");
5617 if (value == Py_None)
5620 if (PyExceptionInstance_Check(type)) {
5622 PyErr_SetString(PyExc_TypeError,
5623 "instance exception may not have a separate value");
5627 type = (PyObject*) Py_TYPE(value);
5628 } else if (!PyExceptionClass_Check(type)) {
5629 PyErr_SetString(PyExc_TypeError,
5630 "raise: exception class must be a subclass of BaseException");
5634 PyErr_SetObject(type, value);
5637 PyThreadState *tstate = PyThreadState_GET();
5638 PyObject* tmp_tb = tstate->curexc_traceback;
5641 tstate->curexc_traceback = tb;
5651 requires=[restore_exception_utility_code])
5653 #------------------------------------------------------------------------------------
5655 get_exception_utility_code = UtilityCode(
5657 static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
5660 static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb) {
5661 PyObject *local_type, *local_value, *local_tb;
5662 PyObject *tmp_type, *tmp_value, *tmp_tb;
5663 PyThreadState *tstate = PyThreadState_GET();
5664 local_type = tstate->curexc_type;
5665 local_value = tstate->curexc_value;
5666 local_tb = tstate->curexc_traceback;
5667 tstate->curexc_type = 0;
5668 tstate->curexc_value = 0;
5669 tstate->curexc_traceback = 0;
5670 PyErr_NormalizeException(&local_type, &local_value, &local_tb);
5671 if (unlikely(tstate->curexc_type))
5673 #if PY_MAJOR_VERSION >= 3
5674 if (unlikely(PyException_SetTraceback(local_value, local_tb) < 0))
5678 *value = local_value;
5680 Py_INCREF(local_type);
5681 Py_INCREF(local_value);
5682 Py_INCREF(local_tb);
5683 tmp_type = tstate->exc_type;
5684 tmp_value = tstate->exc_value;
5685 tmp_tb = tstate->exc_traceback;
5686 tstate->exc_type = local_type;
5687 tstate->exc_value = local_value;
5688 tstate->exc_traceback = local_tb;
5689 /* Make sure tstate is in a consistent state when we XDECREF
5690 these objects (XDECREF may run arbitrary code). */
5691 Py_XDECREF(tmp_type);
5692 Py_XDECREF(tmp_value);
5699 Py_XDECREF(local_type);
5700 Py_XDECREF(local_value);
5701 Py_XDECREF(local_tb);
5707 #------------------------------------------------------------------------------------
5709 get_exception_tuple_utility_code = UtilityCode(proto="""
5710 static PyObject *__Pyx_GetExceptionTuple(void); /*proto*/
5712 # I doubt that calling __Pyx_GetException() here is correct as it moves
5713 # the exception from tstate->curexc_* to tstate->exc_*, which prevents
5714 # exception handlers later on from receiving it.
5716 static PyObject *__Pyx_GetExceptionTuple(void) {
5717 PyObject *type = NULL, *value = NULL, *tb = NULL;
5718 if (__Pyx_GetException(&type, &value, &tb) == 0) {
5719 PyObject* exc_info = PyTuple_New(3);
5724 PyTuple_SET_ITEM(exc_info, 0, type);
5725 PyTuple_SET_ITEM(exc_info, 1, value);
5726 PyTuple_SET_ITEM(exc_info, 2, tb);
5733 requires=[get_exception_utility_code])
5735 #------------------------------------------------------------------------------------
5737 reset_exception_utility_code = UtilityCode(
5739 static CYTHON_INLINE void __Pyx_ExceptionSave(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
5740 static void __Pyx_ExceptionReset(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
5743 static CYTHON_INLINE void __Pyx_ExceptionSave(PyObject **type, PyObject **value, PyObject **tb) {
5744 PyThreadState *tstate = PyThreadState_GET();
5745 *type = tstate->exc_type;
5746 *value = tstate->exc_value;
5747 *tb = tstate->exc_traceback;
5753 static void __Pyx_ExceptionReset(PyObject *type, PyObject *value, PyObject *tb) {
5754 PyObject *tmp_type, *tmp_value, *tmp_tb;
5755 PyThreadState *tstate = PyThreadState_GET();
5756 tmp_type = tstate->exc_type;
5757 tmp_value = tstate->exc_value;
5758 tmp_tb = tstate->exc_traceback;
5759 tstate->exc_type = type;
5760 tstate->exc_value = value;
5761 tstate->exc_traceback = tb;
5762 Py_XDECREF(tmp_type);
5763 Py_XDECREF(tmp_value);
5768 #------------------------------------------------------------------------------------
5770 arg_type_test_utility_code = UtilityCode(
5772 static int __Pyx_ArgTypeTest(PyObject *obj, PyTypeObject *type, int none_allowed,
5773 const char *name, int exact); /*proto*/
5776 static int __Pyx_ArgTypeTest(PyObject *obj, PyTypeObject *type, int none_allowed,
5777 const char *name, int exact)
5780 PyErr_Format(PyExc_SystemError, "Missing type object");
5783 if (none_allowed && obj == Py_None) return 1;
5785 if (Py_TYPE(obj) == type) return 1;
5788 if (PyObject_TypeCheck(obj, type)) return 1;
5790 PyErr_Format(PyExc_TypeError,
5791 "Argument '%s' has incorrect type (expected %s, got %s)",
5792 name, type->tp_name, Py_TYPE(obj)->tp_name);
5797 #------------------------------------------------------------------------------------
5799 # __Pyx_RaiseArgtupleInvalid raises the correct exception when too
5800 # many or too few positional arguments were found. This handles
5801 # Py_ssize_t formatting correctly.
5803 raise_argtuple_invalid_utility_code = UtilityCode(
5805 static void __Pyx_RaiseArgtupleInvalid(const char* func_name, int exact,
5806 Py_ssize_t num_min, Py_ssize_t num_max, Py_ssize_t num_found); /*proto*/
5809 static void __Pyx_RaiseArgtupleInvalid(
5810 const char* func_name,
5814 Py_ssize_t num_found)
5816 Py_ssize_t num_expected;
5817 const char *number, *more_or_less;
5819 if (num_found < num_min) {
5820 num_expected = num_min;
5821 more_or_less = "at least";
5823 num_expected = num_max;
5824 more_or_less = "at most";
5827 more_or_less = "exactly";
5829 number = (num_expected == 1) ? "" : "s";
5830 PyErr_Format(PyExc_TypeError,
5831 #if PY_VERSION_HEX < 0x02050000
5832 "%s() takes %s %d positional argument%s (%d given)",
5834 "%s() takes %s %zd positional argument%s (%zd given)",
5836 func_name, more_or_less, num_expected, number, num_found);
5840 raise_keyword_required_utility_code = UtilityCode(
5842 static CYTHON_INLINE void __Pyx_RaiseKeywordRequired(const char* func_name, PyObject* kw_name); /*proto*/
5845 static CYTHON_INLINE void __Pyx_RaiseKeywordRequired(
5846 const char* func_name,
5849 PyErr_Format(PyExc_TypeError,
5850 #if PY_MAJOR_VERSION >= 3
5851 "%s() needs keyword-only argument %U", func_name, kw_name);
5853 "%s() needs keyword-only argument %s", func_name,
5854 PyString_AS_STRING(kw_name));
5859 raise_double_keywords_utility_code = UtilityCode(
5861 static void __Pyx_RaiseDoubleKeywordsError(
5862 const char* func_name, PyObject* kw_name); /*proto*/
5865 static void __Pyx_RaiseDoubleKeywordsError(
5866 const char* func_name,
5869 PyErr_Format(PyExc_TypeError,
5870 #if PY_MAJOR_VERSION >= 3
5871 "%s() got multiple values for keyword argument '%U'", func_name, kw_name);
5873 "%s() got multiple values for keyword argument '%s'", func_name,
5874 PyString_AS_STRING(kw_name));
5879 #------------------------------------------------------------------------------------
5881 # __Pyx_CheckKeywordStrings raises an error if non-string keywords
5882 # were passed to a function, or if any keywords were passed to a
5883 # function that does not accept them.
5885 keyword_string_check_utility_code = UtilityCode(
5887 static CYTHON_INLINE int __Pyx_CheckKeywordStrings(PyObject *kwdict,
5888 const char* function_name, int kw_allowed); /*proto*/
5891 static CYTHON_INLINE int __Pyx_CheckKeywordStrings(
5893 const char* function_name,
5898 while (PyDict_Next(kwdict, &pos, &key, 0)) {
5899 #if PY_MAJOR_VERSION < 3
5900 if (unlikely(!PyString_CheckExact(key)) && unlikely(!PyString_Check(key)))
5902 if (unlikely(!PyUnicode_CheckExact(key)) && unlikely(!PyUnicode_Check(key)))
5904 goto invalid_keyword_type;
5906 if ((!kw_allowed) && unlikely(key))
5907 goto invalid_keyword;
5909 invalid_keyword_type:
5910 PyErr_Format(PyExc_TypeError,
5911 "%s() keywords must be strings", function_name);
5914 PyErr_Format(PyExc_TypeError,
5915 #if PY_MAJOR_VERSION < 3
5916 "%s() got an unexpected keyword argument '%s'",
5917 function_name, PyString_AsString(key));
5919 "%s() got an unexpected keyword argument '%U'",
5920 function_name, key);
5926 #------------------------------------------------------------------------------------
5928 # __Pyx_ParseOptionalKeywords copies the optional/unknown keyword
5929 # arguments from the kwds dict into kwds2. If kwds2 is NULL, unknown
5930 # keywords will raise an invalid keyword error.
5932 # Three kinds of errors are checked: 1) non-string keywords, 2)
5933 # unexpected keywords and 3) overlap with positional arguments.
5935 # If num_posargs is greater 0, it denotes the number of positional
5936 # arguments that were passed and that must therefore not appear
5937 # amongst the keywords as well.
5939 # This method does not check for required keyword arguments.
5942 parse_keywords_utility_code = UtilityCode(
5944 static int __Pyx_ParseOptionalKeywords(PyObject *kwds, PyObject **argnames[], \
5945 PyObject *kwds2, PyObject *values[], Py_ssize_t num_pos_args, \
5946 const char* function_name); /*proto*/
5949 static int __Pyx_ParseOptionalKeywords(
5951 PyObject **argnames[],
5954 Py_ssize_t num_pos_args,
5955 const char* function_name)
5957 PyObject *key = 0, *value = 0;
5960 PyObject*** first_kw_arg = argnames + num_pos_args;
5962 while (PyDict_Next(kwds, &pos, &key, &value)) {
5963 name = first_kw_arg;
5964 while (*name && (**name != key)) name++;
5966 values[name-argnames] = value;
5968 #if PY_MAJOR_VERSION < 3
5969 if (unlikely(!PyString_CheckExact(key)) && unlikely(!PyString_Check(key))) {
5971 if (unlikely(!PyUnicode_CheckExact(key)) && unlikely(!PyUnicode_Check(key))) {
5973 goto invalid_keyword_type;
5975 for (name = first_kw_arg; *name; name++) {
5976 #if PY_MAJOR_VERSION >= 3
5977 if (PyUnicode_GET_SIZE(**name) == PyUnicode_GET_SIZE(key) &&
5978 PyUnicode_Compare(**name, key) == 0) break;
5980 if (PyString_GET_SIZE(**name) == PyString_GET_SIZE(key) &&
5981 _PyString_Eq(**name, key)) break;
5985 values[name-argnames] = value;
5987 /* unexpected keyword found */
5988 for (name=argnames; name != first_kw_arg; name++) {
5989 if (**name == key) goto arg_passed_twice;
5990 #if PY_MAJOR_VERSION >= 3
5991 if (PyUnicode_GET_SIZE(**name) == PyUnicode_GET_SIZE(key) &&
5992 PyUnicode_Compare(**name, key) == 0) goto arg_passed_twice;
5994 if (PyString_GET_SIZE(**name) == PyString_GET_SIZE(key) &&
5995 _PyString_Eq(**name, key)) goto arg_passed_twice;
5999 if (unlikely(PyDict_SetItem(kwds2, key, value))) goto bad;
6001 goto invalid_keyword;
6009 __Pyx_RaiseDoubleKeywordsError(function_name, **name);
6011 invalid_keyword_type:
6012 PyErr_Format(PyExc_TypeError,
6013 "%s() keywords must be strings", function_name);
6016 PyErr_Format(PyExc_TypeError,
6017 #if PY_MAJOR_VERSION < 3
6018 "%s() got an unexpected keyword argument '%s'",
6019 function_name, PyString_AsString(key));
6021 "%s() got an unexpected keyword argument '%U'",
6022 function_name, key);
6029 #------------------------------------------------------------------------------------
6031 traceback_utility_code = UtilityCode(
6033 static void __Pyx_AddTraceback(const char *funcname); /*proto*/
6036 #include "compile.h"
6037 #include "frameobject.h"
6038 #include "traceback.h"
6040 static void __Pyx_AddTraceback(const char *funcname) {
6041 PyObject *py_srcfile = 0;
6042 PyObject *py_funcname = 0;
6043 PyObject *py_globals = 0;
6044 PyCodeObject *py_code = 0;
6045 PyFrameObject *py_frame = 0;
6047 #if PY_MAJOR_VERSION < 3
6048 py_srcfile = PyString_FromString(%(FILENAME)s);
6050 py_srcfile = PyUnicode_FromString(%(FILENAME)s);
6052 if (!py_srcfile) goto bad;
6054 #if PY_MAJOR_VERSION < 3
6055 py_funcname = PyString_FromFormat( "%%s (%%s:%%d)", funcname, %(CFILENAME)s, %(CLINENO)s);
6057 py_funcname = PyUnicode_FromFormat( "%%s (%%s:%%d)", funcname, %(CFILENAME)s, %(CLINENO)s);
6061 #if PY_MAJOR_VERSION < 3
6062 py_funcname = PyString_FromString(funcname);
6064 py_funcname = PyUnicode_FromString(funcname);
6067 if (!py_funcname) goto bad;
6068 py_globals = PyModule_GetDict(%(GLOBALS)s);
6069 if (!py_globals) goto bad;
6070 py_code = PyCode_New(
6071 0, /*int argcount,*/
6072 #if PY_MAJOR_VERSION >= 3
6073 0, /*int kwonlyargcount,*/
6076 0, /*int stacksize,*/
6078 %(EMPTY_BYTES)s, /*PyObject *code,*/
6079 %(EMPTY_TUPLE)s, /*PyObject *consts,*/
6080 %(EMPTY_TUPLE)s, /*PyObject *names,*/
6081 %(EMPTY_TUPLE)s, /*PyObject *varnames,*/
6082 %(EMPTY_TUPLE)s, /*PyObject *freevars,*/
6083 %(EMPTY_TUPLE)s, /*PyObject *cellvars,*/
6084 py_srcfile, /*PyObject *filename,*/
6085 py_funcname, /*PyObject *name,*/
6086 %(LINENO)s, /*int firstlineno,*/
6087 %(EMPTY_BYTES)s /*PyObject *lnotab*/
6089 if (!py_code) goto bad;
6090 py_frame = PyFrame_New(
6091 PyThreadState_GET(), /*PyThreadState *tstate,*/
6092 py_code, /*PyCodeObject *code,*/
6093 py_globals, /*PyObject *globals,*/
6094 0 /*PyObject *locals*/
6096 if (!py_frame) goto bad;
6097 py_frame->f_lineno = %(LINENO)s;
6098 PyTraceBack_Here(py_frame);
6100 Py_XDECREF(py_srcfile);
6101 Py_XDECREF(py_funcname);
6102 Py_XDECREF(py_code);
6103 Py_XDECREF(py_frame);
6106 'FILENAME': Naming.filename_cname,
6107 'LINENO': Naming.lineno_cname,
6108 'CFILENAME': Naming.cfilenm_cname,
6109 'CLINENO': Naming.clineno_cname,
6110 'GLOBALS': Naming.module_cname,
6111 'EMPTY_TUPLE' : Naming.empty_tuple,
6112 'EMPTY_BYTES' : Naming.empty_bytes,
6115 #------------------------------------------------------------------------------------
6117 unraisable_exception_utility_code = UtilityCode(
6119 static void __Pyx_WriteUnraisable(const char *name); /*proto*/
6122 static void __Pyx_WriteUnraisable(const char *name) {
6123 PyObject *old_exc, *old_val, *old_tb;
6125 __Pyx_ErrFetch(&old_exc, &old_val, &old_tb);
6126 #if PY_MAJOR_VERSION < 3
6127 ctx = PyString_FromString(name);
6129 ctx = PyUnicode_FromString(name);
6131 __Pyx_ErrRestore(old_exc, old_val, old_tb);
6133 PyErr_WriteUnraisable(Py_None);
6135 PyErr_WriteUnraisable(ctx);
6140 requires=[restore_exception_utility_code])
6142 #------------------------------------------------------------------------------------
6144 set_vtable_utility_code = UtilityCode(
6146 static int __Pyx_SetVtable(PyObject *dict, void *vtable); /*proto*/
6149 static int __Pyx_SetVtable(PyObject *dict, void *vtable) {
6150 #if PY_VERSION_HEX >= 0x02070000 && !(PY_MAJOR_VERSION==3&&PY_MINOR_VERSION==0)
6151 PyObject *ob = PyCapsule_New(vtable, 0, 0);
6153 PyObject *ob = PyCObject_FromVoidPtr(vtable, 0);
6157 if (PyDict_SetItemString(dict, "__pyx_vtable__", ob) < 0)
6167 #------------------------------------------------------------------------------------
6169 get_vtable_utility_code = UtilityCode(
6171 static int __Pyx_GetVtable(PyObject *dict, void *vtabptr); /*proto*/
6174 static int __Pyx_GetVtable(PyObject *dict, void *vtabptr) {
6175 PyObject *ob = PyMapping_GetItemString(dict, (char *)"__pyx_vtable__");
6178 #if PY_VERSION_HEX >= 0x02070000 && !(PY_MAJOR_VERSION==3&&PY_MINOR_VERSION==0)
6179 *(void **)vtabptr = PyCapsule_GetPointer(ob, 0);
6181 *(void **)vtabptr = PyCObject_AsVoidPtr(ob);
6183 if (!*(void **)vtabptr)
6193 #------------------------------------------------------------------------------------
6195 init_string_tab_utility_code = UtilityCode(
6197 static int __Pyx_InitStrings(__Pyx_StringTabEntry *t); /*proto*/
6200 static int __Pyx_InitStrings(__Pyx_StringTabEntry *t) {
6202 #if PY_MAJOR_VERSION < 3
6203 if (t->is_unicode) {
6204 *t->p = PyUnicode_DecodeUTF8(t->s, t->n - 1, NULL);
6205 } else if (t->intern) {
6206 *t->p = PyString_InternFromString(t->s);
6208 *t->p = PyString_FromStringAndSize(t->s, t->n - 1);
6210 #else /* Python 3+ has unicode identifiers */
6211 if (t->is_unicode | t->is_str) {
6213 *t->p = PyUnicode_InternFromString(t->s);
6214 } else if (t->encoding) {
6215 *t->p = PyUnicode_Decode(t->s, t->n - 1, t->encoding, NULL);
6217 *t->p = PyUnicode_FromStringAndSize(t->s, t->n - 1);
6220 *t->p = PyBytes_FromStringAndSize(t->s, t->n - 1);
6231 #------------------------------------------------------------------------------------
6233 force_init_threads_utility_code = UtilityCode(
6235 #ifndef __PYX_FORCE_INIT_THREADS
6236 #if PY_VERSION_HEX < 0x02040200
6237 #define __PYX_FORCE_INIT_THREADS 1
6239 #define __PYX_FORCE_INIT_THREADS 0
6244 #------------------------------------------------------------------------------------
6246 # Note that cPython ignores PyTrace_EXCEPTION,
6247 # but maybe some other profilers don't.
6249 profile_utility_code = UtilityCode(proto="""
6250 #ifndef CYTHON_PROFILE
6251 #define CYTHON_PROFILE 1
6254 #ifndef CYTHON_PROFILE_REUSE_FRAME
6255 #define CYTHON_PROFILE_REUSE_FRAME 0
6260 #include "compile.h"
6261 #include "frameobject.h"
6262 #include "traceback.h"
6264 #if CYTHON_PROFILE_REUSE_FRAME
6265 #define CYTHON_FRAME_MODIFIER static
6266 #define CYTHON_FRAME_DEL
6268 #define CYTHON_FRAME_MODIFIER
6269 #define CYTHON_FRAME_DEL Py_DECREF(%(FRAME)s)
6272 #define __Pyx_TraceDeclarations \\
6273 static PyCodeObject *%(FRAME_CODE)s = NULL; \\
6274 CYTHON_FRAME_MODIFIER PyFrameObject *%(FRAME)s = NULL; \\
6275 int __Pyx_use_tracing = 0;
6277 #define __Pyx_TraceCall(funcname, srcfile, firstlineno) \\
6278 if (unlikely(PyThreadState_GET()->use_tracing && PyThreadState_GET()->c_profilefunc)) { \\
6279 __Pyx_use_tracing = __Pyx_TraceSetupAndCall(&%(FRAME_CODE)s, &%(FRAME)s, funcname, srcfile, firstlineno); \\
6282 #define __Pyx_TraceException() \\
6283 if (unlikely(__Pyx_use_tracing( && PyThreadState_GET()->use_tracing && PyThreadState_GET()->c_profilefunc) { \\
6284 PyObject *exc_info = __Pyx_GetExceptionTuple(); \\
6286 PyThreadState_GET()->c_profilefunc( \\
6287 PyThreadState_GET()->c_profileobj, %(FRAME)s, PyTrace_EXCEPTION, exc_info); \\
6288 Py_DECREF(exc_info); \\
6292 #define __Pyx_TraceReturn(result) \\
6293 if (unlikely(__Pyx_use_tracing) && PyThreadState_GET()->use_tracing && PyThreadState_GET()->c_profilefunc) { \\
6294 PyThreadState_GET()->c_profilefunc( \\
6295 PyThreadState_GET()->c_profileobj, %(FRAME)s, PyTrace_RETURN, (PyObject*)result); \\
6296 CYTHON_FRAME_DEL; \\
6299 static PyCodeObject *__Pyx_createFrameCodeObject(const char *funcname, const char *srcfile, int firstlineno); /*proto*/
6300 static int __Pyx_TraceSetupAndCall(PyCodeObject** code, PyFrameObject** frame, const char *funcname, const char *srcfile, int firstlineno); /*proto*/
6304 #define __Pyx_TraceDeclarations
6305 #define __Pyx_TraceCall(funcname, srcfile, firstlineno)
6306 #define __Pyx_TraceException()
6307 #define __Pyx_TraceReturn(result)
6309 #endif /* CYTHON_PROFILE */
6312 "FRAME": Naming.frame_cname,
6313 "FRAME_CODE": Naming.frame_code_cname,
6319 static int __Pyx_TraceSetupAndCall(PyCodeObject** code,
6320 PyFrameObject** frame,
6321 const char *funcname,
6322 const char *srcfile,
6324 if (*frame == NULL || !CYTHON_PROFILE_REUSE_FRAME) {
6325 if (*code == NULL) {
6326 *code = __Pyx_createFrameCodeObject(funcname, srcfile, firstlineno);
6327 if (*code == NULL) return 0;
6329 *frame = PyFrame_New(
6330 PyThreadState_GET(), /*PyThreadState *tstate*/
6331 *code, /*PyCodeObject *code*/
6332 PyModule_GetDict(%(MODULE)s), /*PyObject *globals*/
6333 0 /*PyObject *locals*/
6335 if (*frame == NULL) return 0;
6338 (*frame)->f_tstate = PyThreadState_GET();
6340 return PyThreadState_GET()->c_profilefunc(PyThreadState_GET()->c_profileobj, *frame, PyTrace_CALL, NULL) == 0;
6343 static PyCodeObject *__Pyx_createFrameCodeObject(const char *funcname, const char *srcfile, int firstlineno) {
6344 PyObject *py_srcfile = 0;
6345 PyObject *py_funcname = 0;
6346 PyCodeObject *py_code = 0;
6348 #if PY_MAJOR_VERSION < 3
6349 py_funcname = PyString_FromString(funcname);
6350 py_srcfile = PyString_FromString(srcfile);
6352 py_funcname = PyUnicode_FromString(funcname);
6353 py_srcfile = PyUnicode_FromString(srcfile);
6355 if (!py_funcname | !py_srcfile) goto bad;
6357 py_code = PyCode_New(
6358 0, /*int argcount,*/
6359 #if PY_MAJOR_VERSION >= 3
6360 0, /*int kwonlyargcount,*/
6363 0, /*int stacksize,*/
6365 %(EMPTY_BYTES)s, /*PyObject *code,*/
6366 %(EMPTY_TUPLE)s, /*PyObject *consts,*/
6367 %(EMPTY_TUPLE)s, /*PyObject *names,*/
6368 %(EMPTY_TUPLE)s, /*PyObject *varnames,*/
6369 %(EMPTY_TUPLE)s, /*PyObject *freevars,*/
6370 %(EMPTY_TUPLE)s, /*PyObject *cellvars,*/
6371 py_srcfile, /*PyObject *filename,*/
6372 py_funcname, /*PyObject *name,*/
6373 firstlineno, /*int firstlineno,*/
6374 %(EMPTY_BYTES)s /*PyObject *lnotab*/
6378 Py_XDECREF(py_srcfile);
6379 Py_XDECREF(py_funcname);
6384 #endif /* CYTHON_PROFILE */
6386 'EMPTY_TUPLE' : Naming.empty_tuple,
6387 'EMPTY_BYTES' : Naming.empty_bytes,
6388 "MODULE": Naming.module_cname,