[2] | 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 |
|
---|
[391] | 8 | **Source code:** :source:`Lib/filecmp.py`
|
---|
[2] | 9 |
|
---|
[391] | 10 | --------------
|
---|
| 11 |
|
---|
[2] | 12 | The :mod:`filecmp` module defines functions to compare files and directories,
|
---|
| 13 | with various optional time/correctness trade-offs. For comparing files,
|
---|
| 14 | see also the :mod:`difflib` module.
|
---|
| 15 |
|
---|
| 16 | The :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 |
|
---|
| 54 | Example::
|
---|
| 55 |
|
---|
| 56 | >>> import filecmp
|
---|
[391] | 57 | >>> filecmp.cmp('undoc.rst', 'undoc.rst') # doctest: +SKIP
|
---|
[2] | 58 | True
|
---|
[391] | 59 | >>> filecmp.cmp('undoc.rst', 'index.rst') # doctest: +SKIP
|
---|
[2] | 60 | False
|
---|
| 61 |
|
---|
| 62 |
|
---|
| 63 | .. _dircmp-objects:
|
---|
| 64 |
|
---|
| 65 | The :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 |
|
---|
[391] | 78 | The :class:`dircmp` class compares files by doing *shallow* comparisons
|
---|
| 79 | as described for :func:`filecmp.cmp`.
|
---|
| 80 |
|
---|
[2] | 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 |
|
---|
[391] | 100 | The :class:`dircmp` class offers a number of interesting attributes that may be
|
---|
[2] | 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 |
|
---|
[391] | 109 | .. attribute:: left
|
---|
| 110 |
|
---|
| 111 | The directory *a*.
|
---|
| 112 |
|
---|
| 113 |
|
---|
| 114 | .. attribute:: right
|
---|
| 115 |
|
---|
| 116 | The directory *b*.
|
---|
| 117 |
|
---|
| 118 |
|
---|
[2] | 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 |
|
---|
[391] | 162 | Files which are identical in both *a* and *b*, using the class's
|
---|
| 163 | file comparison operator.
|
---|
[2] | 164 |
|
---|
| 165 |
|
---|
| 166 | .. attribute:: diff_files
|
---|
| 167 |
|
---|
[391] | 168 | Files which are in both *a* and *b*, whose contents differ according
|
---|
| 169 | to the class's file comparison operator.
|
---|
[2] | 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 |
|
---|
[391] | 181 |
|
---|
| 182 | Here is a simplified example of using the ``subdirs`` attribute to search
|
---|
| 183 | recursively 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 |
|
---|