Пример #1
0
    def build_flow(self, func, constargs={}):
        """
        """
        if func.func_doc and func.func_doc.lstrip().startswith('NOT_RPYTHON'):
            raise Exception, "%r is tagged as NOT_RPYTHON" % (func, )
        code = func.func_code
        if code.co_flags & 32:
            # generator
            raise TypeError("%r is a generator" % (func, ))
        code = PyCode._from_code(self, code)
        if func.func_closure is None:
            closure = None
        else:
            closure = [
                extract_cell_content(c, name, func) for c, name in zip(
                    func.func_closure, func.func_code.co_freevars)
            ]
        # CallableFactory.pycall may add class_ to functions that are methods
        name = func.func_name
        class_ = getattr(func, 'class_', None)
        if class_ is not None:
            name = '%s.%s' % (class_.__name__, name)
        for c in "<>&!":
            name = name.replace(c, '_')
        ec = flowcontext.FlowExecutionContext(self, code, func.func_globals,
                                              constargs, closure, name)
        graph = ec.graph
        graph.func = func
        # attach a signature and defaults to the graph
        # so that it becomes even more interchangeable with the function
        # itself
        graph.signature = cpython_code_signature(code)
        graph.defaults = func.func_defaults or ()
        self.setup_executioncontext(ec)

        from pypy.tool.error import FlowingError, format_global_error

        try:
            ec.build_flow()
        except FlowingError, a:
            # attach additional source info to AnnotatorError
            _, _, tb = sys.exc_info()
            e = FlowingError(
                format_global_error(ec.graph, ec.crnt_offset, str(a)))
            raise FlowingError, e, tb
Пример #2
0
    def build_flow(self, func, constargs={}, tweak_for_generator=True):
        """
        """
        if func.func_doc and func.func_doc.lstrip().startswith('NOT_RPYTHON'):
            raise Exception, "%r is tagged as NOT_RPYTHON" % (func, )
        code = func.func_code
        is_generator = bool(code.co_flags & CO_GENERATOR)
        code = PyCode._from_code(self, code)
        if func.func_closure is None:
            cl = None
        else:
            cl = [extract_cell_content(c) for c in func.func_closure]
        # CallableFactory.pycall may add class_ to functions that are methods
        name = func.func_name
        class_ = getattr(func, 'class_', None)
        if class_ is not None:
            name = '%s.%s' % (class_.__name__, name)
        for c in "<>&!":
            name = name.replace(c, '_')

        class outerfunc:  # hack
            closure = cl

        ec = flowcontext.FlowExecutionContext(self, code, func.func_globals,
                                              constargs, outerfunc, name,
                                              is_generator)
        graph = ec.graph
        graph.func = func
        # attach a signature and defaults to the graph
        # so that it becomes even more interchangeable with the function
        # itself
        graph.signature = cpython_code_signature(code)
        graph.defaults = func.func_defaults or ()
        self.setup_executioncontext(ec)

        try:
            ec.build_flow()
        except error.FlowingError, a:
            # attach additional source info to AnnotatorError
            _, _, tb = sys.exc_info()
            formated = error.format_global_error(ec.graph, ec.crnt_offset,
                                                 str(a))
            e = error.FlowingError(formated)
            raise error.FlowingError, e, tb