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/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" @@ -391,6 +397,23 @@ 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/non-ASCII str/unicode cwds + + # test non absolute paths, os.getcwd/getcwdu are called + for path in ('cwd', '\xe7w\xf0'): + with test_support.TempCWD(path): + self.assertStr(posixpath.abspath("foo")) + self.assertStr(posixpath.abspath("f\xf2\xf2")) + for upath in (u'cwdu', u'\xe7w\xf0u'): + with test_support.TempCWD(upath): + self.assertUnicode(posixpath.abspath(u"fuu")) + self.assertUnicode(posixpath.abspath(u"f\xf9\xf9")) + + # 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):