#5827: make sure that normpath preserves unicode

This commit is contained in:
Ezio Melotti 2010-01-12 03:32:05 +00:00
parent 58a96efde5
commit b5689de044
5 changed files with 25 additions and 8 deletions

View File

@ -397,6 +397,8 @@ def expandvars(path):
def normpath(path): def normpath(path):
"""Normalize path, eliminating double slashes, etc.""" """Normalize path, eliminating double slashes, etc."""
# Preserve unicode (if path is unicode)
backslash, dot = (u'\\', u'.') if isinstance(path, unicode) else ('\\', '.')
path = path.replace("/", "\\") path = path.replace("/", "\\")
prefix, path = splitdrive(path) prefix, path = splitdrive(path)
# We need to be careful here. If the prefix is empty, and the path starts # We need to be careful here. If the prefix is empty, and the path starts
@ -411,12 +413,12 @@ def normpath(path):
if prefix == '': if prefix == '':
# No drive letter - preserve initial backslashes # No drive letter - preserve initial backslashes
while path[:1] == "\\": while path[:1] == "\\":
prefix = prefix + "\\" prefix = prefix + backslash
path = path[1:] path = path[1:]
else: else:
# We have a drive letter - collapse initial backslashes # We have a drive letter - collapse initial backslashes
if path.startswith("\\"): if path.startswith("\\"):
prefix = prefix + "\\" prefix = prefix + backslash
path = path.lstrip("\\") path = path.lstrip("\\")
comps = path.split("\\") comps = path.split("\\")
i = 0 i = 0
@ -435,8 +437,8 @@ def normpath(path):
i += 1 i += 1
# If the path is now empty, substitute '.' # If the path is now empty, substitute '.'
if not prefix and not comps: if not prefix and not comps:
comps.append('.') comps.append(dot)
return prefix + "\\".join(comps) return prefix + backslash.join(comps)
# Return an absolute path. # Return an absolute path.

View File

@ -307,8 +307,10 @@ def expandvars(path):
def normpath(path): def normpath(path):
"""Normalize path, eliminating double slashes, etc.""" """Normalize path, eliminating double slashes, etc."""
# Preserve unicode (if path is unicode)
slash, dot = (u'/', u'.') if isinstance(path, unicode) else ('/', '.')
if path == '': if path == '':
return '.' return dot
initial_slashes = path.startswith('/') initial_slashes = path.startswith('/')
# POSIX allows one or two initial slashes, but treats three or more # POSIX allows one or two initial slashes, but treats three or more
# as single slash. # as single slash.
@ -326,10 +328,10 @@ def normpath(path):
elif new_comps: elif new_comps:
new_comps.pop() new_comps.pop()
comps = new_comps comps = new_comps
path = '/'.join(comps) path = slash.join(comps)
if initial_slashes: if initial_slashes:
path = '/'*initial_slashes + path path = slash*initial_slashes + path
return path or '.' return path or dot
def abspath(path): def abspath(path):

View File

@ -123,6 +123,11 @@ class TestNtpath(unittest.TestCase):
tester("ntpath.normpath('C:////a/b')", r'C:\a\b') tester("ntpath.normpath('C:////a/b')", r'C:\a\b')
tester("ntpath.normpath('//machine/share//a/b')", r'\\machine\share\a\b') tester("ntpath.normpath('//machine/share//a/b')", r'\\machine\share\a\b')
# Issue 5827: Make sure normpath preserves unicode
for path in (u'', u'.', u'/', u'\\', u'///foo/.//bar//'):
self.assertTrue(isinstance(ntpath.normpath(path), unicode),
'normpath() returned str instead of unicode')
def test_expandvars(self): def test_expandvars(self):
with test_support.EnvironmentVarGuard() as env: with test_support.EnvironmentVarGuard() as env:
env.clear() env.clear()

View File

@ -381,6 +381,11 @@ class PosixPathTest(unittest.TestCase):
self.assertEqual(posixpath.normpath("///foo/.//bar//.//..//.//baz"), "/foo/baz") self.assertEqual(posixpath.normpath("///foo/.//bar//.//..//.//baz"), "/foo/baz")
self.assertEqual(posixpath.normpath("///..//./foo/.//bar"), "/foo/bar") self.assertEqual(posixpath.normpath("///..//./foo/.//bar"), "/foo/bar")
# Issue 5827: Make sure normpath preserves unicode
for path in (u'', u'.', u'/', u'\\', u'///foo/.//bar//'):
self.assertTrue(isinstance(posixpath.normpath(path), unicode),
'normpath() returned str instead of unicode')
self.assertRaises(TypeError, posixpath.normpath) self.assertRaises(TypeError, posixpath.normpath)
def test_abspath(self): def test_abspath(self):

View File

@ -23,6 +23,9 @@ Core and Builtins
Library Library
------- -------
- Issue #5827: Make sure that normpath preserves unicode. Initial patch
by Matt Giuca.
- Issue #5372: Drop the reuse of .o files in Distutils' ccompiler (since - Issue #5372: Drop the reuse of .o files in Distutils' ccompiler (since
Extension extra options may change the output without changing the .c Extension extra options may change the output without changing the .c
file). Initial patch by Collin Winter. file). Initial patch by Collin Winter.