[PATCH 3 of 7] import-checker: try a little harder to show fewer cycles

Augie Fackler raf at durin42.com
Sun Nov 17 11:21:25 CST 2013


# HG changeset patch
# User Augie Fackler <raf at durin42.com>
# Date 1383795950 18000
#      Wed Nov 06 22:45:50 2013 -0500
# Node ID dcfea9369d456f676ce2eb80cd60d17d031c04e5
# Parent  8b6007b0ecd735b917d39bdeab1b2ec028fd3992
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.

diff --git a/contrib/import-checker.py b/contrib/import-checker.py
--- a/contrib/import-checker.py
+++ b/contrib/import-checker.py
@@ -137,6 +137,15 @@
             continue
         check_one_mod(i, imports, path=path, ignore=ignore)
 
+def rotatecycle(cycle):
+    """arrange a cycle so that the lexicographically first module listed first
+
+    >>> rotatecycle(['foo', 'bar', 'foo'])
+    ['bar', 'foo', 'bar']
+    """
+    lowest = min(cycle)
+    idx = cycle.index(lowest)
+    return cycle[idx:] + cycle[1:idx] + [lowest]
 
 def find_cycles(imports):
     """Find cycles in an already-loaded import graph.
@@ -146,8 +155,8 @@
     ...            'top.baz': ['foo'],
     ...            'top.qux': ['foo']}
     >>> print '\\n'.join(sorted(find_cycles(imports)))
-    top.bar -> top.baz -> top.foo -> top.bar
-    top.foo -> top.qux -> top.foo
+    top.bar -> top.baz -> top.foo -> top.bar -> top.bar
+    top.foo -> top.qux -> top.foo -> top.foo
     """
     cycles = {}
     seen_in_cycle = set()
@@ -156,7 +165,7 @@
             check_one_mod(mod, imports, ignore=cycles)
         except CircularImport, e:
             cycle = e.args[0]
-            cycles[cyclekey(cycle)] = ' -> '.join(cycle)
+            cycles[cyclekey(cycle)] = ' -> '.join(rotatecycle(cycle))
             seen_in_cycle |= set(cycle)
     return cycles.values()
 


More information about the Mercurial-devel mailing list