blob: 9a5f78a50dedc6fb73aecefad084b245c0bf24f5 [file] [log] [blame]
Guido van Rossume7b146f2000-02-04 15:28:42 +00001"""Utility functions for copying files and directory trees.
Guido van Rossum9d0a3df1997-04-29 14:45:19 +00002
Guido van Rossum959fa011999-08-18 20:03:17 +00003XXX The functions here don't copy the resource fork or other metadata on Mac.
Guido van Rossum9d0a3df1997-04-29 14:45:19 +00004
5"""
Guido van Rossumc6360141990-10-13 19:23:40 +00006
Guido van Rossumc96207a1992-03-31 18:55:40 +00007import os
Guido van Rossum83c03e21999-02-23 23:07:51 +00008import sys
Guido van Rossum9d0a3df1997-04-29 14:45:19 +00009import stat
Brett Cannon1c3fa182004-06-19 21:11:35 +000010from os.path import abspath
Georg Brandl2ee470f2008-07-16 12:55:28 +000011import fnmatch
Guido van Rossumc6360141990-10-13 19:23:40 +000012
Skip Montanaro0de65802001-02-15 22:15:14 +000013__all__ = ["copyfileobj","copyfile","copymode","copystat","copy","copy2",
Raymond Hettinger2b9bfb32002-10-30 05:44:50 +000014 "copytree","move","rmtree","Error"]
Martin v. Löwise9ce0b02002-10-07 13:23:24 +000015
Neal Norwitz4ce69a52005-09-01 00:45:28 +000016class Error(EnvironmentError):
Martin v. Löwise9ce0b02002-10-07 13:23:24 +000017 pass
Guido van Rossumc6360141990-10-13 19:23:40 +000018
Georg Brandl6aa2d1f2008-08-12 08:35:52 +000019try:
20 WindowsError
21except NameError:
22 WindowsError = None
23
Greg Stein42bb8b32000-07-12 09:55:30 +000024def copyfileobj(fsrc, fdst, length=16*1024):
25 """copy data from file-like object fsrc to file-like object fdst"""
26 while 1:
27 buf = fsrc.read(length)
28 if not buf:
29 break
30 fdst.write(buf)
31
Johannes Gijsbers46f14592004-08-14 13:30:02 +000032def _samefile(src, dst):
33 # Macintosh, Unix.
34 if hasattr(os.path,'samefile'):
Johannes Gijsbersf9a098e2004-08-14 14:51:01 +000035 try:
36 return os.path.samefile(src, dst)
37 except OSError:
38 return False
Johannes Gijsbers46f14592004-08-14 13:30:02 +000039
40 # All other platforms: check for same pathname.
41 return (os.path.normcase(os.path.abspath(src)) ==
42 os.path.normcase(os.path.abspath(dst)))
Tim Peters495ad3c2001-01-15 01:36:40 +000043
Guido van Rossumc6360141990-10-13 19:23:40 +000044def copyfile(src, dst):
Guido van Rossum9d0a3df1997-04-29 14:45:19 +000045 """Copy data from src to dst"""
Johannes Gijsbers46f14592004-08-14 13:30:02 +000046 if _samefile(src, dst):
Collin Winterce36ad82007-08-30 01:19:48 +000047 raise Error("`%s` and `%s` are the same file" % (src, dst))
Johannes Gijsbers46f14592004-08-14 13:30:02 +000048
Guido van Rossuma2baf461997-04-29 14:06:46 +000049 fsrc = None
50 fdst = None
51 try:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +000052 fsrc = open(src, 'rb')
53 fdst = open(dst, 'wb')
Greg Stein42bb8b32000-07-12 09:55:30 +000054 copyfileobj(fsrc, fdst)
Guido van Rossuma2baf461997-04-29 14:06:46 +000055 finally:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +000056 if fdst:
57 fdst.close()
58 if fsrc:
59 fsrc.close()
Guido van Rossumc6360141990-10-13 19:23:40 +000060
Guido van Rossumc6360141990-10-13 19:23:40 +000061def copymode(src, dst):
Guido van Rossum9d0a3df1997-04-29 14:45:19 +000062 """Copy mode bits from src to dst"""
Tim Peters0c947242001-01-21 20:00:00 +000063 if hasattr(os, 'chmod'):
64 st = os.stat(src)
Walter Dörwald294bbf32002-06-06 09:48:13 +000065 mode = stat.S_IMODE(st.st_mode)
Tim Peters0c947242001-01-21 20:00:00 +000066 os.chmod(dst, mode)
Guido van Rossumc6360141990-10-13 19:23:40 +000067
Guido van Rossumc6360141990-10-13 19:23:40 +000068def copystat(src, dst):
Thomas Wouterscf297e42007-02-23 15:07:44 +000069 """Copy all stat info (mode bits, atime, mtime, flags) from src to dst"""
Guido van Rossuma2baf461997-04-29 14:06:46 +000070 st = os.stat(src)
Walter Dörwald294bbf32002-06-06 09:48:13 +000071 mode = stat.S_IMODE(st.st_mode)
Tim Peters0c947242001-01-21 20:00:00 +000072 if hasattr(os, 'utime'):
Walter Dörwald294bbf32002-06-06 09:48:13 +000073 os.utime(dst, (st.st_atime, st.st_mtime))
Tim Peters0c947242001-01-21 20:00:00 +000074 if hasattr(os, 'chmod'):
75 os.chmod(dst, mode)
Thomas Wouterscf297e42007-02-23 15:07:44 +000076 if hasattr(os, 'chflags') and hasattr(st, 'st_flags'):
77 os.chflags(dst, st.st_flags)
Guido van Rossumc6360141990-10-13 19:23:40 +000078
Guido van Rossum9d0a3df1997-04-29 14:45:19 +000079
Guido van Rossumc6360141990-10-13 19:23:40 +000080def copy(src, dst):
Guido van Rossum9d0a3df1997-04-29 14:45:19 +000081 """Copy data and mode bits ("cp src dst").
Tim Peters495ad3c2001-01-15 01:36:40 +000082
Guido van Rossum9d0a3df1997-04-29 14:45:19 +000083 The destination may be a directory.
84
85 """
Guido van Rossuma2baf461997-04-29 14:06:46 +000086 if os.path.isdir(dst):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +000087 dst = os.path.join(dst, os.path.basename(src))
Guido van Rossuma2baf461997-04-29 14:06:46 +000088 copyfile(src, dst)
89 copymode(src, dst)
Guido van Rossumc6360141990-10-13 19:23:40 +000090
Guido van Rossumc6360141990-10-13 19:23:40 +000091def copy2(src, dst):
Guido van Rossum9d0a3df1997-04-29 14:45:19 +000092 """Copy data and all stat info ("cp -p src dst").
93
94 The destination may be a directory.
95
96 """
Guido van Rossuma2baf461997-04-29 14:06:46 +000097 if os.path.isdir(dst):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +000098 dst = os.path.join(dst, os.path.basename(src))
Guido van Rossuma2baf461997-04-29 14:06:46 +000099 copyfile(src, dst)
100 copystat(src, dst)
Guido van Rossumc6360141990-10-13 19:23:40 +0000101
Georg Brandl2ee470f2008-07-16 12:55:28 +0000102def ignore_patterns(*patterns):
103 """Function that can be used as copytree() ignore parameter.
Guido van Rossum9d0a3df1997-04-29 14:45:19 +0000104
Georg Brandl2ee470f2008-07-16 12:55:28 +0000105 Patterns is a sequence of glob-style patterns
106 that are used to exclude files"""
107 def _ignore_patterns(path, names):
108 ignored_names = []
109 for pattern in patterns:
110 ignored_names.extend(fnmatch.filter(names, pattern))
111 return set(ignored_names)
112 return _ignore_patterns
113
114def copytree(src, dst, symlinks=False, ignore=None):
Guido van Rossum9d0a3df1997-04-29 14:45:19 +0000115 """Recursively copy a directory tree using copy2().
116
117 The destination directory must not already exist.
Neal Norwitza4c93b62003-02-23 21:36:32 +0000118 If exception(s) occur, an Error is raised with a list of reasons.
Guido van Rossum9d0a3df1997-04-29 14:45:19 +0000119
120 If the optional symlinks flag is true, symbolic links in the
121 source tree result in symbolic links in the destination tree; if
122 it is false, the contents of the files pointed to by symbolic
123 links are copied.
124
Georg Brandl2ee470f2008-07-16 12:55:28 +0000125 The optional ignore argument is a callable. If given, it
126 is called with the `src` parameter, which is the directory
127 being visited by copytree(), and `names` which is the list of
128 `src` contents, as returned by os.listdir():
129
130 callable(src, names) -> ignored_names
131
132 Since copytree() is called recursively, the callable will be
133 called once for each directory that is copied. It returns a
134 list of names relative to the `src` directory that should
135 not be copied.
136
Guido van Rossum9d0a3df1997-04-29 14:45:19 +0000137 XXX Consider this example code rather than the ultimate tool.
138
139 """
Guido van Rossuma2baf461997-04-29 14:06:46 +0000140 names = os.listdir(src)
Georg Brandl2ee470f2008-07-16 12:55:28 +0000141 if ignore is not None:
142 ignored_names = ignore(src, names)
143 else:
144 ignored_names = set()
145
Johannes Gijsberse4172ea2005-01-08 12:31:29 +0000146 os.makedirs(dst)
Martin v. Löwise9ce0b02002-10-07 13:23:24 +0000147 errors = []
Guido van Rossuma2baf461997-04-29 14:06:46 +0000148 for name in names:
Georg Brandl2ee470f2008-07-16 12:55:28 +0000149 if name in ignored_names:
150 continue
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000151 srcname = os.path.join(src, name)
152 dstname = os.path.join(dst, name)
153 try:
154 if symlinks and os.path.islink(srcname):
155 linkto = os.readlink(srcname)
156 os.symlink(linkto, dstname)
157 elif os.path.isdir(srcname):
Georg Brandl2ee470f2008-07-16 12:55:28 +0000158 copytree(srcname, dstname, symlinks, ignore)
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000159 else:
160 copy2(srcname, dstname)
161 # XXX What about devices, sockets etc.?
Guido van Rossumb940e112007-01-10 16:19:56 +0000162 except (IOError, os.error) as why:
Thomas Wouters477c8d52006-05-27 19:21:47 +0000163 errors.append((srcname, dstname, str(why)))
Georg Brandla1be88e2005-08-31 22:48:45 +0000164 # catch the Error from the recursive copytree so that we can
165 # continue with other files
Guido van Rossumb940e112007-01-10 16:19:56 +0000166 except Error as err:
Georg Brandla1be88e2005-08-31 22:48:45 +0000167 errors.extend(err.args[0])
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000168 try:
169 copystat(src, dst)
Guido van Rossumb940e112007-01-10 16:19:56 +0000170 except OSError as why:
Georg Brandl6aa2d1f2008-08-12 08:35:52 +0000171 if WindowsError is not None and isinstance(why, WindowsError):
172 # Copying file access times may fail on Windows
173 pass
174 else:
175 errors.extend((src, dst, str(why)))
Martin v. Löwise9ce0b02002-10-07 13:23:24 +0000176 if errors:
Collin Winterce36ad82007-08-30 01:19:48 +0000177 raise Error(errors)
Guido van Rossumd7673291998-02-06 21:38:09 +0000178
Barry Warsaw234d9a92003-01-24 17:36:15 +0000179def rmtree(path, ignore_errors=False, onerror=None):
Guido van Rossumd7673291998-02-06 21:38:09 +0000180 """Recursively delete a directory tree.
181
Johannes Gijsbersef5ffc42004-10-31 12:05:31 +0000182 If ignore_errors is set, errors are ignored; otherwise, if onerror
183 is set, it is called to handle the error with arguments (func,
184 path, exc_info) where func is os.listdir, os.remove, or os.rmdir;
185 path is the argument to that function that caused it to fail; and
186 exc_info is a tuple returned by sys.exc_info(). If ignore_errors
187 is false and onerror is None, an exception is raised.
188
Guido van Rossumd7673291998-02-06 21:38:09 +0000189 """
Johannes Gijsbersef5ffc42004-10-31 12:05:31 +0000190 if ignore_errors:
191 def onerror(*args):
Barry Warsaw234d9a92003-01-24 17:36:15 +0000192 pass
Johannes Gijsbersef5ffc42004-10-31 12:05:31 +0000193 elif onerror is None:
194 def onerror(*args):
195 raise
Christian Heimes9bd667a2008-01-20 15:14:11 +0000196 try:
197 if os.path.islink(path):
198 # symlinks to directories are forbidden, see bug #1669
199 raise OSError("Cannot call rmtree on a symbolic link")
200 except OSError:
201 onerror(os.path.islink, path, sys.exc_info())
202 # can't continue even if onerror hook returns
203 return
Johannes Gijsbersef5ffc42004-10-31 12:05:31 +0000204 names = []
205 try:
206 names = os.listdir(path)
Guido van Rossumb940e112007-01-10 16:19:56 +0000207 except os.error as err:
Johannes Gijsbersef5ffc42004-10-31 12:05:31 +0000208 onerror(os.listdir, path, sys.exc_info())
209 for name in names:
210 fullname = os.path.join(path, name)
211 try:
212 mode = os.lstat(fullname).st_mode
213 except os.error:
214 mode = 0
215 if stat.S_ISDIR(mode):
216 rmtree(fullname, ignore_errors, onerror)
Barry Warsaw234d9a92003-01-24 17:36:15 +0000217 else:
Johannes Gijsbersef5ffc42004-10-31 12:05:31 +0000218 try:
219 os.remove(fullname)
Guido van Rossumb940e112007-01-10 16:19:56 +0000220 except os.error as err:
Johannes Gijsbersef5ffc42004-10-31 12:05:31 +0000221 onerror(os.remove, fullname, sys.exc_info())
222 try:
223 os.rmdir(path)
224 except os.error:
225 onerror(os.rmdir, path, sys.exc_info())
Guido van Rossumd7673291998-02-06 21:38:09 +0000226
Martin v. Löwise9ce0b02002-10-07 13:23:24 +0000227
Christian Heimesada8c3b2008-03-18 18:26:33 +0000228def _basename(path):
229 # A basename() variant which first strips the trailing slash, if present.
230 # Thus we always get the last component of the path, even for directories.
231 return os.path.basename(path.rstrip(os.path.sep))
232
233def move(src, dst):
234 """Recursively move a file or directory to another location. This is
235 similar to the Unix "mv" command.
236
237 If the destination is a directory or a symlink to a directory, the source
238 is moved inside the directory. The destination path must not already
239 exist.
240
241 If the destination already exists but is not a directory, it may be
242 overwritten depending on os.rename() semantics.
243
244 If the destination is on our current filesystem, then rename() is used.
245 Otherwise, src is copied to the destination and then removed.
Martin v. Löwise9ce0b02002-10-07 13:23:24 +0000246 A lot more could be done here... A look at a mv.c shows a lot of
247 the issues this implementation glosses over.
248
249 """
Christian Heimesada8c3b2008-03-18 18:26:33 +0000250 real_dst = dst
251 if os.path.isdir(dst):
252 real_dst = os.path.join(dst, _basename(src))
253 if os.path.exists(real_dst):
254 raise Error("Destination path '%s' already exists" % real_dst)
Martin v. Löwise9ce0b02002-10-07 13:23:24 +0000255 try:
Christian Heimesada8c3b2008-03-18 18:26:33 +0000256 os.rename(src, real_dst)
Martin v. Löwise9ce0b02002-10-07 13:23:24 +0000257 except OSError:
258 if os.path.isdir(src):
Brett Cannon1c3fa182004-06-19 21:11:35 +0000259 if destinsrc(src, dst):
Collin Winterce36ad82007-08-30 01:19:48 +0000260 raise Error("Cannot move a directory '%s' into itself '%s'." % (src, dst))
Christian Heimesada8c3b2008-03-18 18:26:33 +0000261 copytree(src, real_dst, symlinks=True)
Martin v. Löwise9ce0b02002-10-07 13:23:24 +0000262 rmtree(src)
263 else:
Christian Heimesada8c3b2008-03-18 18:26:33 +0000264 copy2(src, real_dst)
Martin v. Löwise9ce0b02002-10-07 13:23:24 +0000265 os.unlink(src)
Brett Cannon1c3fa182004-06-19 21:11:35 +0000266
267def destinsrc(src, dst):
268 return abspath(dst).startswith(abspath(src))