Exemple #1
0
def find_cycles(system):
    from rpython.tool.algo import graphlib
    vertices = dict.fromkeys(system.modules)
    edges = {}
    for m in system.modules:
        edges[m] = []
        for n in system.modules[m]._imports:
            edges[m].append(graphlib.Edge(m, n))
    cycles = []
    for component in graphlib.strong_components(vertices, edges):
        random_vertex = component.iterkeys().next()
        cycles.extend(graphlib.all_cycles(random_vertex, component, edges))

    ncycles = []
    for cycle in cycles:
        packs = {}
        for edge in cycle:
            package = edge.source.rsplit('.', 1)[0]
            packs[package] = True
        if len(packs) > 1:
            ncycles.append(cycle)
    cycles = ncycles

    for cycle in cycles:
        l = len(cycle[0].source)
        print cycle[0].source, '->', cycle[0].target
        for edge in cycle[1:]:
            print ' ' * l, '->', edge.target
    print len(cycles), 'inter-package cycles'
Exemple #2
0
def find_cycles(system):
    from rpython.tool.algo import graphlib
    vertices = dict.fromkeys(system.modules)
    edges = {}
    for m in system.modules:
        edges[m] = []
        for n in system.modules[m]._imports:
            edges[m].append(graphlib.Edge(m, n))
    cycles = []
    for component in graphlib.strong_components(vertices, edges):
        random_vertex = component.iterkeys().next()
        cycles.extend(graphlib.all_cycles(random_vertex, component, edges))

    ncycles = []
    for cycle in cycles:
        packs = {}
        for edge in cycle:
            package = edge.source.rsplit('.', 1)[0]
            packs[package] = True
        if len(packs) > 1:
            ncycles.append(cycle)
    cycles = ncycles

    for cycle in cycles:
        l = len(cycle[0].source)
        print cycle[0].source, '->', cycle[0].target
        for edge in cycle[1:]:
            print ' '*l, '->', edge.target
    print len(cycles), 'inter-package cycles'
Exemple #3
0
    def definestr_finalizer_order(cls):
        import random
        from rpython.tool.algo import graphlib

        cls.finalizer_order_examples = examples = []
        if cls.large_tests_ok:
            letters = 'abcdefghijklmnopqrstuvwxyz'
            COUNT = 20
        else:
            letters = 'abcdefghijklm'
            COUNT = 2
        for i in range(COUNT):
            input = []
            edges = {}
            for c in letters:
                edges[c] = []
            # make up a random graph
            for c in letters:
                for j in range(random.randrange(0, 4)):
                    d = random.choice(letters)
                    edges[c].append(graphlib.Edge(c, d))
                    input.append((c, d))
            # find the expected order in which destructors should be called
            components = list(graphlib.strong_components(edges, edges))
            head = {}
            for component in components:
                c = component.keys()[0]
                for d in component:
                    assert d not in head
                    head[d] = c
            assert len(head) == len(letters)
            strict = []
            for c, d in input:
                if head[c] != head[d]:
                    strict.append((c, d))
            examples.append((input, components, strict))

        class State:
            pass

        state = State()

        def age_of(c):
            return state.age[ord(c) - ord('a')]

        def set_age_of(c, newvalue):
            # NB. this used to be a dictionary, but setting into a dict
            # consumes memory.  This has the effect that this test's
            # finalizer_trigger method can consume more memory and potentially
            # cause another collection.  This would result in objects
            # being unexpectedly destroyed at the same 'state.time'.
            state.age[ord(c) - ord('a')] = newvalue

        class A:
            def __init__(self, key):
                self.key = key
                self.refs = []
                fq.register_finalizer(self)

        class FQ(rgc.FinalizerQueue):
            Class = A

            def finalizer_trigger(self):
                from rpython.rlib.debug import debug_print
                while True:
                    a = self.next_dead()
                    if a is None:
                        break
                    debug_print("DEL:", a.key)
                    assert age_of(a.key) == -1
                    set_age_of(a.key, state.time)
                    state.progress = True

        fq = FQ()

        def build_example(input):
            state.time = 0
            state.age = [-1] * len(letters)
            vertices = {}
            for c in letters:
                vertices[c] = A(c)
            for c, d in input:
                vertices[c].refs.append(vertices[d])

        def f(_):
            i = 0
            while i < len(examples):
                input, components, strict = examples[i]
                build_example(input)
                while state.time < len(letters):
                    from rpython.rlib.debug import debug_print
                    debug_print("STATE.TIME:", state.time)
                    state.progress = False
                    llop.gc__collect(lltype.Void)
                    if not state.progress:
                        break
                    state.time += 1
                # summarize the finalization order
                lst = []
                for c in letters:
                    lst.append('%s:%d' % (c, age_of(c)))
                summary = ', '.join(lst)

                # check that all instances have been finalized
                if -1 in state.age:
                    return error(i, summary, "not all instances finalized")
                # check that if a -> b and a and b are not in the same
                # strong component, then a is finalized strictly before b
                for c, d in strict:
                    if age_of(c) >= age_of(d):
                        return error(
                            i, summary,
                            "%s should be finalized before %s" % (c, d))
                # check that two instances in the same strong component
                # are never finalized during the same collection
                for component in components:
                    seen = {}
                    for c in component:
                        age = age_of(c)
                        if age in seen:
                            d = seen[age]
                            return error(
                                i, summary, "%s and %s should not be finalized"
                                " at the same time" % (c, d))
                        seen[age] = c
                i += 1
            return "ok"

        def error(i, summary, msg):
            return '%d\n%s\n%s' % (i, summary, msg)

        return f
Exemple #4
0
    def definestr_finalizer_order(cls):
        import random
        from rpython.tool.algo import graphlib

        cls.finalizer_order_examples = examples = []
        if cls.large_tests_ok:
            letters = 'abcdefghijklmnopqrstuvwxyz'
            COUNT = 20
        else:
            letters = 'abcdefghijklm'
            COUNT = 2
        for i in range(COUNT):
            input = []
            edges = {}
            for c in letters:
                edges[c] = []
            # make up a random graph
            for c in letters:
                for j in range(random.randrange(0, 4)):
                    d = random.choice(letters)
                    edges[c].append(graphlib.Edge(c, d))
                    input.append((c, d))
            # find the expected order in which destructors should be called
            components = list(graphlib.strong_components(edges, edges))
            head = {}
            for component in components:
                c = component.keys()[0]
                for d in component:
                    assert d not in head
                    head[d] = c
            assert len(head) == len(letters)
            strict = []
            for c, d in input:
                if head[c] != head[d]:
                    strict.append((c, d))
            examples.append((input, components, strict))

        class State:
            pass
        state = State()
        def age_of(c):
            return state.age[ord(c) - ord('a')]
        def set_age_of(c, newvalue):
            # NB. this used to be a dictionary, but setting into a dict
            # consumes memory.  This has the effect that this test's
            # finalizer_trigger method can consume more memory and potentially
            # cause another collection.  This would result in objects
            # being unexpectedly destroyed at the same 'state.time'.
            state.age[ord(c) - ord('a')] = newvalue

        class A:
            def __init__(self, key):
                self.key = key
                self.refs = []
                fq.register_finalizer(self)

        class FQ(rgc.FinalizerQueue):
            Class = A
            def finalizer_trigger(self):
                from rpython.rlib.debug import debug_print
                while True:
                    a = self.next_dead()
                    if a is None:
                        break
                    debug_print("DEL:", a.key)
                    assert age_of(a.key) == -1
                    set_age_of(a.key, state.time)
                    state.progress = True
        fq = FQ()

        def build_example(input):
            state.time = 0
            state.age = [-1] * len(letters)
            vertices = {}
            for c in letters:
                vertices[c] = A(c)
            for c, d in input:
                vertices[c].refs.append(vertices[d])

        def f(_):
            i = 0
            while i < len(examples):
                input, components, strict = examples[i]
                build_example(input)
                while state.time < len(letters):
                    from rpython.rlib.debug import debug_print
                    debug_print("STATE.TIME:", state.time)
                    state.progress = False
                    llop.gc__collect(lltype.Void)
                    if not state.progress:
                        break
                    state.time += 1
                # summarize the finalization order
                lst = []
                for c in letters:
                    lst.append('%s:%d' % (c, age_of(c)))
                summary = ', '.join(lst)

                # check that all instances have been finalized
                if -1 in state.age:
                    return error(i, summary, "not all instances finalized")
                # check that if a -> b and a and b are not in the same
                # strong component, then a is finalized strictly before b
                for c, d in strict:
                    if age_of(c) >= age_of(d):
                        return error(i, summary,
                                     "%s should be finalized before %s"
                                     % (c, d))
                # check that two instances in the same strong component
                # are never finalized during the same collection
                for component in components:
                    seen = {}
                    for c in component:
                        age = age_of(c)
                        if age in seen:
                            d = seen[age]
                            return error(i, summary,
                                         "%s and %s should not be finalized"
                                         " at the same time" % (c, d))
                        seen[age] = c
                i += 1
            return "ok"

        def error(i, summary, msg):
            return '%d\n%s\n%s' % (i, summary, msg)

        return f
Exemple #5
0
    def definestr_finalizer_order(cls):
        import random
        from rpython.tool.algo import graphlib

        cls.finalizer_order_examples = examples = []
        if cls.large_tests_ok:
            letters = 'abcdefghijklmnopqrstuvwxyz'
            COUNT = 20
        else:
            letters = 'abcdefghijklm'
            COUNT = 2
        for i in range(COUNT):
            input = []
            edges = {}
            for c in letters:
                edges[c] = []
            # make up a random graph
            for c in letters:
                for j in range(random.randrange(0, 4)):
                    d = random.choice(letters)
                    edges[c].append(graphlib.Edge(c, d))
                    input.append((c, d))
            # find the expected order in which destructors should be called
            components = list(graphlib.strong_components(edges, edges))
            head = {}
            for component in components:
                c = component.keys()[0]
                for d in component:
                    assert d not in head
                    head[d] = c
            assert len(head) == len(letters)
            strict = []
            for c, d in input:
                if head[c] != head[d]:
                    strict.append((c, d))
            examples.append((input, components, strict))

        class State:
            pass
        state = State()
        class A:
            def __init__(self, key):
                self.key = key
                self.refs = []
            def __del__(self):
                assert state.age[self.key] == -1
                state.age[self.key] = state.time
                state.progress = True

        def build_example(input):
            state.time = 0
            state.age = {}
            vertices = {}
            for c in letters:
                vertices[c] = A(c)
                state.age[c] = -1
            for c, d in input:
                vertices[c].refs.append(vertices[d])

        def f(_):
            i = 0
            while i < len(examples):
                input, components, strict = examples[i]
                build_example(input)
                while state.time < len(letters):
                    state.progress = False
                    llop.gc__collect(lltype.Void)
                    if not state.progress:
                        break
                    state.time += 1
                # summarize the finalization order
                lst = []
                for c in letters:
                    lst.append('%s:%d' % (c, state.age[c]))
                summary = ', '.join(lst)

                # check that all instances have been finalized
                if -1 in state.age.values():
                    return error(i, summary, "not all instances finalized")
                # check that if a -> b and a and b are not in the same
                # strong component, then a is finalized strictly before b
                for c, d in strict:
                    if state.age[c] >= state.age[d]:
                        return error(i, summary,
                                     "%s should be finalized before %s"
                                     % (c, d))
                # check that two instances in the same strong component
                # are never finalized during the same collection
                for component in components:
                    seen = {}
                    for c in component:
                        age = state.age[c]
                        if age in seen:
                            d = seen[age]
                            return error(i, summary,
                                         "%s and %s should not be finalized"
                                         " at the same time" % (c, d))
                        seen[age] = c
                i += 1
            return "ok"

        def error(i, summary, msg):
            return '%d\n%s\n%s' % (i, summary, msg)

        return f