issue27182: update fsencode and fsdecode for os.path(); patch by Dusty Phillips

This commit is contained in:
Ethan Furman 2016-06-04 10:19:27 -07:00
parent 7a3827f61f
commit c1cbeedf0c
2 changed files with 29 additions and 8 deletions

View File

@ -877,29 +877,35 @@ def _fscodec():
def fsencode(filename):
"""
Encode filename to the filesystem encoding with 'surrogateescape' error
handler, return bytes unchanged. On Windows, use 'strict' error handler if
the file system encoding is 'mbcs' (which is the default encoding).
Encode filename (an os.PathLike, bytes, or str) to the filesystem
encoding with 'surrogateescape' error handler, return bytes unchanged.
On Windows, use 'strict' error handler if the file system encoding is
'mbcs' (which is the default encoding).
"""
filename = fspath(filename)
if isinstance(filename, bytes):
return filename
elif isinstance(filename, str):
return filename.encode(encoding, errors)
else:
raise TypeError("expect bytes or str, not %s" % type(filename).__name__)
raise TypeError("expected str, bytes or os.PathLike object, not "
+ path_type.__name__)
def fsdecode(filename):
"""
Decode filename from the filesystem encoding with 'surrogateescape' error
handler, return str unchanged. On Windows, use 'strict' error handler if
the file system encoding is 'mbcs' (which is the default encoding).
Decode filename (an os.PathLike, bytes, or str) from the filesystem
encoding with 'surrogateescape' error handler, return str unchanged. On
Windows, use 'strict' error handler if the file system encoding is
'mbcs' (which is the default encoding).
"""
filename = fspath(filename)
if isinstance(filename, str):
return filename
elif isinstance(filename, bytes):
return filename.decode(encoding, errors)
else:
raise TypeError("expect bytes or str, not %s" % type(filename).__name__)
raise TypeError("expected str, bytes or os.PathLike object, not "
+ path_type.__name__)
return fsencode, fsdecode

View File

@ -3106,6 +3106,21 @@ class TestPEP519(unittest.TestCase):
for s in 'hello', 'goodbye', 'some/path/and/file':
self.assertEqual(s, os.fspath(s))
def test_fsencode_fsdecode_return_pathlike(self):
class Pathlike:
def __init__(self, path):
self.path = path
def __fspath__(self):
return self.path
for p in "path/like/object", b"path/like/object":
pathlike = Pathlike(p)
self.assertEqual(p, os.fspath(pathlike))
self.assertEqual(b"path/like/object", os.fsencode(pathlike))
self.assertEqual("path/like/object", os.fsdecode(pathlike))
def test_garbage_in_exception_out(self):
vapor = type('blah', (), {})
for o in int, type, os, vapor():