Index: Lib/posixpath.py =================================================================== --- Lib/posixpath.py (revision 77442) +++ 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 77442) +++ 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/test/test_ntpath.py =================================================================== --- Lib/test/test_ntpath.py (revision 77442) +++ Lib/test/test_ntpath.py (working copy) @@ -163,10 +163,29 @@ try: import nt except ImportError: - pass + # check that the function is there even if we are not on Windows + ntpath.abspath + # XXX this needs more tests else: tester('ntpath.abspath("C:\\")', "C:\\") + # XXX this needs more tests + # Issue 3426: check that abspath retuns unicode when the arg is + # unicode and str when it's str, with both ASCII/non-ASCII + # str/unicode cwds + + # test non absolute paths, os.getcwd/getcwdu are called + for cwd in (u'cwd', u'\xe7w\xf0'): + with test_support.TempCWD(cwd): + for path in ('', 'foo', 'C:\\foo', 'f\xf2\xf2'): + self.assertStr(ntpath.abspath(path)) + for upath in (u'', u'fuu', u'C:\\fuu', u'f\xf9\xf9'): + self.assertUnicode(ntpath.abspath(upath)) + + # test absolute paths, os.getcwd/getcwdu are not called + self.assertStr(ntpath.abspath("/foo")) + self.assertUnicode(ntpath.abspath(u"/foo")) + def test_relpath(self): currentdir = os.path.split(os.getcwd())[-1] tester('ntpath.relpath("a")', 'a') Index: Lib/test/test_support.py =================================================================== --- Lib/test/test_support.py (revision 77441) +++ 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 77442) +++ 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" @@ -389,8 +395,27 @@ self.assertRaises(TypeError, posixpath.normpath) def test_abspath(self): - self.assertTrue("foo" in posixpath.abspath("foo")) + self.assertTrue(posixpath.abspath('foo').endswith('foo')) + self.assertTrue(posixpath.abspath('foo/').endswith('foo')) + self.assertEqual(posixpath.abspath('/foo'), '/foo') + self.assertEqual(posixpath.abspath(''), os.getcwd()) + self.assertEqual(posixpath.abspath(u''), os.getcwdu()) + # Issue 3426: check that abspath retuns unicode when the arg is unicode + # and str when it's str, with both ASCII/non-ASCII str/unicode cwds + + # test non absolute paths, os.getcwd/getcwdu are called + for cwd in (u'cwd', u'\xe7w\xf0'): + with test_support.TempCWD(cwd): + for path in ('', 'foo', '/foo', 'f\xf2\xf2'): + self.assertStr(posixpath.abspath(path)) + for upath in (u'', u'fuu', u'/fuu', u'f\xf9\xf9'): + self.assertUnicode(posixpath.abspath(upath)) + + # test absolute paths, os.getcwd/getcwdu are not called + self.assertStr(posixpath.abspath("/foo")) + self.assertUnicode(posixpath.abspath(u"/foo")) + self.assertRaises(TypeError, posixpath.abspath) def test_realpath(self):