comparison contrib/import-checker.py @ 20038:c65a6937b828

import-checker: try a little harder to show fewer cycles This makes sure that all cycles begin with the lexicographically first module, so that we're less likely to show overlapping cycles in the final analysis.
author Augie Fackler <raf@durin42.com>
date Sun, 17 Nov 2013 13:33:20 -0500
parents 957b43371928
children 761f2929a6ad
comparison
equal deleted inserted replaced
20037:957b43371928 20038:c65a6937b828
151 if cyclekey(cycle) not in ignore: 151 if cyclekey(cycle) not in ignore:
152 raise CircularImport(cycle) 152 raise CircularImport(cycle)
153 continue 153 continue
154 check_one_mod(i, imports, path=path, ignore=ignore) 154 check_one_mod(i, imports, path=path, ignore=ignore)
155 155
156 def rotatecycle(cycle):
157 """arrange a cycle so that the lexicographically first module listed first
158
159 >>> rotatecycle(['foo', 'bar', 'foo'])
160 ['bar', 'foo', 'bar']
161 """
162 lowest = min(cycle)
163 idx = cycle.index(lowest)
164 return cycle[idx:] + cycle[1:idx] + [lowest]
156 165
157 def find_cycles(imports): 166 def find_cycles(imports):
158 """Find cycles in an already-loaded import graph. 167 """Find cycles in an already-loaded import graph.
159 168
160 >>> imports = {'top.foo': ['bar', 'os.path', 'qux'], 169 >>> imports = {'top.foo': ['bar', 'os.path', 'qux'],
161 ... 'top.bar': ['baz', 'sys'], 170 ... 'top.bar': ['baz', 'sys'],
162 ... 'top.baz': ['foo'], 171 ... 'top.baz': ['foo'],
163 ... 'top.qux': ['foo']} 172 ... 'top.qux': ['foo']}
164 >>> print '\\n'.join(sorted(find_cycles(imports))) 173 >>> print '\\n'.join(sorted(find_cycles(imports)))
165 top.bar -> top.baz -> top.foo -> top.bar 174 top.bar -> top.baz -> top.foo -> top.bar -> top.bar
166 top.foo -> top.qux -> top.foo 175 top.foo -> top.qux -> top.foo -> top.foo
167 """ 176 """
168 cycles = {} 177 cycles = {}
169 for mod in sorted(imports.iterkeys()): 178 for mod in sorted(imports.iterkeys()):
170 try: 179 try:
171 check_one_mod(mod, imports, ignore=cycles) 180 check_one_mod(mod, imports, ignore=cycles)