<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def find_widening_points(function_addr, function_endpoints, graph):
 # pylint: disable=unused-argument """ Given a local transition graph of a function, find all widening points inside. Correctly choosing widening points is very important in order to not lose too much information during static analysis. We mainly consider merge points that has at least one loop back edges coming in as widening points. :param int function_addr: Address of the function. :param list function_endpoints: Endpoints of the function, typically coming from Function.endpoints. :param networkx.DiGraph graph: A local transition graph of a function, normally Function.graph. :return: A list of addresses of widening points. :rtype: list """


        sccs = networkx.strongly_connected_components(graph)

        widening_addrs = set()

        for scc in sccs:
            if len(scc) == 1:
                node = next(iter(scc))
                if graph.has_edge(node, node):
                    # self loop
                    widening_addrs.add(node.addr)
            else:
                for n in scc:
                    predecessors = graph.predecessors(n)
                    if any([ p not in scc for p in predecessors]):
                        widening_addrs.add(n.addr)
                        break

        return list(widening_addrs)