Mercurial > cpython-lru_cache-weakref
annotate Lib/dircmp.py @ 4566:6403c94de50d legacy-trunk
Added safeguard against failure in __del__.
| author | Guido van Rossum <guido@python.org> |
|---|---|
| date | Wed, 27 Nov 1996 19:39:58 +0000 |
| parents | 1d06b1499eb9 |
| children | e34991022571 |
| rev | line source |
|---|---|
| 5 | 1 # Module 'dirmp' |
| 2 # | |
| 3 # Defines a class to build directory diff tools on. | |
| 4 | |
| 771 | 5 import os |
| 5 | 6 |
| 7 import dircache | |
| 8 import cmpcache | |
| 9 import statcache | |
|
21
961696ef3ab7
Use 'stat' module instead of hardcoding information from <sys/stat.h>.
Guido van Rossum <guido@python.org>
parents:
5
diff
changeset
|
10 from stat import * |
| 5 | 11 |
| 12 # Directory comparison class. | |
| 13 # | |
| 522 | 14 class dircmp: |
| 5 | 15 # |
|
1110
1d06b1499eb9
* Got entirely rid of path.py.
Guido van Rossum <guido@python.org>
parents:
771
diff
changeset
|
16 def new(self, a, b): # Initialize |
|
1d06b1499eb9
* Got entirely rid of path.py.
Guido van Rossum <guido@python.org>
parents:
771
diff
changeset
|
17 self.a = a |
|
1d06b1499eb9
* Got entirely rid of path.py.
Guido van Rossum <guido@python.org>
parents:
771
diff
changeset
|
18 self.b = b |
|
1d06b1499eb9
* Got entirely rid of path.py.
Guido van Rossum <guido@python.org>
parents:
771
diff
changeset
|
19 # Properties that caller may change before calling self.run(): |
|
1d06b1499eb9
* Got entirely rid of path.py.
Guido van Rossum <guido@python.org>
parents:
771
diff
changeset
|
20 self.hide = [os.curdir, os.pardir] # Names never to be shown |
|
1d06b1499eb9
* Got entirely rid of path.py.
Guido van Rossum <guido@python.org>
parents:
771
diff
changeset
|
21 self.ignore = ['RCS', 'tags'] # Names ignored in comparison |
| 5 | 22 # |
|
1110
1d06b1499eb9
* Got entirely rid of path.py.
Guido van Rossum <guido@python.org>
parents:
771
diff
changeset
|
23 return self |
| 5 | 24 # |
|
1110
1d06b1499eb9
* Got entirely rid of path.py.
Guido van Rossum <guido@python.org>
parents:
771
diff
changeset
|
25 def run(self): # Compare everything except common subdirectories |
|
1d06b1499eb9
* Got entirely rid of path.py.
Guido van Rossum <guido@python.org>
parents:
771
diff
changeset
|
26 self.a_list = filter(dircache.listdir(self.a), self.hide) |
|
1d06b1499eb9
* Got entirely rid of path.py.
Guido van Rossum <guido@python.org>
parents:
771
diff
changeset
|
27 self.b_list = filter(dircache.listdir(self.b), self.hide) |
|
1d06b1499eb9
* Got entirely rid of path.py.
Guido van Rossum <guido@python.org>
parents:
771
diff
changeset
|
28 self.a_list.sort() |
|
1d06b1499eb9
* Got entirely rid of path.py.
Guido van Rossum <guido@python.org>
parents:
771
diff
changeset
|
29 self.b_list.sort() |
|
1d06b1499eb9
* Got entirely rid of path.py.
Guido van Rossum <guido@python.org>
parents:
771
diff
changeset
|
30 self.phase1() |
|
1d06b1499eb9
* Got entirely rid of path.py.
Guido van Rossum <guido@python.org>
parents:
771
diff
changeset
|
31 self.phase2() |
|
1d06b1499eb9
* Got entirely rid of path.py.
Guido van Rossum <guido@python.org>
parents:
771
diff
changeset
|
32 self.phase3() |
| 5 | 33 # |
|
1110
1d06b1499eb9
* Got entirely rid of path.py.
Guido van Rossum <guido@python.org>
parents:
771
diff
changeset
|
34 def phase1(self): # Compute common names |
|
1d06b1499eb9
* Got entirely rid of path.py.
Guido van Rossum <guido@python.org>
parents:
771
diff
changeset
|
35 self.a_only = [] |
|
1d06b1499eb9
* Got entirely rid of path.py.
Guido van Rossum <guido@python.org>
parents:
771
diff
changeset
|
36 self.common = [] |
|
1d06b1499eb9
* Got entirely rid of path.py.
Guido van Rossum <guido@python.org>
parents:
771
diff
changeset
|
37 for x in self.a_list: |
|
1d06b1499eb9
* Got entirely rid of path.py.
Guido van Rossum <guido@python.org>
parents:
771
diff
changeset
|
38 if x in self.b_list: |
|
1d06b1499eb9
* Got entirely rid of path.py.
Guido van Rossum <guido@python.org>
parents:
771
diff
changeset
|
39 self.common.append(x) |
| 5 | 40 else: |
|
1110
1d06b1499eb9
* Got entirely rid of path.py.
Guido van Rossum <guido@python.org>
parents:
771
diff
changeset
|
41 self.a_only.append(x) |
| 5 | 42 # |
|
1110
1d06b1499eb9
* Got entirely rid of path.py.
Guido van Rossum <guido@python.org>
parents:
771
diff
changeset
|
43 self.b_only = [] |
|
1d06b1499eb9
* Got entirely rid of path.py.
Guido van Rossum <guido@python.org>
parents:
771
diff
changeset
|
44 for x in self.b_list: |
|
1d06b1499eb9
* Got entirely rid of path.py.
Guido van Rossum <guido@python.org>
parents:
771
diff
changeset
|
45 if x not in self.common: |
|
1d06b1499eb9
* Got entirely rid of path.py.
Guido van Rossum <guido@python.org>
parents:
771
diff
changeset
|
46 self.b_only.append(x) |
| 5 | 47 # |
|
1110
1d06b1499eb9
* Got entirely rid of path.py.
Guido van Rossum <guido@python.org>
parents:
771
diff
changeset
|
48 def phase2(self): # Distinguish files, directories, funnies |
|
1d06b1499eb9
* Got entirely rid of path.py.
Guido van Rossum <guido@python.org>
parents:
771
diff
changeset
|
49 self.common_dirs = [] |
|
1d06b1499eb9
* Got entirely rid of path.py.
Guido van Rossum <guido@python.org>
parents:
771
diff
changeset
|
50 self.common_files = [] |
|
1d06b1499eb9
* Got entirely rid of path.py.
Guido van Rossum <guido@python.org>
parents:
771
diff
changeset
|
51 self.common_funny = [] |
| 5 | 52 # |
|
1110
1d06b1499eb9
* Got entirely rid of path.py.
Guido van Rossum <guido@python.org>
parents:
771
diff
changeset
|
53 for x in self.common: |
|
1d06b1499eb9
* Got entirely rid of path.py.
Guido van Rossum <guido@python.org>
parents:
771
diff
changeset
|
54 a_path = os.path.join(self.a, x) |
|
1d06b1499eb9
* Got entirely rid of path.py.
Guido van Rossum <guido@python.org>
parents:
771
diff
changeset
|
55 b_path = os.path.join(self.b, x) |
| 5 | 56 # |
| 57 ok = 1 | |
| 58 try: | |
| 59 a_stat = statcache.stat(a_path) | |
| 771 | 60 except os.error, why: |
| 5 | 61 # print 'Can\'t stat', a_path, ':', why[1] |
| 62 ok = 0 | |
| 63 try: | |
| 64 b_stat = statcache.stat(b_path) | |
| 771 | 65 except os.error, why: |
| 5 | 66 # print 'Can\'t stat', b_path, ':', why[1] |
| 67 ok = 0 | |
| 68 # | |
| 69 if ok: | |
|
21
961696ef3ab7
Use 'stat' module instead of hardcoding information from <sys/stat.h>.
Guido van Rossum <guido@python.org>
parents:
5
diff
changeset
|
70 a_type = S_IFMT(a_stat[ST_MODE]) |
|
961696ef3ab7
Use 'stat' module instead of hardcoding information from <sys/stat.h>.
Guido van Rossum <guido@python.org>
parents:
5
diff
changeset
|
71 b_type = S_IFMT(b_stat[ST_MODE]) |
| 5 | 72 if a_type <> b_type: |
|
1110
1d06b1499eb9
* Got entirely rid of path.py.
Guido van Rossum <guido@python.org>
parents:
771
diff
changeset
|
73 self.common_funny.append(x) |
|
21
961696ef3ab7
Use 'stat' module instead of hardcoding information from <sys/stat.h>.
Guido van Rossum <guido@python.org>
parents:
5
diff
changeset
|
74 elif S_ISDIR(a_type): |
|
1110
1d06b1499eb9
* Got entirely rid of path.py.
Guido van Rossum <guido@python.org>
parents:
771
diff
changeset
|
75 self.common_dirs.append(x) |
|
21
961696ef3ab7
Use 'stat' module instead of hardcoding information from <sys/stat.h>.
Guido van Rossum <guido@python.org>
parents:
5
diff
changeset
|
76 elif S_ISREG(a_type): |
|
1110
1d06b1499eb9
* Got entirely rid of path.py.
Guido van Rossum <guido@python.org>
parents:
771
diff
changeset
|
77 self.common_files.append(x) |
| 5 | 78 else: |
|
1110
1d06b1499eb9
* Got entirely rid of path.py.
Guido van Rossum <guido@python.org>
parents:
771
diff
changeset
|
79 self.common_funny.append(x) |
| 5 | 80 else: |
|
1110
1d06b1499eb9
* Got entirely rid of path.py.
Guido van Rossum <guido@python.org>
parents:
771
diff
changeset
|
81 self.common_funny.append(x) |
| 5 | 82 # |
|
1110
1d06b1499eb9
* Got entirely rid of path.py.
Guido van Rossum <guido@python.org>
parents:
771
diff
changeset
|
83 def phase3(self): # Find out differences between common files |
|
1d06b1499eb9
* Got entirely rid of path.py.
Guido van Rossum <guido@python.org>
parents:
771
diff
changeset
|
84 xx = cmpfiles(self.a, self.b, self.common_files) |
|
1d06b1499eb9
* Got entirely rid of path.py.
Guido van Rossum <guido@python.org>
parents:
771
diff
changeset
|
85 self.same_files, self.diff_files, self.funny_files = xx |
| 5 | 86 # |
|
1110
1d06b1499eb9
* Got entirely rid of path.py.
Guido van Rossum <guido@python.org>
parents:
771
diff
changeset
|
87 def phase4(self): # Find out differences between common subdirectories |
| 5 | 88 # A new dircmp object is created for each common subdirectory, |
| 89 # these are stored in a dictionary indexed by filename. | |
| 90 # The hide and ignore properties are inherited from the parent | |
|
1110
1d06b1499eb9
* Got entirely rid of path.py.
Guido van Rossum <guido@python.org>
parents:
771
diff
changeset
|
91 self.subdirs = {} |
|
1d06b1499eb9
* Got entirely rid of path.py.
Guido van Rossum <guido@python.org>
parents:
771
diff
changeset
|
92 for x in self.common_dirs: |
|
1d06b1499eb9
* Got entirely rid of path.py.
Guido van Rossum <guido@python.org>
parents:
771
diff
changeset
|
93 a_x = os.path.join(self.a, x) |
|
1d06b1499eb9
* Got entirely rid of path.py.
Guido van Rossum <guido@python.org>
parents:
771
diff
changeset
|
94 b_x = os.path.join(self.b, x) |
|
1d06b1499eb9
* Got entirely rid of path.py.
Guido van Rossum <guido@python.org>
parents:
771
diff
changeset
|
95 self.subdirs[x] = newdd = dircmp().new(a_x, b_x) |
|
1d06b1499eb9
* Got entirely rid of path.py.
Guido van Rossum <guido@python.org>
parents:
771
diff
changeset
|
96 newdd.hide = self.hide |
|
1d06b1499eb9
* Got entirely rid of path.py.
Guido van Rossum <guido@python.org>
parents:
771
diff
changeset
|
97 newdd.ignore = self.ignore |
| 5 | 98 newdd.run() |
| 99 # | |
|
1110
1d06b1499eb9
* Got entirely rid of path.py.
Guido van Rossum <guido@python.org>
parents:
771
diff
changeset
|
100 def phase4_closure(self): # Recursively call phase4() on subdirectories |
|
1d06b1499eb9
* Got entirely rid of path.py.
Guido van Rossum <guido@python.org>
parents:
771
diff
changeset
|
101 self.phase4() |
|
1d06b1499eb9
* Got entirely rid of path.py.
Guido van Rossum <guido@python.org>
parents:
771
diff
changeset
|
102 for x in self.subdirs.keys(): |
|
1d06b1499eb9
* Got entirely rid of path.py.
Guido van Rossum <guido@python.org>
parents:
771
diff
changeset
|
103 self.subdirs[x].phase4_closure() |
| 5 | 104 # |
|
1110
1d06b1499eb9
* Got entirely rid of path.py.
Guido van Rossum <guido@python.org>
parents:
771
diff
changeset
|
105 def report(self): # Print a report on the differences between a and b |
| 5 | 106 # Assume that phases 1 to 3 have been executed |
| 107 # Output format is purposely lousy | |
|
1110
1d06b1499eb9
* Got entirely rid of path.py.
Guido van Rossum <guido@python.org>
parents:
771
diff
changeset
|
108 print 'diff', self.a, self.b |
|
1d06b1499eb9
* Got entirely rid of path.py.
Guido van Rossum <guido@python.org>
parents:
771
diff
changeset
|
109 if self.a_only: |
|
1d06b1499eb9
* Got entirely rid of path.py.
Guido van Rossum <guido@python.org>
parents:
771
diff
changeset
|
110 print 'Only in', self.a, ':', self.a_only |
|
1d06b1499eb9
* Got entirely rid of path.py.
Guido van Rossum <guido@python.org>
parents:
771
diff
changeset
|
111 if self.b_only: |
|
1d06b1499eb9
* Got entirely rid of path.py.
Guido van Rossum <guido@python.org>
parents:
771
diff
changeset
|
112 print 'Only in', self.b, ':', self.b_only |
|
1d06b1499eb9
* Got entirely rid of path.py.
Guido van Rossum <guido@python.org>
parents:
771
diff
changeset
|
113 if self.same_files: |
|
1d06b1499eb9
* Got entirely rid of path.py.
Guido van Rossum <guido@python.org>
parents:
771
diff
changeset
|
114 print 'Identical files :', self.same_files |
|
1d06b1499eb9
* Got entirely rid of path.py.
Guido van Rossum <guido@python.org>
parents:
771
diff
changeset
|
115 if self.diff_files: |
|
1d06b1499eb9
* Got entirely rid of path.py.
Guido van Rossum <guido@python.org>
parents:
771
diff
changeset
|
116 print 'Differing files :', self.diff_files |
|
1d06b1499eb9
* Got entirely rid of path.py.
Guido van Rossum <guido@python.org>
parents:
771
diff
changeset
|
117 if self.funny_files: |
|
1d06b1499eb9
* Got entirely rid of path.py.
Guido van Rossum <guido@python.org>
parents:
771
diff
changeset
|
118 print 'Trouble with common files :', self.funny_files |
|
1d06b1499eb9
* Got entirely rid of path.py.
Guido van Rossum <guido@python.org>
parents:
771
diff
changeset
|
119 if self.common_dirs: |
|
1d06b1499eb9
* Got entirely rid of path.py.
Guido van Rossum <guido@python.org>
parents:
771
diff
changeset
|
120 print 'Common subdirectories :', self.common_dirs |
|
1d06b1499eb9
* Got entirely rid of path.py.
Guido van Rossum <guido@python.org>
parents:
771
diff
changeset
|
121 if self.common_funny: |
|
1d06b1499eb9
* Got entirely rid of path.py.
Guido van Rossum <guido@python.org>
parents:
771
diff
changeset
|
122 print 'Common funny cases :', self.common_funny |
| 5 | 123 # |
|
1110
1d06b1499eb9
* Got entirely rid of path.py.
Guido van Rossum <guido@python.org>
parents:
771
diff
changeset
|
124 def report_closure(self): # Print reports on self and on subdirs |
| 5 | 125 # If phase 4 hasn't been done, no subdir reports are printed |
|
1110
1d06b1499eb9
* Got entirely rid of path.py.
Guido van Rossum <guido@python.org>
parents:
771
diff
changeset
|
126 self.report() |
| 5 | 127 try: |
|
1110
1d06b1499eb9
* Got entirely rid of path.py.
Guido van Rossum <guido@python.org>
parents:
771
diff
changeset
|
128 x = self.subdirs |
| 522 | 129 except AttributeError: |
| 5 | 130 return # No subdirectories computed |
|
1110
1d06b1499eb9
* Got entirely rid of path.py.
Guido van Rossum <guido@python.org>
parents:
771
diff
changeset
|
131 for x in self.subdirs.keys(): |
| 5 | 132 print |
|
1110
1d06b1499eb9
* Got entirely rid of path.py.
Guido van Rossum <guido@python.org>
parents:
771
diff
changeset
|
133 self.subdirs[x].report_closure() |
| 5 | 134 # |
|
1110
1d06b1499eb9
* Got entirely rid of path.py.
Guido van Rossum <guido@python.org>
parents:
771
diff
changeset
|
135 def report_phase4_closure(self): # Report and do phase 4 recursively |
|
1d06b1499eb9
* Got entirely rid of path.py.
Guido van Rossum <guido@python.org>
parents:
771
diff
changeset
|
136 self.report() |
|
1d06b1499eb9
* Got entirely rid of path.py.
Guido van Rossum <guido@python.org>
parents:
771
diff
changeset
|
137 self.phase4() |
|
1d06b1499eb9
* Got entirely rid of path.py.
Guido van Rossum <guido@python.org>
parents:
771
diff
changeset
|
138 for x in self.subdirs.keys(): |
| 5 | 139 print |
|
1110
1d06b1499eb9
* Got entirely rid of path.py.
Guido van Rossum <guido@python.org>
parents:
771
diff
changeset
|
140 self.subdirs[x].report_phase4_closure() |
| 5 | 141 |
| 142 | |
| 143 # Compare common files in two directories. | |
| 144 # Return: | |
| 145 # - files that compare equal | |
| 146 # - files that compare different | |
| 147 # - funny cases (can't stat etc.) | |
| 148 # | |
| 149 def cmpfiles(a, b, common): | |
| 150 res = ([], [], []) | |
| 151 for x in common: | |
| 771 | 152 res[cmp(os.path.join(a, x), os.path.join(b, x))].append(x) |
| 5 | 153 return res |
| 154 | |
| 155 | |
| 156 # Compare two files. | |
| 157 # Return: | |
| 158 # 0 for equal | |
| 159 # 1 for different | |
| 160 # 2 for funny cases (can't stat, etc.) | |
| 161 # | |
| 162 def cmp(a, b): | |
| 163 try: | |
| 164 if cmpcache.cmp(a, b): return 0 | |
| 165 return 1 | |
| 771 | 166 except os.error: |
| 5 | 167 return 2 |
| 168 | |
| 169 | |
| 170 # Remove a list item. | |
| 171 # NB: This modifies the list argument. | |
| 172 # | |
| 173 def remove(list, item): | |
| 174 for i in range(len(list)): | |
| 559 | 175 if list[i] == item: |
| 5 | 176 del list[i] |
| 177 break | |
| 178 | |
| 179 | |
| 180 # Return a copy with items that occur in skip removed. | |
| 181 # | |
| 182 def filter(list, skip): | |
| 183 result = [] | |
| 184 for item in list: | |
| 185 if item not in skip: result.append(item) | |
| 186 return result | |
| 187 | |
| 188 | |
| 189 # Demonstration and testing. | |
| 190 # | |
| 191 def demo(): | |
| 192 import sys | |
| 193 import getopt | |
| 194 options, args = getopt.getopt(sys.argv[1:], 'r') | |
| 195 if len(args) <> 2: raise getopt.error, 'need exactly two args' | |
| 196 dd = dircmp().new(args[0], args[1]) | |
| 197 dd.run() | |
| 198 if ('-r', '') in options: | |
| 199 dd.report_phase4_closure() | |
| 200 else: | |
| 201 dd.report() | |
| 202 | |
| 203 # demo() |
