Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit ada8c3b

Browse files
committed
Merged revisions 61520,61523-61528,61532 via svnmerge from
svn+ssh://[email protected]/python/trunk ........ r61520 | thomas.heller | 2008-03-18 16:03:17 +0100 (Di, 18 Mär 2008) | 5 lines Include <alloca.h> on Solaris, see issue #1506. It would probably be better to have a configure test for that, but this is outside of my configure expertise. ........ r61523 | brett.cannon | 2008-03-18 16:35:58 +0100 (Di, 18 Mär 2008) | 5 lines Remove all traces of HAVE_STRERROR. The removal of strerror.c led to the function check being removed from configure.in. ........ r61524 | brett.cannon | 2008-03-18 16:52:00 +0100 (Di, 18 Mär 2008) | 2 lines Fix test_errno to only check for error numbers that are defined by Standard C. ........ r61525 | steven.bethard | 2008-03-18 17:00:19 +0100 (Di, 18 Mär 2008) | 1 line Use test_support.unlink instead of os.unlink in tearDown(). (Seems to fix an occasional failure in Windows Vista.) ........ r61526 | brett.cannon | 2008-03-18 17:47:51 +0100 (Di, 18 Mär 2008) | 3 lines Cast the arguments to PyString_AsStringAndSize() to silence compiler warnings on OS X. ........ r61527 | sean.reifschneider | 2008-03-18 18:24:12 +0100 (Di, 18 Mär 2008) | 3 lines Issue 1577: shutil.move() where destination is a directory was doing a copy, now it is doing a os.rename() if it's on the same file-system. ........ r61528 | brett.cannon | 2008-03-18 18:25:13 +0100 (Di, 18 Mär 2008) | 12 lines Add Tools/scripts/patchcheck.py. Invoked from ``make check``, the script does some verification: - Runs reindent.py on all .py files. - Checks if any changes in Doc exist. - Whether Misc/ACKS was changed. - Whether Misc/NEWS was changed. The hope is that ``make check`` can become a command anybody can run to get reminders about what all the requisite steps needed to create a proper patch/checkin. ........ r61532 | neal.norwitz | 2008-03-18 18:58:02 +0100 (Di, 18 Mär 2008) | 1 line Get regrtest working when re-running tests ........
1 parent 430865f commit ada8c3b

10 files changed

Lines changed: 242 additions & 92 deletions

File tree

Lib/shutil.py

Lines changed: 25 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -187,26 +187,44 @@ def onerror(*args):
187187
except os.error:
188188
onerror(os.rmdir, path, sys.exc_info())
189189

190+
191+
def _basename(path):
192+
# A basename() variant which first strips the trailing slash, if present.
193+
# Thus we always get the last component of the path, even for directories.
194+
return os.path.basename(path.rstrip(os.path.sep))
195+
190196
def move(src, dst):
191-
"""Recursively move a file or directory to another location.
197+
"""Recursively move a file or directory to another location. This is
198+
similar to the Unix "mv" command.
199+
200+
If the destination is a directory or a symlink to a directory, the source
201+
is moved inside the directory. The destination path must not already
202+
exist.
192203
193-
If the destination is on our current filesystem, then simply use
194-
rename. Otherwise, copy src to the dst and then remove src.
204+
If the destination already exists but is not a directory, it may be
205+
overwritten depending on os.rename() semantics.
206+
207+
If the destination is on our current filesystem, then rename() is used.
208+
Otherwise, src is copied to the destination and then removed.
195209
A lot more could be done here... A look at a mv.c shows a lot of
196210
the issues this implementation glosses over.
197211
198212
"""
199-
213+
real_dst = dst
214+
if os.path.isdir(dst):
215+
real_dst = os.path.join(dst, _basename(src))
216+
if os.path.exists(real_dst):
217+
raise Error("Destination path '%s' already exists" % real_dst)
200218
try:
201-
os.rename(src, dst)
219+
os.rename(src, real_dst)
202220
except OSError:
203221
if os.path.isdir(src):
204222
if destinsrc(src, dst):
205223
raise Error("Cannot move a directory '%s' into itself '%s'." % (src, dst))
206-
copytree(src, dst, symlinks=True)
224+
copytree(src, real_dst, symlinks=True)
207225
rmtree(src)
208226
else:
209-
copy2(src,dst)
227+
copy2(src, real_dst)
210228
os.unlink(src)
211229

212230
def destinsrc(src, dst):

Lib/test/test_errno.py

Lines changed: 4 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -7,61 +7,15 @@
77
from test import test_support
88
import unittest
99

10-
errors = ['E2BIG', 'EACCES', 'EADDRINUSE', 'EADDRNOTAVAIL', 'EADV',
11-
'EAFNOSUPPORT', 'EAGAIN', 'EALREADY', 'EBADE', 'EBADF',
12-
'EBADFD', 'EBADMSG', 'EBADR', 'EBADRQC', 'EBADSLT',
13-
'EBFONT', 'EBUSY', 'ECHILD', 'ECHRNG', 'ECOMM',
14-
'ECONNABORTED', 'ECONNREFUSED', 'ECONNRESET',
15-
'EDEADLK', 'EDEADLOCK', 'EDESTADDRREQ', 'EDOTDOT', 'EDOM',
16-
'EDQUOT', 'EEXIST', 'EFAULT', 'EFBIG', 'EHOSTDOWN',
17-
'EHOSTUNREACH', 'EIDRM', 'EILSEQ', 'EINPROGRESS',
18-
'EINTR', 'EINVAL', 'EIO', 'EISCONN', 'EISDIR', 'EISNAM',
19-
'EL2HLT', 'EL2NSYNC', 'EL3HLT', 'EL3RST', 'ELIBACC',
20-
'ELIBBAD', 'ELIBEXEC', 'ELIBMAX', 'ELIBSCN', 'ELNRNG',
21-
'ELOOP', 'EMFILE', 'EMLINK', 'EMSGSIZE', 'EMULTIHOP',
22-
'ENAMETOOLONG', 'ENAVAIL', 'ENETDOWN', 'ENETRESET', 'ENETUNREACH',
23-
'ENFILE', 'ENOANO', 'ENOBUFS', 'ENOCSI', 'ENODATA',
24-
'ENODEV', 'ENOENT', 'ENOEXEC', 'ENOLCK', 'ENOLINK',
25-
'ENOMEM', 'ENOMSG', 'ENONET', 'ENOPKG', 'ENOPROTOOPT',
26-
'ENOSPC', 'ENOSR', 'ENOSTR', 'ENOSYS', 'ENOTBLK',
27-
'ENOTCONN', 'ENOTDIR', 'ENOTEMPTY', 'ENOTNAM', 'ENOTOBACCO', 'ENOTSOCK',
28-
'ENOTTY', 'ENOTUNIQ', 'ENXIO', 'EOPNOTSUPP',
29-
'EOVERFLOW', 'EPERM', 'EPFNOSUPPORT', 'EPIPE',
30-
'EPROTO', 'EPROTONOSUPPORT', 'EPROTOTYPE',
31-
'ERANGE', 'EREMCHG', 'EREMOTE', 'EREMOTEIO', 'ERESTART',
32-
'EROFS', 'ESHUTDOWN', 'ESOCKTNOSUPPORT', 'ESPIPE',
33-
'ESRCH', 'ESRMNT', 'ESTALE', 'ESTRPIPE', 'ETIME',
34-
'ETIMEDOUT', 'ETOOMANYREFS', 'ETXTBSY', 'EUCLEAN', 'EUNATCH',
35-
'EUSERS', 'EWOULDBLOCK', 'EXDEV', 'EXFULL',
36-
'WSABASEERR', 'WSADESCRIPTIO', 'WSAEACCES', 'WSAEADDRINUSE',
37-
'WSAEADDRNOTAVAIL', 'WSAEAFNOSUPPORT', 'WSAEALREADY',
38-
'WSAEBADF', 'WSAECONNABORTED', 'WSAECONNREFUSED',
39-
'WSAECONNRESET', 'WSAEDESTADDRREQ', 'WSAEDISCON',
40-
'WSAEDQUOT', 'WSAEFAULT', 'WSAEHOSTDOWN', 'WSAEHOSTUNREACH',
41-
'WSAEINPROGRESS', 'WSAEINTR', 'WSAEINVAL', 'WSAEISCONN',
42-
'WSAELOOP', 'WSAEMFILE', 'WSAEMSGSIZE', 'WSAENAMETOOLONG',
43-
'WSAENETDOWN', 'WSAENETRESET', 'WSAENETUNREACH',
44-
'WSAENOBUFS', 'WSAENOPROTOOPT', 'WSAENOTCONN',
45-
'WSAENOTEMPTY', 'WSAENOTSOCK', 'WSAEOPNOTSUPP',
46-
'WSAEPFNOSUPPORT', 'WSAEPROCLIM', 'WSAEPROTONOSUPPORT',
47-
'WSAEPROTOTYPE', 'WSAEREMOTE', 'WSAESHUTDOWN',
48-
'WSAESOCKTNOSUPPORT', 'WSAESTALE', 'WSAETIMEDOUT',
49-
'WSAETOOMANYREFS', 'WSAEUSERS', 'WSAEWOULDBLOCK',
50-
'WSAGETASYNCBUFLE', 'WSAGETASYNCERRO', 'WSAGETSELECTERRO',
51-
'WSAGETSELECTEVEN', 'WSAHOS', 'WSAMAKEASYNCREPL',
52-
'WSAMAKESELECTREPL', 'WSAN', 'WSANOTINITIALISED', 'WSASY',
53-
'WSASYSNOTREADY', 'WSATR', 'WSAVERNOTSUPPORTED']
54-
10+
std_c_errors = frozenset(['EDOM', 'ERANGE'])
5511

5612
class ErrnoAttributeTests(unittest.TestCase):
5713

5814
def test_for_improper_attributes(self):
5915
# No unexpected attributes should be on the module.
60-
errors_set = set(errors)
61-
for attribute in errno.__dict__.keys():
62-
if attribute.isupper():
63-
self.assert_(attribute in errors_set,
64-
"%s is an unexpected error value" % attribute)
16+
for error_code in std_c_errors:
17+
self.assert_(hasattr(errno, error_code),
18+
"errno is missing %s" % error_code)
6519

6620
def test_using_errorcode(self):
6721
# Every key value in errno.errorcode should be on the module.

Lib/test/test_shutil.py

Lines changed: 115 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -63,17 +63,6 @@ def test_rmtree_dont_delete_file(self):
6363
self.assertRaises(OSError, shutil.rmtree, path)
6464
os.remove(path)
6565

66-
def test_dont_move_dir_in_itself(self):
67-
src_dir = tempfile.mkdtemp()
68-
try:
69-
dst = os.path.join(src_dir, 'foo')
70-
self.assertRaises(shutil.Error, shutil.move, src_dir, dst)
71-
finally:
72-
try:
73-
os.rmdir(src_dir)
74-
except:
75-
pass
76-
7766
def test_copytree_simple(self):
7867
def write_data(path, data):
7968
f = open(path, "w")
@@ -162,9 +151,123 @@ def test_rmtree_on_symlink(self):
162151
shutil.rmtree(TESTFN, ignore_errors=True)
163152

164153

154+
class TestMove(unittest.TestCase):
155+
156+
def setUp(self):
157+
filename = "foo"
158+
self.src_dir = tempfile.mkdtemp()
159+
self.dst_dir = tempfile.mkdtemp()
160+
self.src_file = os.path.join(self.src_dir, filename)
161+
self.dst_file = os.path.join(self.dst_dir, filename)
162+
# Try to create a dir in the current directory, hoping that it is
163+
# not located on the same filesystem as the system tmp dir.
164+
try:
165+
self.dir_other_fs = tempfile.mkdtemp(
166+
dir=os.path.dirname(__file__))
167+
self.file_other_fs = os.path.join(self.dir_other_fs,
168+
filename)
169+
except OSError:
170+
self.dir_other_fs = None
171+
with open(self.src_file, "wb") as f:
172+
f.write(b"spam")
173+
174+
def tearDown(self):
175+
for d in (self.src_dir, self.dst_dir, self.dir_other_fs):
176+
try:
177+
if d:
178+
shutil.rmtree(d)
179+
except:
180+
pass
181+
182+
def _check_move_file(self, src, dst, real_dst):
183+
contents = open(src, "rb").read()
184+
shutil.move(src, dst)
185+
self.assertEqual(contents, open(real_dst, "rb").read())
186+
self.assertFalse(os.path.exists(src))
187+
188+
def _check_move_dir(self, src, dst, real_dst):
189+
contents = sorted(os.listdir(src))
190+
shutil.move(src, dst)
191+
self.assertEqual(contents, sorted(os.listdir(real_dst)))
192+
self.assertFalse(os.path.exists(src))
193+
194+
def test_move_file(self):
195+
# Move a file to another location on the same filesystem.
196+
self._check_move_file(self.src_file, self.dst_file, self.dst_file)
197+
198+
def test_move_file_to_dir(self):
199+
# Move a file inside an existing dir on the same filesystem.
200+
self._check_move_file(self.src_file, self.dst_dir, self.dst_file)
201+
202+
def test_move_file_other_fs(self):
203+
# Move a file to an existing dir on another filesystem.
204+
if not self.dir_other_fs:
205+
# skip
206+
return
207+
self._check_move_file(self.src_file, self.file_other_fs,
208+
self.file_other_fs)
209+
210+
def test_move_file_to_dir_other_fs(self):
211+
# Move a file to another location on another filesystem.
212+
if not self.dir_other_fs:
213+
# skip
214+
return
215+
self._check_move_file(self.src_file, self.dir_other_fs,
216+
self.file_other_fs)
217+
218+
def test_move_dir(self):
219+
# Move a dir to another location on the same filesystem.
220+
dst_dir = tempfile.mktemp()
221+
try:
222+
self._check_move_dir(self.src_dir, dst_dir, dst_dir)
223+
finally:
224+
try:
225+
shutil.rmtree(dst_dir)
226+
except:
227+
pass
228+
229+
def test_move_dir_other_fs(self):
230+
# Move a dir to another location on another filesystem.
231+
if not self.dir_other_fs:
232+
# skip
233+
return
234+
dst_dir = tempfile.mktemp(dir=self.dir_other_fs)
235+
try:
236+
self._check_move_dir(self.src_dir, dst_dir, dst_dir)
237+
finally:
238+
try:
239+
shutil.rmtree(dst_dir)
240+
except:
241+
pass
242+
243+
def test_move_dir_to_dir(self):
244+
# Move a dir inside an existing dir on the same filesystem.
245+
self._check_move_dir(self.src_dir, self.dst_dir,
246+
os.path.join(self.dst_dir, os.path.basename(self.src_dir)))
247+
248+
def test_move_dir_to_dir_other_fs(self):
249+
# Move a dir inside an existing dir on another filesystem.
250+
if not self.dir_other_fs:
251+
# skip
252+
return
253+
self._check_move_dir(self.src_dir, self.dir_other_fs,
254+
os.path.join(self.dir_other_fs, os.path.basename(self.src_dir)))
255+
256+
def test_existing_file_inside_dest_dir(self):
257+
# A file with the same name inside the destination dir already exists.
258+
with open(self.dst_file, "wb"):
259+
pass
260+
self.assertRaises(shutil.Error, shutil.move, self.src_file, self.dst_dir)
261+
262+
def test_dont_move_dir_in_itself(self):
263+
# Moving a dir inside itself raises an Error.
264+
dst = os.path.join(self.src_dir, "bar")
265+
self.assertRaises(shutil.Error, shutil.move, self.src_dir, dst)
266+
267+
165268

166269
def test_main():
167-
test_support.run_unittest(TestShutil)
270+
test_support.run_unittest(TestShutil, TestMove)
168271

169272
if __name__ == '__main__':
170273
test_main()

Makefile.pre.in

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1150,6 +1150,10 @@ funny:
11501150
-o -name MANIFEST \
11511151
-o -print
11521152

1153+
# Perform some verification checks on any modified files.
1154+
check:
1155+
./$(BUILDPYTHON) $(srcdir)/Tools/scripts/patchcheck.py
1156+
11531157
# Dependencies
11541158

11551159
Python/thread.o: @THREADHEADERS@

Modules/_fileio.c

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -104,11 +104,7 @@ dircheck(PyFileIOObject* self)
104104
if (self->fd < 0)
105105
return 0;
106106
if (fstat(self->fd, &buf) == 0 && S_ISDIR(buf.st_mode)) {
107-
#ifdef HAVE_STRERROR
108107
char *msg = strerror(EISDIR);
109-
#else
110-
char *msg = "Is a directory";
111-
#endif
112108
PyObject *exc;
113109
internal_close(self);
114110

@@ -295,12 +291,8 @@ fileio_dealloc(PyFileIOObject *self)
295291
if (self->fd >= 0 && self->closefd) {
296292
errno = internal_close(self);
297293
if (errno < 0) {
298-
#ifdef HAVE_STRERROR
299294
PySys_WriteStderr("close failed: [Errno %d] %s\n",
300295
errno, strerror(errno));
301-
#else
302-
PySys_WriteStderr("close failed: [Errno %d]\n", errno);
303-
#endif
304296
}
305297
}
306298

Modules/main.c

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -507,13 +507,9 @@ Py_Main(int argc, char **argv)
507507

508508
if (sts==-1 && filename!=NULL) {
509509
if ((fp = fopen(filename, "r")) == NULL) {
510-
#ifdef HAVE_STRERROR
511510
fprintf(stderr, "%s: can't open file '%s': [Errno %d] %s\n",
512511
argv[0], filename, errno, strerror(errno));
513-
#else
514-
fprintf(stderr, "%s: can't open file '%s': Errno %d\n",
515-
argv[0], filename, errno);
516-
#endif
512+
517513
return 2;
518514
}
519515
else if (skipfirstline) {

Modules/posixmodule.c

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5239,7 +5239,6 @@ posix_unsetenv(PyObject *self, PyObject *args)
52395239
}
52405240
#endif /* unsetenv */
52415241

5242-
#ifdef HAVE_STRERROR
52435242
PyDoc_STRVAR(posix_strerror__doc__,
52445243
"strerror(code) -> string\n\n\
52455244
Translate an error code to a message string.");
@@ -5259,7 +5258,6 @@ posix_strerror(PyObject *self, PyObject *args)
52595258
}
52605259
return PyUnicode_FromString(message);
52615260
}
5262-
#endif /* strerror */
52635261

52645262

52655263
#ifdef HAVE_SYS_WAIT_H
@@ -6977,9 +6975,7 @@ static PyMethodDef posix_methods[] = {
69776975
#ifdef HAVE_UNSETENV
69786976
{"unsetenv", posix_unsetenv, METH_VARARGS, posix_unsetenv__doc__},
69796977
#endif
6980-
#ifdef HAVE_STRERROR
69816978
{"strerror", posix_strerror, METH_VARARGS, posix_strerror__doc__},
6982-
#endif
69836979
#ifdef HAVE_FCHDIR
69846980
{"fchdir", posix_fchdir, METH_O, posix_fchdir__doc__},
69856981
#endif

Modules/socketmodule.c

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2922,15 +2922,10 @@ gethost_common(struct hostent *h, struct sockaddr *addr, int alen, int af)
29222922
}
29232923

29242924
if (h->h_addrtype != af) {
2925-
#ifdef HAVE_STRERROR
29262925
/* Let's get real error message to return */
29272926
PyErr_SetString(socket_error,
29282927
(char *)strerror(EAFNOSUPPORT));
2929-
#else
2930-
PyErr_SetString(
2931-
socket_error,
2932-
"Address family not supported by protocol family");
2933-
#endif
2928+
29342929
return NULL;
29352930
}
29362931

0 commit comments

Comments
 (0)