1:mod:`filecmp` --- File and Directory Comparisons 2================================================= 3 4.. module:: filecmp 5 :synopsis: Compare files efficiently. 6.. sectionauthor:: Moshe Zadka <moshez@zadka.site.co.il> 7 8**Source code:** :source:`Lib/filecmp.py` 9 10-------------- 11 12The :mod:`filecmp` module defines functions to compare files and directories, 13with various optional time/correctness trade-offs. For comparing files, 14see also the :mod:`difflib` module. 15 16The :mod:`filecmp` module defines the following functions: 17 18 19.. function:: cmp(f1, f2[, shallow]) 20 21 Compare the files named *f1* and *f2*, returning ``True`` if they seem equal, 22 ``False`` otherwise. 23 24 Unless *shallow* is given and is false, files with identical :func:`os.stat` 25 signatures are taken to be equal. 26 27 Files that were compared using this function will not be compared again unless 28 their :func:`os.stat` signature changes. 29 30 Note that no external programs are called from this function, giving it 31 portability and efficiency. 32 33 34.. function:: cmpfiles(dir1, dir2, common[, shallow]) 35 36 Compare the files in the two directories *dir1* and *dir2* whose names are 37 given by *common*. 38 39 Returns three lists of file names: *match*, *mismatch*, 40 *errors*. *match* contains the list of files that match, *mismatch* contains 41 the names of those that don't, and *errors* lists the names of files which 42 could not be compared. Files are listed in *errors* if they don't exist in 43 one of the directories, the user lacks permission to read them or if the 44 comparison could not be done for some other reason. 45 46 The *shallow* parameter has the same meaning and default value as for 47 :func:`filecmp.cmp`. 48 49 For example, ``cmpfiles('a', 'b', ['c', 'd/e'])`` will compare ``a/c`` with 50 ``b/c`` and ``a/d/e`` with ``b/d/e``. ``'c'`` and ``'d/e'`` will each be in 51 one of the three returned lists. 52 53 54Example:: 55 56 >>> import filecmp 57 >>> filecmp.cmp('undoc.rst', 'undoc.rst') # doctest: +SKIP 58 True 59 >>> filecmp.cmp('undoc.rst', 'index.rst') # doctest: +SKIP 60 False 61 62 63.. _dircmp-objects: 64 65The :class:`dircmp` class 66------------------------- 67 68:class:`dircmp` instances are built using this constructor: 69 70 71.. class:: dircmp(a, b[, ignore[, hide]]) 72 73 Construct a new directory comparison object, to compare the directories *a* and 74 *b*. *ignore* is a list of names to ignore, and defaults to ``['RCS', 'CVS', 75 'tags']``. *hide* is a list of names to hide, and defaults to ``[os.curdir, 76 os.pardir]``. 77 78 The :class:`dircmp` class compares files by doing *shallow* comparisons 79 as described for :func:`filecmp.cmp`. 80 81 The :class:`dircmp` class provides the following methods: 82 83 84 .. method:: report() 85 86 Print (to ``sys.stdout``) a comparison between *a* and *b*. 87 88 89 .. method:: report_partial_closure() 90 91 Print a comparison between *a* and *b* and common immediate 92 subdirectories. 93 94 95 .. method:: report_full_closure() 96 97 Print a comparison between *a* and *b* and common subdirectories 98 (recursively). 99 100 The :class:`dircmp` class offers a number of interesting attributes that may be 101 used to get various bits of information about the directory trees being 102 compared. 103 104 Note that via :meth:`__getattr__` hooks, all attributes are computed lazily, 105 so there is no speed penalty if only those attributes which are lightweight 106 to compute are used. 107 108 109 .. attribute:: left 110 111 The directory *a*. 112 113 114 .. attribute:: right 115 116 The directory *b*. 117 118 119 .. attribute:: left_list 120 121 Files and subdirectories in *a*, filtered by *hide* and *ignore*. 122 123 124 .. attribute:: right_list 125 126 Files and subdirectories in *b*, filtered by *hide* and *ignore*. 127 128 129 .. attribute:: common 130 131 Files and subdirectories in both *a* and *b*. 132 133 134 .. attribute:: left_only 135 136 Files and subdirectories only in *a*. 137 138 139 .. attribute:: right_only 140 141 Files and subdirectories only in *b*. 142 143 144 .. attribute:: common_dirs 145 146 Subdirectories in both *a* and *b*. 147 148 149 .. attribute:: common_files 150 151 Files in both *a* and *b* 152 153 154 .. attribute:: common_funny 155 156 Names in both *a* and *b*, such that the type differs between the 157 directories, or names for which :func:`os.stat` reports an error. 158 159 160 .. attribute:: same_files 161 162 Files which are identical in both *a* and *b*, using the class's 163 file comparison operator. 164 165 166 .. attribute:: diff_files 167 168 Files which are in both *a* and *b*, whose contents differ according 169 to the class's file comparison operator. 170 171 172 .. attribute:: funny_files 173 174 Files which are in both *a* and *b*, but could not be compared. 175 176 177 .. attribute:: subdirs 178 179 A dictionary mapping names in :attr:`common_dirs` to :class:`dircmp` objects. 180 181 182Here is a simplified example of using the ``subdirs`` attribute to search 183recursively through two directories to show common different files:: 184 185 >>> from filecmp import dircmp 186 >>> def print_diff_files(dcmp): 187 ... for name in dcmp.diff_files: 188 ... print "diff_file %s found in %s and %s" % (name, dcmp.left, 189 ... dcmp.right) 190 ... for sub_dcmp in dcmp.subdirs.values(): 191 ... print_diff_files(sub_dcmp) 192 ... 193 >>> dcmp = dircmp('dir1', 'dir2') # doctest: +SKIP 194 >>> print_diff_files(dcmp) # doctest: +SKIP 195 196