[pypy-commit] pypy py3k: add replace() for win32
mattip
pypy.commits at gmail.com
Fri May 20 12:50:45 EDT 2016
Author: Matti Picus <matti.picus at gmail.com>
Branch: py3k
Changeset: r84536:0fadbd4f5524
Date: 2016-05-20 18:23 +0300
http://bitbucket.org/pypy/pypy/changeset/0fadbd4f5524/
Log: add replace() for win32 (grafted from
54617a9d23bb8b70763929b214ab24eba547ccc3)
diff --git a/rpython/rlib/rposix.py b/rpython/rlib/rposix.py
--- a/rpython/rlib/rposix.py
+++ b/rpython/rlib/rposix.py
@@ -1045,15 +1045,23 @@
win32traits = make_win32_traits(traits)
path1 = traits.as_str0(path1)
path2 = traits.as_str0(path2)
- if not win32traits.MoveFile(path1, path2):
+ if not win32traits.MoveFileEx(path1, path2, 0):
raise rwin32.lastSavedWindowsError()
@specialize.argtype(0, 1)
def replace(path1, path2):
- if os.name == 'nt':
- raise NotImplementedError(
- 'On windows, os.replace() should overwrite the destination')
- return rename(path1, path2)
+ if _WIN32:
+ traits = _preferred_traits(path1)
+ win32traits = make_win32_traits(traits)
+ path1 = traits.as_str0(path1)
+ path2 = traits.as_str0(path2)
+ ret = win32traits.MoveFileEx(path1, path2,
+ win32traits.MOVEFILE_REPLACE_EXISTING)
+ if not ret:
+ raise rwin32.lastSavedWindowsError()
+ else:
+ ret = rename(path1, path2)
+ return ret
#___________________________________________________________________
diff --git a/rpython/rlib/rwin32file.py b/rpython/rlib/rwin32file.py
--- a/rpython/rlib/rwin32file.py
+++ b/rpython/rlib/rwin32file.py
@@ -45,6 +45,8 @@
'INVALID_FILE_ATTRIBUTES')
ERROR_SHARING_VIOLATION = platform.ConstantInteger(
'ERROR_SHARING_VIOLATION')
+ MOVEFILE_REPLACE_EXISTING = platform.ConstantInteger(
+ 'MOVEFILE_REPLACE_EXISTING')
_S_IFDIR = platform.ConstantInteger('_S_IFDIR')
_S_IFREG = platform.ConstantInteger('_S_IFREG')
_S_IFCHR = platform.ConstantInteger('_S_IFCHR')
@@ -103,7 +105,7 @@
FILE_WRITE_ATTRIBUTES OPEN_EXISTING FILE_FLAG_BACKUP_SEMANTICS
VOLUME_NAME_DOS VOLUME_NAME_NT
ERROR_FILE_NOT_FOUND ERROR_NO_MORE_FILES
- ERROR_SHARING_VIOLATION
+ ERROR_SHARING_VIOLATION MOVEFILE_REPLACE_EXISTING
'''.split():
locals()[name] = config[name]
LPWIN32_FIND_DATA = lltype.Ptr(WIN32_FIND_DATA)
@@ -199,9 +201,9 @@
rwin32.BOOL,
save_err=rffi.RFFI_SAVE_LASTERROR)
- MoveFile = external(
- 'MoveFile' + suffix,
- [traits.CCHARP, traits.CCHARP],
+ MoveFileEx = external(
+ 'MoveFileEx' + suffix,
+ [traits.CCHARP, traits.CCHARP, rwin32.DWORD],
rwin32.BOOL,
save_err=rffi.RFFI_SAVE_LASTERROR)
diff --git a/rpython/rlib/test/test_rposix.py b/rpython/rlib/test/test_rposix.py
--- a/rpython/rlib/test/test_rposix.py
+++ b/rpython/rlib/test/test_rposix.py
@@ -334,6 +334,11 @@
self.path = UnicodeWithEncoding(self.ufilename)
self.path2 = UnicodeWithEncoding(self.ufilename + ".new")
+ def _teardown_method(self, method):
+ for path in [self.ufilename + ".new", self.ufilename]:
+ if os.path.exists(path):
+ os.unlink(path)
+
def test_open(self):
def f():
try:
@@ -390,6 +395,14 @@
assert not os.path.exists(self.ufilename)
assert os.path.exists(self.ufilename + '.new')
+ def test_replace(self):
+ def f():
+ return rposix.replace(self.path, self.path2)
+
+ interpret(f, [])
+ assert not os.path.exists(self.ufilename)
+ assert os.path.exists(self.ufilename + '.new')
+
def test_listdir(self):
udir = UnicodeWithEncoding(os.path.dirname(self.ufilename))
More information about the pypy-commit
mailing list