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