Index: Lib/os2emxpath.py =================================================================== --- Lib/os2emxpath.py (revision 77513) +++ Lib/os2emxpath.py (working copy) @@ -146,7 +146,11 @@ def abspath(path): """Return the absolute version of a path""" if not isabs(path): - path = join(os.getcwd(), path) + if isinstance(path, unicode): + cwd = os.getcwdu() + else: + cwd = os.getcwd() + path = join(cwd, path) return normpath(path) # realpath is a no-op on systems without islink support Index: Lib/posixpath.py =================================================================== --- Lib/posixpath.py (revision 77513) +++ Lib/posixpath.py (working copy) @@ -337,7 +337,11 @@ def abspath(path): """Return an absolute path.""" if not isabs(path): - path = join(os.getcwd(), path) + if isinstance(path, unicode): + cwd = os.getcwdu() + else: + cwd = os.getcwd() + path = join(cwd, path) return normpath(path) Index: Lib/ntpath.py =================================================================== --- Lib/ntpath.py (revision 77513) +++ Lib/ntpath.py (working copy) @@ -449,7 +449,11 @@ def abspath(path): """Return the absolute version of a path.""" if not isabs(path): - path = join(os.getcwd(), path) + if isinstance(path, unicode): + cwd = os.getcwdu() + else: + cwd = os.getcwd() + path = join(cwd, path) return normpath(path) else: # use native Windows method on Windows @@ -461,6 +465,8 @@ path = _getfullpathname(path) except WindowsError: pass # Bad path - return unchanged. + elif isinstance(path, unicode): + path = os.getcwdu() else: path = os.getcwd() return normpath(path) Index: Lib/macpath.py =================================================================== --- Lib/macpath.py (revision 77513) +++ Lib/macpath.py (working copy) @@ -186,7 +186,11 @@ def abspath(path): """Return an absolute path.""" if not isabs(path): - path = join(os.getcwd(), path) + if isinstance(path, unicode): + cwd = os.getcwdu() + else: + cwd = os.getcwd() + path = join(cwd, path) return normpath(path) # realpath is a no-op on systems without islink support Index: Lib/test/test_ntpath.py =================================================================== --- Lib/test/test_ntpath.py (revision 77513) +++ Lib/test/test_ntpath.py (working copy) @@ -14,6 +14,13 @@ class TestNtpath(unittest.TestCase): + + def assertStr(self, s): + self.assertTrue(isinstance(s, str), '%r is not str' % s) + + def assertUnicode(self, s): + self.assertTrue(isinstance(s, unicode), '%r is not unicode' % s) + def test_splitext(self): tester('ntpath.splitext("foo.ext")', ('foo', '.ext')) tester('ntpath.splitext("/foo/foo.ext")', ('/foo/foo', '.ext')) @@ -160,13 +167,25 @@ # the rest of the tests for the ntpath module to be run to completion # on any platform, since most of the module is intended to be usable # from any platform. + # XXX this needs more tests try: import nt except ImportError: - pass + # check that the function is there even if we are not on Windows + ntpath.abspath else: tester('ntpath.abspath("C:\\")', "C:\\") + # Issue 3426: check that abspath retuns unicode when the arg is + # unicode and str when it's str, with both ASCII and non-ASCII cwds + for cwd in (u'cwd', u'\xe7w\xf0'): + with test_support.TempCWD(cwd): + for path in ('', 'foo', 'f\xf2\xf2', '/foo', 'C:\\'): + self.assertStr(ntpath.abspath(path)) + for upath in (u'', u'fuu', u'f\xf9\xf9', u'/fuu', u'U:\\'): + self.assertUnicode(ntpath.abspath(upath)) + + def test_relpath(self): currentdir = os.path.split(os.getcwd())[-1] tester('ntpath.relpath("a")', 'a') Index: Lib/test/test_macpath.py =================================================================== --- Lib/test/test_macpath.py (revision 77513) +++ Lib/test/test_macpath.py (working copy) @@ -5,9 +5,25 @@ class MacPathTestCase(unittest.TestCase): + def assertStr(self, s): + self.assertTrue(isinstance(s, str), '%r is not str' % s) + + def assertUnicode(self, s): + self.assertTrue(isinstance(s, unicode), '%r is not unicode' % s) + def test_abspath(self): self.assertTrue(macpath.abspath("xx:yy") == "xx:yy") + # Issue 3426: check that abspath retuns unicode when the arg is unicode + # and str when it's str, with both ASCII and non-ASCII cwds + for cwd in (u'cwd', u'\xe7w\xf0'): + with test_support.TempCWD(cwd): + for path in ('', 'foo', 'f\xf2\xf2', '/foo', 'C:\\'): + self.assertStr(macpath.abspath(path)) + for upath in (u'', u'fuu', u'f\xf9\xf9', u'/fuu', u'U:\\'): + self.assertUnicode(macpath.abspath(upath)) + + def test_isabs(self): isabs = macpath.isabs self.assertTrue(isabs("xx:yy")) Index: Lib/test/test_support.py =================================================================== --- Lib/test/test_support.py (revision 77513) +++ Lib/test/test_support.py (working copy) @@ -612,6 +612,22 @@ sys.path[:] = self.original_value +class TempCWD(object): + def __init__(self, dirname='tempdir'): + self.dirname = os.path.join(TESTFN, dirname) + self._oldcwd = os.getcwd() + + def __enter__(self): + if not os.path.exists(self.dirname): + os.makedirs(self.dirname) + os.chdir(self.dirname) + return self.dirname + + def __exit__(self, exc, value, tb): + os.chdir(self._oldcwd) + rmtree(os.path.dirname(self.dirname)) + + class TransientResource(object): """Raise ResourceDenied if an exception is raised while the context manager Index: Lib/test/test_posixpath.py =================================================================== --- Lib/test/test_posixpath.py (revision 77513) +++ Lib/test/test_posixpath.py (working copy) @@ -28,6 +28,12 @@ def assertIs(self, a, b): self.assertTrue(a is b) + def assertStr(self, s): + self.assertTrue(isinstance(s, str), '%r is not str' % s) + + def assertUnicode(self, s): + self.assertTrue(isinstance(s, unicode), '%r is not unicode' % s) + def test_normcase(self): # Check that normcase() is idempotent p = "FoO/./BaR" @@ -391,6 +397,15 @@ def test_abspath(self): self.assertTrue("foo" in posixpath.abspath("foo")) + # Issue 3426: check that abspath retuns unicode when the arg is unicode + # and str when it's str, with both ASCII and non-ASCII cwds + for cwd in (u'cwd', u'\xe7w\xf0'): + with test_support.TempCWD(cwd): + for path in ('', 'foo', 'f\xf2\xf2', '/foo', 'C:\\'): + self.assertStr(posixpath.abspath(path)) + for upath in (u'', u'fuu', u'f\xf9\xf9', u'/fuu', u'U:\\'): + self.assertUnicode(posixpath.abspath(upath)) + self.assertRaises(TypeError, posixpath.abspath) def test_realpath(self):