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
7103ff94
Commit
7103ff94
authored
Sep 06, 2016
by
Benjamin Peterson
Browse files
Options
Browse Files
Download
Plain Diff
merge heads
parents
0cf22387
581139cb
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
61 additions
and
60 deletions
+61
-60
Doc/c-api/unicode.rst
Doc/c-api/unicode.rst
+4
-1
Lib/test/test_os.py
Lib/test/test_os.py
+28
-36
Misc/NEWS
Misc/NEWS
+5
-0
Modules/clinic/posixmodule.c.h
Modules/clinic/posixmodule.c.h
+7
-7
Modules/posixmodule.c
Modules/posixmodule.c
+4
-4
Objects/unicodeobject.c
Objects/unicodeobject.c
+13
-12
No files found.
Doc/c-api/unicode.rst
View file @
7103ff94
...
...
@@ -810,13 +810,16 @@ used, passing :c:func:`PyUnicode_FSConverter` as the conversion function:
.. c:function:: int PyUnicode_FSConverter(PyObject* obj, void* result)
ParseTuple converter: encode :class:`str` objects to :class:`bytes` using
ParseTuple converter: encode :class:`str` objects -- obtained directly or
through the :class:`os.PathLike` interface -- to :class:`bytes` using
:c:func:`PyUnicode_EncodeFSDefault`; :class:`bytes` objects are output as-is.
*result* must be a :c:type:`PyBytesObject*` which must be released when it is
no longer used.
.. versionadded:: 3.1
.. versionchanged:: 3.6
Accepts a :term:`path-like object`.
To decode file names during argument parsing, the ``"O&"`` converter should be
used, passing :c:func:`PyUnicode_FSDecoder` as the conversion function:
...
...
Lib/test/test_os.py
View file @
7103ff94
...
...
@@ -100,6 +100,21 @@ def bytes_filename_warn(expected):
yield
class
_PathLike
(
os
.
PathLike
):
def
__init__
(
self
,
path
=
""
):
self
.
path
=
path
def
__str__
(
self
):
return
str
(
self
.
path
)
def
__fspath__
(
self
):
if
isinstance
(
self
.
path
,
BaseException
):
raise
self
.
path
else
:
return
self
.
path
def
create_file
(
filename
,
content
=
b'content'
):
with
open
(
filename
,
"xb"
,
0
)
as
fp
:
fp
.
write
(
content
)
...
...
@@ -894,15 +909,7 @@ class WalkTests(unittest.TestCase):
self
.
assertEqual
(
all
[
1
],
self
.
sub2_tree
)
def
test_file_like_path
(
self
):
class
FileLike
:
def
__init__
(
self
,
path
):
self
.
_path
=
path
def
__str__
(
self
):
return
str
(
self
.
_path
)
def
__fspath__
(
self
):
return
self
.
_path
self
.
test_walk_prune
(
FileLike
(
self
.
walk_path
))
self
.
test_walk_prune
(
_PathLike
(
self
.
walk_path
))
def
test_walk_bottom_up
(
self
):
# Walk bottom-up.
...
...
@@ -2124,7 +2131,8 @@ class PidTests(unittest.TestCase):
def
test_waitpid
(
self
):
args
=
[
sys
.
executable
,
'-c'
,
'pass'
]
pid
=
os
.
spawnv
(
os
.
P_NOWAIT
,
args
[
0
],
args
)
# Add an implicit test for PyUnicode_FSConverter().
pid
=
os
.
spawnv
(
os
.
P_NOWAIT
,
_PathLike
(
args
[
0
]),
args
)
status
=
os
.
waitpid
(
pid
,
0
)
self
.
assertEqual
(
status
,
(
pid
,
0
))
...
...
@@ -2833,25 +2841,18 @@ class PathTConverterTests(unittest.TestCase):
]
def
test_path_t_converter
(
self
):
class
PathLike
:
def
__init__
(
self
,
path
):
self
.
path
=
path
def
__fspath__
(
self
):
return
self
.
path
str_filename
=
support
.
TESTFN
if
os
.
name
==
'nt'
:
bytes_fspath
=
bytes_filename
=
None
else
:
bytes_filename
=
support
.
TESTFN
.
encode
(
'ascii'
)
bytes_fspath
=
PathLike
(
bytes_filename
)
fd
=
os
.
open
(
PathLike
(
str_filename
),
os
.
O_WRONLY
|
os
.
O_CREAT
)
bytes_fspath
=
_
PathLike
(
bytes_filename
)
fd
=
os
.
open
(
_
PathLike
(
str_filename
),
os
.
O_WRONLY
|
os
.
O_CREAT
)
self
.
addCleanup
(
support
.
unlink
,
support
.
TESTFN
)
self
.
addCleanup
(
os
.
close
,
fd
)
int_fspath
=
PathLike
(
fd
)
str_fspath
=
PathLike
(
str_filename
)
int_fspath
=
_
PathLike
(
fd
)
str_fspath
=
_
PathLike
(
str_filename
)
for
name
,
allow_fd
,
extra_args
,
cleanup_fn
in
self
.
functions
:
with
self
.
subTest
(
name
=
name
):
...
...
@@ -3205,15 +3206,6 @@ class TestPEP519(unittest.TestCase):
# if a C version is provided.
fspath
=
staticmethod
(
os
.
fspath
)
class
PathLike
:
def
__init__
(
self
,
path
=
''
):
self
.
path
=
path
def
__fspath__
(
self
):
if
isinstance
(
self
.
path
,
BaseException
):
raise
self
.
path
else
:
return
self
.
path
def
test_return_bytes
(
self
):
for
b
in
b'hello'
,
b'goodbye'
,
b'some/path/and/file'
:
self
.
assertEqual
(
b
,
self
.
fspath
(
b
))
...
...
@@ -3224,16 +3216,16 @@ class TestPEP519(unittest.TestCase):
def
test_fsencode_fsdecode
(
self
):
for
p
in
"path/like/object"
,
b"path/like/object"
:
pathlike
=
self
.
PathLike
(
p
)
pathlike
=
_
PathLike
(
p
)
self
.
assertEqual
(
p
,
self
.
fspath
(
pathlike
))
self
.
assertEqual
(
b"path/like/object"
,
os
.
fsencode
(
pathlike
))
self
.
assertEqual
(
"path/like/object"
,
os
.
fsdecode
(
pathlike
))
def
test_pathlike
(
self
):
self
.
assertEqual
(
'#feelthegil'
,
self
.
fspath
(
self
.
PathLike
(
'#feelthegil'
)))
self
.
assertTrue
(
issubclass
(
self
.
PathLike
,
os
.
PathLike
))
self
.
assertTrue
(
isinstance
(
self
.
PathLike
(),
os
.
PathLike
))
self
.
assertEqual
(
'#feelthegil'
,
self
.
fspath
(
_
PathLike
(
'#feelthegil'
)))
self
.
assertTrue
(
issubclass
(
_
PathLike
,
os
.
PathLike
))
self
.
assertTrue
(
isinstance
(
_
PathLike
(),
os
.
PathLike
))
def
test_garbage_in_exception_out
(
self
):
vapor
=
type
(
'blah'
,
(),
{})
...
...
@@ -3245,14 +3237,14 @@ class TestPEP519(unittest.TestCase):
def
test_bad_pathlike
(
self
):
# __fspath__ returns a value other than str or bytes.
self
.
assertRaises
(
TypeError
,
self
.
fspath
,
self
.
PathLike
(
42
))
self
.
assertRaises
(
TypeError
,
self
.
fspath
,
_
PathLike
(
42
))
# __fspath__ attribute that is not callable.
c
=
type
(
'foo'
,
(),
{})
c
.
__fspath__
=
1
self
.
assertRaises
(
TypeError
,
self
.
fspath
,
c
())
# __fspath__ raises an exception.
self
.
assertRaises
(
ZeroDivisionError
,
self
.
fspath
,
self
.
PathLike
(
ZeroDivisionError
()))
_
PathLike
(
ZeroDivisionError
()))
# Only test if the C version is provided, otherwise TestPEP519 already tested
# the pure Python implementation.
...
...
Misc/NEWS
View file @
7103ff94
...
...
@@ -188,6 +188,11 @@ Library
-
Issue
#
27573
:
exit
message
for
code
.
interact
is
now
configurable
.
C
API
-----
-
Issue
#
26027
:
Add
support
for
path
-
like
objects
in
PyUnicode_FSConverter
().
Tests
-----
...
...
Modules/clinic/posixmodule.c.h
View file @
7103ff94
...
...
@@ -3011,13 +3011,13 @@ PyDoc_STRVAR(os_waitpid__doc__,
{"waitpid", (PyCFunction)os_waitpid, METH_VARARGS, os_waitpid__doc__},
static
PyObject
*
os_waitpid_impl
(
PyObject
*
module
,
Py_
intptr_t
pid
,
int
options
);
os_waitpid_impl
(
PyObject
*
module
,
intptr_t
pid
,
int
options
);
static
PyObject
*
os_waitpid
(
PyObject
*
module
,
PyObject
*
args
)
{
PyObject
*
return_value
=
NULL
;
Py_
intptr_t
pid
;
intptr_t
pid
;
int
options
;
if
(
!
PyArg_ParseTuple
(
args
,
""
_Py_PARSE_INTPTR
"i:waitpid"
,
...
...
@@ -5479,13 +5479,13 @@ PyDoc_STRVAR(os_get_handle_inheritable__doc__,
{"get_handle_inheritable", (PyCFunction)os_get_handle_inheritable, METH_O, os_get_handle_inheritable__doc__},
static
int
os_get_handle_inheritable_impl
(
PyObject
*
module
,
Py_
intptr_t
handle
);
os_get_handle_inheritable_impl
(
PyObject
*
module
,
intptr_t
handle
);
static
PyObject
*
os_get_handle_inheritable
(
PyObject
*
module
,
PyObject
*
arg
)
{
PyObject
*
return_value
=
NULL
;
Py_
intptr_t
handle
;
intptr_t
handle
;
int
_return_value
;
if
(
!
PyArg_Parse
(
arg
,
""
_Py_PARSE_INTPTR
":get_handle_inheritable"
,
&
handle
))
{
...
...
@@ -5515,14 +5515,14 @@ PyDoc_STRVAR(os_set_handle_inheritable__doc__,
{"set_handle_inheritable", (PyCFunction)os_set_handle_inheritable, METH_VARARGS, os_set_handle_inheritable__doc__},
static
PyObject
*
os_set_handle_inheritable_impl
(
PyObject
*
module
,
Py_
intptr_t
handle
,
os_set_handle_inheritable_impl
(
PyObject
*
module
,
intptr_t
handle
,
int
inheritable
);
static
PyObject
*
os_set_handle_inheritable
(
PyObject
*
module
,
PyObject
*
args
)
{
PyObject
*
return_value
=
NULL
;
Py_
intptr_t
handle
;
intptr_t
handle
;
int
inheritable
;
if
(
!
PyArg_ParseTuple
(
args
,
""
_Py_PARSE_INTPTR
"p:set_handle_inheritable"
,
...
...
@@ -6042,4 +6042,4 @@ exit:
#ifndef OS_SET_HANDLE_INHERITABLE_METHODDEF
#define OS_SET_HANDLE_INHERITABLE_METHODDEF
#endif
/* !defined(OS_SET_HANDLE_INHERITABLE_METHODDEF) */
/*[clinic end generated code: output=
2b85bb3703a6488a
input=a9049054013a1b77]*/
/*[clinic end generated code: output=
677ce794fb126161
input=a9049054013a1b77]*/
Modules/posixmodule.c
View file @
7103ff94
...
...
@@ -2520,7 +2520,7 @@ class sched_param_converter(CConverter):
impl_by_reference = True;
[python start generated code]*/
/*[python end generated code: output=da39a3ee5e6b4b0d input=
affe68316f16040
1]*/
/*[python end generated code: output=da39a3ee5e6b4b0d input=
418fce0e0114446
1]*/
/*[clinic input]
...
...
@@ -7092,7 +7092,7 @@ The options argument is ignored on Windows.
static
PyObject
*
os_waitpid_impl
(
PyObject
*
module
,
intptr_t
pid
,
int
options
)
/*[clinic end generated code: output=
15f1ce005a346b09 input=444c8f51cca5b862
]*/
/*[clinic end generated code: output=
be836b221271d538 input=40f2440c515410f8
]*/
{
int
status
;
intptr_t
res
;
...
...
@@ -11383,7 +11383,7 @@ Get the close-on-exe flag of the specified file descriptor.
static
int
os_get_handle_inheritable_impl
(
PyObject
*
module
,
intptr_t
handle
)
/*[clinic end generated code: output=
9e5389b0aa0916ce input=5f7759443aae3dc5
]*/
/*[clinic end generated code: output=
36be5afca6ea84d8 input=cfe99f9c05c70ad1
]*/
{
DWORD
flags
;
...
...
@@ -11408,7 +11408,7 @@ Set the inheritable flag of the specified handle.
static
PyObject
*
os_set_handle_inheritable_impl
(
PyObject
*
module
,
intptr_t
handle
,
int
inheritable
)
/*[clinic end generated code: output=
b1e67bfa3213d745 input=e64b2b2730469def
]*/
/*[clinic end generated code: output=
021d74fe6c96baa3 input=7a7641390d8364fc
]*/
{
DWORD
flags
=
inheritable
?
HANDLE_FLAG_INHERIT
:
0
;
if
(
!
SetHandleInformation
((
HANDLE
)
handle
,
HANDLE_FLAG_INHERIT
,
flags
))
{
...
...
Objects/unicodeobject.c
View file @
7103ff94
...
...
@@ -3842,6 +3842,7 @@ PyUnicode_DecodeFSDefaultAndSize(const char *s, Py_ssize_t size)
int
PyUnicode_FSConverter
(
PyObject
*
arg
,
void
*
addr
)
{
PyObject
*
path
=
NULL
;
PyObject
*
output
=
NULL
;
Py_ssize_t
size
;
void
*
data
;
...
...
@@ -3850,22 +3851,22 @@ PyUnicode_FSConverter(PyObject* arg, void* addr)
*
(
PyObject
**
)
addr
=
NULL
;
return
1
;
}
if
(
PyBytes_Check
(
arg
))
{
output
=
arg
;
Py_INCREF
(
output
)
;
path
=
PyOS_FSPath
(
arg
);
if
(
path
==
NULL
)
{
return
0
;
}
else
if
(
PyUnicode_Check
(
arg
))
{
output
=
PyUnicode_EncodeFSDefault
(
arg
);
if
(
!
output
)
if
(
PyBytes_Check
(
path
))
{
output
=
path
;
}
else
{
// PyOS_FSPath() guarantees its returned value is bytes or str.
output
=
PyUnicode_EncodeFSDefault
(
path
);
Py_DECREF
(
path
);
if
(
!
output
)
{
return
0
;
}
assert
(
PyBytes_Check
(
output
));
}
else
{
PyErr_Format
(
PyExc_TypeError
,
"must be str or bytes, not %.100s"
,
Py_TYPE
(
arg
)
->
tp_name
);
return
0
;
}
size
=
PyBytes_GET_SIZE
(
output
);
data
=
PyBytes_AS_STRING
(
output
);
if
((
size_t
)
size
!=
strlen
(
data
))
{
...
...
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