Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
C
cpython
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
cpython
Commits
f3b2d88b
Commit
f3b2d88b
authored
Jan 30, 2012
by
Antoine Pitrou
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Issue #8828: Add new function os.replace(), for cross-platform renaming with overwriting.
parent
8a894508
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
65 additions
and
15 deletions
+65
-15
Doc/library/os.rst
Doc/library/os.rst
+16
-2
Lib/test/test_os.py
Lib/test/test_os.py
+12
-0
Misc/NEWS
Misc/NEWS
+3
-0
Modules/posixmodule.c
Modules/posixmodule.c
+34
-13
No files found.
Doc/library/os.rst
View file @
f3b2d88b
...
...
@@ -1889,8 +1889,9 @@ Files and Directories
Unix flavors if *src* and *dst* are on different filesystems. If successful,
the renaming will be an atomic operation (this is a POSIX requirement). On
Windows, if *dst* already exists, :exc:`OSError` will be raised even if it is a
file; there may be no way to implement an atomic rename when *dst* names an
existing file.
file.
If you want cross-platform overwriting of the destination, use :func:`replace`.
Availability: Unix, Windows.
...
...
@@ -1908,6 +1909,19 @@ Files and Directories
permissions needed to remove the leaf directory or file.
.. function:: replace(src, dst)
Rename the file or directory *src* to *dst*. If *dst* is a directory,
:exc:`OSError` will be raised. If *dst* exists and is a file, it will
be replaced silently if the user has permission. The operation may fail
if *src* and *dst* are on different filesystems. If successful,
the renaming will be an atomic operation (this is a POSIX requirement).
Availability: Unix, Windows
.. versionadded:: 3.3
.. function:: rmdir(path)
Remove (delete) the directory *path*. Only works when the directory is
...
...
Lib/test/test_os.py
View file @
f3b2d88b
...
...
@@ -129,6 +129,18 @@ class FileTests(unittest.TestCase):
self
.
fdopen_helper
(
'r'
)
self
.
fdopen_helper
(
'r'
,
100
)
def
test_replace
(
self
):
TESTFN2
=
support
.
TESTFN
+
".2"
with
open
(
support
.
TESTFN
,
'w'
)
as
f
:
f
.
write
(
"1"
)
with
open
(
TESTFN2
,
'w'
)
as
f
:
f
.
write
(
"2"
)
self
.
addCleanup
(
os
.
unlink
,
TESTFN2
)
os
.
replace
(
support
.
TESTFN
,
TESTFN2
)
self
.
assertRaises
(
FileNotFoundError
,
os
.
stat
,
support
.
TESTFN
)
with
open
(
TESTFN2
,
'r'
)
as
f
:
self
.
assertEqual
(
f
.
read
(),
"1"
)
# Test attributes on return values from os.*stat* family.
class
StatAttributeTests
(
unittest
.
TestCase
):
...
...
Misc/NEWS
View file @
f3b2d88b
...
...
@@ -463,6 +463,9 @@ Core and Builtins
Library
-------
-
Issue
#
8828
:
Add
new
function
os
.
replace
(),
for
cross
-
platform
renaming
with
overwriting
.
-
Issue
#
13848
:
open
()
and
the
FileIO
constructor
now
check
for
NUL
characters
in
the
file
name
.
Patch
by
Hynek
Schlawack
.
...
...
Modules/posixmodule.c
View file @
f3b2d88b
...
...
@@ -3280,17 +3280,16 @@ posix_setpriority(PyObject *self, PyObject *args)
#endif
/* HAVE_SETPRIORITY */
PyDoc_STRVAR
(
posix_rename__doc__
,
"rename(old, new)
\n\n
\
Rename a file or directory."
);
static
PyObject
*
posix_rename
(
PyObject
*
self
,
PyObject
*
args
)
internal_rename
(
PyObject
*
self
,
PyObject
*
args
,
int
is_replace
)
{
#ifdef MS_WINDOWS
PyObject
*
src
,
*
dst
;
BOOL
result
;
if
(
PyArg_ParseTuple
(
args
,
"UU:rename"
,
&
src
,
&
dst
))
int
flags
=
is_replace
?
MOVEFILE_REPLACE_EXISTING
:
0
;
if
(
PyArg_ParseTuple
(
args
,
is_replace
?
"UU:replace"
:
"UU:rename"
,
&
src
,
&
dst
))
{
wchar_t
*
wsrc
,
*
wdst
;
...
...
@@ -3301,16 +3300,17 @@ posix_rename(PyObject *self, PyObject *args)
if
(
wdst
==
NULL
)
return
NULL
;
Py_BEGIN_ALLOW_THREADS
result
=
MoveFile
W
(
wsrc
,
wdst
);
result
=
MoveFile
ExW
(
wsrc
,
wdst
,
flags
);
Py_END_ALLOW_THREADS
if
(
!
result
)
return
win32_error
(
"rename"
,
NULL
);
return
win32_error
(
is_replace
?
"replace"
:
"rename"
,
NULL
);
Py_INCREF
(
Py_None
);
return
Py_None
;
}
else
{
PyErr_Clear
();
if
(
!
PyArg_ParseTuple
(
args
,
"O&O&:rename"
,
if
(
!
PyArg_ParseTuple
(
args
,
is_replace
?
"O&O&:replace"
:
"O&O&:rename"
,
PyUnicode_FSConverter
,
&
src
,
PyUnicode_FSConverter
,
&
dst
))
return
NULL
;
...
...
@@ -3319,15 +3319,15 @@ posix_rename(PyObject *self, PyObject *args)
goto
error
;
Py_BEGIN_ALLOW_THREADS
result
=
MoveFileA
(
PyBytes_AS_STRING
(
src
),
PyBytes_AS_STRING
(
dst
)
);
result
=
MoveFile
Ex
A
(
PyBytes_AS_STRING
(
src
),
PyBytes_AS_STRING
(
dst
),
flags
);
Py_END_ALLOW_THREADS
Py_XDECREF
(
src
);
Py_XDECREF
(
dst
);
if
(
!
result
)
return
win32_error
(
"rename"
,
NULL
);
return
win32_error
(
is_replace
?
"replace"
:
"rename"
,
NULL
);
Py_INCREF
(
Py_None
);
return
Py_None
;
...
...
@@ -3337,10 +3337,30 @@ error:
return
NULL
;
}
#else
return
posix_2str
(
args
,
"O&O&:rename"
,
rename
);
return
posix_2str
(
args
,
is_replace
?
"O&O&:replace"
:
"O&O&:rename"
,
rename
);
#endif
}
PyDoc_STRVAR
(
posix_rename__doc__
,
"rename(old, new)
\n\n
\
Rename a file or directory."
);
static
PyObject
*
posix_rename
(
PyObject
*
self
,
PyObject
*
args
)
{
return
internal_rename
(
self
,
args
,
0
);
}
PyDoc_STRVAR
(
posix_replace__doc__
,
"replace(old, new)
\n\n
\
Rename a file or directory, overwriting the destination."
);
static
PyObject
*
posix_replace
(
PyObject
*
self
,
PyObject
*
args
)
{
return
internal_rename
(
self
,
args
,
1
);
}
PyDoc_STRVAR
(
posix_rmdir__doc__
,
"rmdir(path)
\n\n
\
...
...
@@ -10555,6 +10575,7 @@ static PyMethodDef posix_methods[] = {
{
"readlink"
,
win_readlink
,
METH_VARARGS
,
win_readlink__doc__
},
#endif
/* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
{
"rename"
,
posix_rename
,
METH_VARARGS
,
posix_rename__doc__
},
{
"replace"
,
posix_replace
,
METH_VARARGS
,
posix_replace__doc__
},
{
"rmdir"
,
posix_rmdir
,
METH_VARARGS
,
posix_rmdir__doc__
},
{
"stat"
,
posix_stat
,
METH_VARARGS
,
posix_stat__doc__
},
{
"stat_float_times"
,
stat_float_times
,
METH_VARARGS
,
stat_float_times__doc__
},
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment