77import os
88import sys
99import stat
10+ import exceptions
1011
1112__all__ = ["copyfileobj" ,"copyfile" ,"copymode" ,"copystat" ,"copy" ,"copy2" ,
12- "copytree" ,"rmtree" ]
13+ "copytree" ,"rmtree" ,"Error" ]
14+
15+ class Error (exceptions .EnvironmentError ):
16+ pass
1317
1418def copyfileobj (fsrc , fdst , length = 16 * 1024 ):
1519 """copy data from file-like object fsrc to file-like object fdst"""
@@ -95,6 +99,7 @@ def copytree(src, dst, symlinks=0):
9599 """
96100 names = os .listdir (src )
97101 os .mkdir (dst )
102+ errors = []
98103 for name in names :
99104 srcname = os .path .join (src , name )
100105 dstname = os .path .join (dst , name )
@@ -108,7 +113,9 @@ def copytree(src, dst, symlinks=0):
108113 copy2 (srcname , dstname )
109114 # XXX What about devices, sockets etc.?
110115 except (IOError , os .error ), why :
111- print "Can't copy %s to %s: %s" % (`srcname` , `dstname` , str (why ))
116+ errors .append ((srcname , dstname , why ))
117+ if errors :
118+ raise Error , errors
112119
113120def rmtree (path , ignore_errors = 0 , onerror = None ):
114121 """Recursively delete a directory tree.
@@ -141,3 +148,24 @@ def _build_cmdtuple(path, cmdtuples):
141148 else :
142149 cmdtuples .append ((os .remove , real_f ))
143150 cmdtuples .append ((os .rmdir , path ))
151+
152+
153+ def move (src , dst ):
154+ """Recursively move a file or directory to another location.
155+
156+ If the destination is on our current filesystem, then simply use
157+ rename. Otherwise, copy src to the dst and then remove src.
158+ A lot more could be done here... A look at a mv.c shows a lot of
159+ the issues this implementation glosses over.
160+
161+ """
162+
163+ try :
164+ os .rename (src , dst )
165+ except OSError :
166+ if os .path .isdir (src ):
167+ copytree (src , dst , symlinks = 1 )
168+ rmtree (src )
169+ else :
170+ copy2 (src ,dst )
171+ os .unlink (src )
0 commit comments