diff --git a/Lib/test/test_genericpath.py b/Lib/test/test_genericpath.py index ec722f3c1e9..614f887dad0 100644 --- a/Lib/test/test_genericpath.py +++ b/Lib/test/test_genericpath.py @@ -1,38 +1,87 @@ +""" +Tests common to genericpath, macpath, ntpath and posixpath +""" + import unittest from test import support import os import genericpath -class AllCommonTest(unittest.TestCase): + +def safe_rmdir(dirname): + try: + os.rmdir(dirname) + except OSError: + pass + + +class GenericTest(unittest.TestCase): + # The path module to be tested + pathmodule = genericpath + common_attributes = ['commonprefix', 'getsize', 'getatime', 'getctime', + 'getmtime', 'exists', 'isdir', 'isfile'] + attributes = [] + + def test_no_argument(self): + for attr in self.common_attributes + self.attributes: + with self.assertRaises(TypeError): + getattr(self.pathmodule, attr)() + raise self.fail("{}.{}() did not raise a TypeError" + .format(self.pathmodule.__name__, attr)) def test_commonprefix(self): + commonprefix = self.pathmodule.commonprefix self.assertEqual( - genericpath.commonprefix([]), + commonprefix([]), "" ) self.assertEqual( - genericpath.commonprefix(["/home/swenson/spam", "/home/swen/spam"]), + commonprefix(["/home/swenson/spam", "/home/swen/spam"]), "/home/swen" ) self.assertEqual( - genericpath.commonprefix(["/home/swen/spam", "/home/swen/eggs"]), + commonprefix(["/home/swen/spam", "/home/swen/eggs"]), "/home/swen/" ) self.assertEqual( - genericpath.commonprefix(["/home/swen/spam", "/home/swen/spam"]), + commonprefix(["/home/swen/spam", "/home/swen/spam"]), "/home/swen/spam" ) + self.assertEqual( + commonprefix([b"/home/swenson/spam", b"/home/swen/spam"]), + b"/home/swen" + ) + self.assertEqual( + commonprefix([b"/home/swen/spam", b"/home/swen/eggs"]), + b"/home/swen/" + ) + self.assertEqual( + commonprefix([b"/home/swen/spam", b"/home/swen/spam"]), + b"/home/swen/spam" + ) + + testlist = ['', 'abc', 'Xbcd', 'Xb', 'XY', 'abcd', + 'aXc', 'abd', 'ab', 'aX', 'abcX'] + for s1 in testlist: + for s2 in testlist: + p = commonprefix([s1, s2]) + self.assertTrue(s1.startswith(p)) + self.assertTrue(s2.startswith(p)) + if s1 != s2: + n = len(p) + self.assertNotEqual(s1[n:n+1], s2[n:n+1]) + def test_getsize(self): f = open(support.TESTFN, "wb") try: f.write(b"foo") f.close() - self.assertEqual(genericpath.getsize(support.TESTFN), 3) + self.assertEqual(self.pathmodule.getsize(support.TESTFN), 3) finally: if not f.closed: f.close() - os.remove(support.TESTFN) + support.unlink(support.TESTFN) def test_time(self): f = open(support.TESTFN, "wb") @@ -48,134 +97,177 @@ class AllCommonTest(unittest.TestCase): self.assertEqual(d, b"foobar") self.assertLessEqual( - genericpath.getctime(support.TESTFN), - genericpath.getmtime(support.TESTFN) + self.pathmodule.getctime(support.TESTFN), + self.pathmodule.getmtime(support.TESTFN) ) finally: if not f.closed: f.close() - os.remove(support.TESTFN) + support.unlink(support.TESTFN) def test_exists(self): - self.assertIs(genericpath.exists(support.TESTFN), False) + self.assertIs(self.pathmodule.exists(support.TESTFN), False) f = open(support.TESTFN, "wb") try: f.write(b"foo") f.close() - self.assertIs(genericpath.exists(support.TESTFN), True) + self.assertIs(self.pathmodule.exists(support.TESTFN), True) + if not self.pathmodule == genericpath: + self.assertIs(self.pathmodule.lexists(support.TESTFN), + True) finally: if not f.close(): f.close() - try: - os.remove(support.TESTFN) - except os.error: - pass - - self.assertRaises(TypeError, genericpath.exists) + support.unlink(support.TESTFN) def test_isdir(self): - self.assertIs(genericpath.isdir(support.TESTFN), False) + self.assertIs(self.pathmodule.isdir(support.TESTFN), False) f = open(support.TESTFN, "wb") try: f.write(b"foo") f.close() - self.assertIs(genericpath.isdir(support.TESTFN), False) + self.assertIs(self.pathmodule.isdir(support.TESTFN), False) os.remove(support.TESTFN) os.mkdir(support.TESTFN) - self.assertIs(genericpath.isdir(support.TESTFN), True) + self.assertIs(self.pathmodule.isdir(support.TESTFN), True) os.rmdir(support.TESTFN) finally: if not f.close(): f.close() - try: - os.remove(support.TESTFN) - except os.error: - pass - try: - os.rmdir(support.TESTFN) - except os.error: - pass - - self.assertRaises(TypeError, genericpath.isdir) + support.unlink(support.TESTFN) + safe_rmdir(support.TESTFN) def test_isfile(self): - self.assertIs(genericpath.isfile(support.TESTFN), False) + self.assertIs(self.pathmodule.isfile(support.TESTFN), False) f = open(support.TESTFN, "wb") try: f.write(b"foo") f.close() - self.assertIs(genericpath.isfile(support.TESTFN), True) + self.assertIs(self.pathmodule.isfile(support.TESTFN), True) os.remove(support.TESTFN) os.mkdir(support.TESTFN) - self.assertIs(genericpath.isfile(support.TESTFN), False) + self.assertIs(self.pathmodule.isfile(support.TESTFN), False) os.rmdir(support.TESTFN) finally: if not f.close(): f.close() - try: - os.remove(support.TESTFN) - except os.error: - pass - try: - os.rmdir(support.TESTFN) - except os.error: - pass + support.unlink(support.TESTFN) + safe_rmdir(support.TESTFN) - self.assertRaises(TypeError, genericpath.isdir) - def test_samefile(self): - f = open(support.TESTFN + "1", "wb") - try: - f.write(b"foo") - f.close() - self.assertIs( - genericpath.samefile( - support.TESTFN + "1", - support.TESTFN + "1" - ), - True - ) - # If we don't have links, assume that os.stat doesn't return resonable - # inode information and thus, that samefile() doesn't work - if hasattr(os, "symlink"): - os.symlink( - support.TESTFN + "1", - support.TESTFN + "2" - ) - self.assertIs( - genericpath.samefile( - support.TESTFN + "1", - support.TESTFN + "2" - ), - True - ) - os.remove(support.TESTFN + "2") - f = open(support.TESTFN + "2", "wb") - f.write(b"bar") - f.close() - self.assertIs( - genericpath.samefile( - support.TESTFN + "1", - support.TESTFN + "2" - ), - False - ) - finally: - if not f.close(): - f.close() - try: - os.remove(support.TESTFN + "1") - except os.error: - pass - try: - os.remove(support.TESTFN + "2") - except os.error: - pass +class CommonTest(GenericTest): + # The path module to be tested + pathmodule = None + common_attributes = GenericTest.common_attributes + [ + # Properties + 'curdir', 'pardir', 'extsep', 'sep', + 'pathsep', 'defpath', 'altsep', 'devnull', + # Methods + 'normcase', 'splitdrive', 'expandvars', 'normpath', 'abspath', + 'join', 'split', 'splitext', 'isabs', 'basename', 'dirname', + 'lexists', 'islink', 'ismount', 'expanduser', 'normpath', 'realpath', + ] + + def test_normcase(self): + # Check that normcase() is idempotent + p = "FoO/./BaR" + p = self.pathmodule.normcase(p) + self.assertEqual(p, self.pathmodule.normcase(p)) + + p = b"FoO/./BaR" + p = self.pathmodule.normcase(p) + self.assertEqual(p, self.pathmodule.normcase(p)) + + def test_splitdrive(self): + # splitdrive for non-NT paths + splitdrive = self.pathmodule.splitdrive + self.assertEqual(splitdrive("/foo/bar"), ("", "/foo/bar")) + self.assertEqual(splitdrive("foo:bar"), ("", "foo:bar")) + self.assertEqual(splitdrive(":foo:bar"), ("", ":foo:bar")) + + self.assertEqual(splitdrive(b"/foo/bar"), (b"", b"/foo/bar")) + self.assertEqual(splitdrive(b"foo:bar"), (b"", b"foo:bar")) + self.assertEqual(splitdrive(b":foo:bar"), (b"", b":foo:bar")) + + def test_expandvars(self): + if self.pathmodule.__name__ == 'macpath': + self.skipTest('macpath.expandvars is a stub') + expandvars = self.pathmodule.expandvars + with support.EnvironmentVarGuard() as env: + env.clear() + env["foo"] = "bar" + env["{foo"] = "baz1" + env["{foo}"] = "baz2" + self.assertEqual(expandvars("foo"), "foo") + self.assertEqual(expandvars("$foo bar"), "bar bar") + self.assertEqual(expandvars("${foo}bar"), "barbar") + self.assertEqual(expandvars("$[foo]bar"), "$[foo]bar") + self.assertEqual(expandvars("$bar bar"), "$bar bar") + self.assertEqual(expandvars("$?bar"), "$?bar") + self.assertEqual(expandvars("${foo}bar"), "barbar") + self.assertEqual(expandvars("$foo}bar"), "bar}bar") + self.assertEqual(expandvars("${foo"), "${foo") + self.assertEqual(expandvars("${{foo}}"), "baz1}") + self.assertEqual(expandvars("$foo$foo"), "barbar") + self.assertEqual(expandvars("$bar$bar"), "$bar$bar") + + self.assertEqual(expandvars(b"foo"), b"foo") + self.assertEqual(expandvars(b"$foo bar"), b"bar bar") + self.assertEqual(expandvars(b"${foo}bar"), b"barbar") + self.assertEqual(expandvars(b"$[foo]bar"), b"$[foo]bar") + self.assertEqual(expandvars(b"$bar bar"), b"$bar bar") + self.assertEqual(expandvars(b"$?bar"), b"$?bar") + self.assertEqual(expandvars(b"${foo}bar"), b"barbar") + self.assertEqual(expandvars(b"$foo}bar"), b"bar}bar") + self.assertEqual(expandvars(b"${foo"), b"${foo") + self.assertEqual(expandvars(b"${{foo}}"), b"baz1}") + self.assertEqual(expandvars(b"$foo$foo"), b"barbar") + self.assertEqual(expandvars(b"$bar$bar"), b"$bar$bar") + + def test_abspath(self): + self.assertIn("foo", self.pathmodule.abspath("foo")) + self.assertIn(b"foo", self.pathmodule.abspath(b"foo")) + + # Abspath returns bytes when the arg is bytes + for path in (b'', b'foo', b'f\xf2\xf2', b'/foo', b'C:\\'): + self.assertIsInstance(self.pathmodule.abspath(path), bytes) + + def test_realpath(self): + self.assertIn("foo", self.pathmodule.realpath("foo")) + self.assertIn(b"foo", self.pathmodule.realpath(b"foo")) + + def test_normpath_issue5827(self): + # Make sure normpath preserves unicode + for path in ('', '.', '/', '\\', '///foo/.//bar//'): + self.assertIsInstance(self.pathmodule.normpath(path), str) + + def test_abspath_issue3426(self): + # Check that abspath returns unicode when the arg is unicode + # with both ASCII and non-ASCII cwds. + abspath = self.pathmodule.abspath + for path in ('', 'fuu', 'f\xf9\xf9', '/fuu', 'U:\\'): + self.assertIsInstance(abspath(path), str) + + unicwd = '\xe7w\xf0' + try: + fsencoding = support.TESTFN_ENCODING or "ascii" + unicwd.encode(fsencoding) + except (AttributeError, UnicodeEncodeError): + # FS encoding is probably ASCII + pass + else: + with support.temp_cwd(unicwd): + for path in ('', 'fuu', 'f\xf9\xf9', '/fuu', 'U:\\'): + self.assertIsInstance(abspath(path), str) + + # Test non-ASCII, non-UTF8 bytes in the path. + with support.temp_cwd('\xe7w\xf0'): + self.test_abspath() - self.assertRaises(TypeError, genericpath.samefile) def test_main(): - support.run_unittest(AllCommonTest) + support.run_unittest(GenericTest) + if __name__=="__main__": test_main() diff --git a/Lib/test/test_macpath.py b/Lib/test/test_macpath.py index 2c737583274..b36ba005d11 100644 --- a/Lib/test/test_macpath.py +++ b/Lib/test/test_macpath.py @@ -1,5 +1,5 @@ import macpath -from test import support +from test import support, test_genericpath import unittest @@ -139,8 +139,13 @@ class MacPathTestCase(unittest.TestCase): self.assertEqual(normpath(b"a:"), b"a:") self.assertEqual(normpath(b"a:b:"), b"a:b") + +class MacCommonTest(test_genericpath.CommonTest): + pathmodule = macpath + + def test_main(): - support.run_unittest(MacPathTestCase) + support.run_unittest(MacPathTestCase, MacCommonTest) if __name__ == "__main__": diff --git a/Lib/test/test_ntpath.py b/Lib/test/test_ntpath.py index 94a7d9e14ef..c83b45f3e3e 100644 --- a/Lib/test/test_ntpath.py +++ b/Lib/test/test_ntpath.py @@ -1,7 +1,7 @@ import ntpath import os from test.support import verbose, TestFailed -import test.support as support +from test import support, test_genericpath import unittest @@ -174,7 +174,6 @@ class TestNtpath(unittest.TestCase): tester("ntpath.normpath('C:////a/b')", r'C:\a\b') tester("ntpath.normpath('//machine/share//a/b')", r'\\machine\share\a\b') - def test_expandvars(self): with support.EnvironmentVarGuard() as env: env.clear() @@ -236,8 +235,13 @@ class TestNtpath(unittest.TestCase): tester('ntpath.relpath("/a/b", "/a/b")', '.') +class NtCommonTest(test_genericpath.CommonTest): + pathmodule = ntpath + attributes = ['relpath', 'splitunc'] + + def test_main(): - support.run_unittest(TestNtpath) + support.run_unittest(TestNtpath, NtCommonTest) if __name__ == "__main__": diff --git a/Lib/test/test_posixpath.py b/Lib/test/test_posixpath.py index 1b1167a0061..2d845a822ac 100644 --- a/Lib/test/test_posixpath.py +++ b/Lib/test/test_posixpath.py @@ -1,5 +1,5 @@ import unittest -from test import support +from test import support, test_genericpath import posixpath, os from posixpath import realpath, abspath, join, dirname, basename, relpath @@ -25,16 +25,6 @@ class PosixPathTest(unittest.TestCase): support.unlink(support.TESTFN + suffix) safe_rmdir(support.TESTFN + suffix) - def test_normcase(self): - # Check that normcase() is idempotent - p = "FoO/./BaR" - self.assertEqual(p, posixpath.normcase(p)) - - p = b"FoO/./BaR" - self.assertEqual(p, posixpath.normcase(p)) - - self.assertRaises(TypeError, posixpath.normcase) - def test_join(self): self.assertEqual(posixpath.join("/foo", "bar", "/bar", "baz"), "/bar/baz") @@ -49,16 +39,9 @@ class PosixPathTest(unittest.TestCase): self.assertEqual(posixpath.join(b"/foo/", b"bar/", b"baz/"), b"/foo/bar/baz/") - self.assertRaises(TypeError, posixpath.join) self.assertRaises(TypeError, posixpath.join, b"bytes", "str") self.assertRaises(TypeError, posixpath.join, "str", b"bytes") - def test_splitdrive(self): - self.assertEqual(posixpath.splitdrive("/foo/bar"), ("", "/foo/bar")) - self.assertEqual(posixpath.splitdrive(b"/foo/bar"), (b"", b"/foo/bar")) - - self.assertRaises(TypeError, posixpath.splitdrive) - def test_split(self): self.assertEqual(posixpath.split("/foo/bar"), ("/foo", "bar")) self.assertEqual(posixpath.split("/"), ("/", "")) @@ -72,8 +55,6 @@ class PosixPathTest(unittest.TestCase): self.assertEqual(posixpath.split(b"////foo"), (b"////", b"foo")) self.assertEqual(posixpath.split(b"//foo//bar"), (b"//foo", b"bar")) - self.assertRaises(TypeError, posixpath.split) - def splitextTest(self, path, filename, ext): self.assertEqual(posixpath.splitext(path), (filename, ext)) self.assertEqual(posixpath.splitext("/" + path), ("/" + filename, ext)) @@ -115,7 +96,6 @@ class PosixPathTest(unittest.TestCase): self.splitextTest("..", "..", "") self.splitextTest("........", "........", "") self.splitextTest("", "", "") - self.assertRaises(TypeError, posixpath.splitext) def test_isabs(self): self.assertIs(posixpath.isabs(""), False) @@ -130,8 +110,6 @@ class PosixPathTest(unittest.TestCase): self.assertIs(posixpath.isabs(b"/foo/bar"), True) self.assertIs(posixpath.isabs(b"foo/bar"), False) - self.assertRaises(TypeError, posixpath.isabs) - def test_basename(self): self.assertEqual(posixpath.basename("/foo/bar"), "bar") self.assertEqual(posixpath.basename("/"), "") @@ -145,8 +123,6 @@ class PosixPathTest(unittest.TestCase): self.assertEqual(posixpath.basename(b"////foo"), b"foo") self.assertEqual(posixpath.basename(b"//foo//bar"), b"bar") - self.assertRaises(TypeError, posixpath.basename) - def test_dirname(self): self.assertEqual(posixpath.dirname("/foo/bar"), "/foo") self.assertEqual(posixpath.dirname("/"), "/") @@ -160,8 +136,6 @@ class PosixPathTest(unittest.TestCase): self.assertEqual(posixpath.dirname(b"////foo"), b"////") self.assertEqual(posixpath.dirname(b"//foo//bar"), b"//foo") - self.assertRaises(TypeError, posixpath.dirname) - def test_commonprefix(self): self.assertEqual( posixpath.commonprefix([]), @@ -252,56 +226,6 @@ class PosixPathTest(unittest.TestCase): if not f.close(): f.close() - self.assertRaises(TypeError, posixpath.islink) - - def test_exists(self): - self.assertIs(posixpath.exists(support.TESTFN), False) - f = open(support.TESTFN, "wb") - try: - f.write(b"foo") - f.close() - self.assertIs(posixpath.exists(support.TESTFN), True) - self.assertIs(posixpath.lexists(support.TESTFN), True) - finally: - if not f.close(): - f.close() - - self.assertRaises(TypeError, posixpath.exists) - - def test_isdir(self): - self.assertIs(posixpath.isdir(support.TESTFN), False) - f = open(support.TESTFN, "wb") - try: - f.write(b"foo") - f.close() - self.assertIs(posixpath.isdir(support.TESTFN), False) - os.remove(support.TESTFN) - os.mkdir(support.TESTFN) - self.assertIs(posixpath.isdir(support.TESTFN), True) - os.rmdir(support.TESTFN) - finally: - if not f.close(): - f.close() - - self.assertRaises(TypeError, posixpath.isdir) - - def test_isfile(self): - self.assertIs(posixpath.isfile(support.TESTFN), False) - f = open(support.TESTFN, "wb") - try: - f.write(b"foo") - f.close() - self.assertIs(posixpath.isfile(support.TESTFN), True) - os.remove(support.TESTFN) - os.mkdir(support.TESTFN) - self.assertIs(posixpath.isfile(support.TESTFN), False) - os.rmdir(support.TESTFN) - finally: - if not f.close(): - f.close() - - self.assertRaises(TypeError, posixpath.isdir) - def test_samefile(self): f = open(support.TESTFN + "1", "wb") try: @@ -343,8 +267,6 @@ class PosixPathTest(unittest.TestCase): if not f.close(): f.close() - self.assertRaises(TypeError, posixpath.samefile) - def test_samestat(self): f = open(support.TESTFN + "1", "wb") try: @@ -384,13 +306,9 @@ class PosixPathTest(unittest.TestCase): if not f.close(): f.close() - self.assertRaises(TypeError, posixpath.samestat) - def test_ismount(self): self.assertIs(posixpath.ismount("/"), True) - self.assertRaises(TypeError, posixpath.ismount) - def test_expanduser(self): self.assertEqual(posixpath.expanduser("foo"), "foo") self.assertEqual(posixpath.expanduser(b"foo"), b"foo") @@ -420,41 +338,6 @@ class PosixPathTest(unittest.TestCase): env['HOME'] = '/' self.assertEqual(posixpath.expanduser("~"), "/") - self.assertRaises(TypeError, posixpath.expanduser) - - def test_expandvars(self): - with support.EnvironmentVarGuard() as env: - env.clear() - env["foo"] = "bar" - env["{foo"] = "baz1" - env["{foo}"] = "baz2" - self.assertEqual(posixpath.expandvars("foo"), "foo") - self.assertEqual(posixpath.expandvars("$foo bar"), "bar bar") - self.assertEqual(posixpath.expandvars("${foo}bar"), "barbar") - self.assertEqual(posixpath.expandvars("$[foo]bar"), "$[foo]bar") - self.assertEqual(posixpath.expandvars("$bar bar"), "$bar bar") - self.assertEqual(posixpath.expandvars("$?bar"), "$?bar") - self.assertEqual(posixpath.expandvars("${foo}bar"), "barbar") - self.assertEqual(posixpath.expandvars("$foo}bar"), "bar}bar") - self.assertEqual(posixpath.expandvars("${foo"), "${foo") - self.assertEqual(posixpath.expandvars("${{foo}}"), "baz1}") - self.assertEqual(posixpath.expandvars("$foo$foo"), "barbar") - self.assertEqual(posixpath.expandvars("$bar$bar"), "$bar$bar") - - self.assertEqual(posixpath.expandvars(b"foo"), b"foo") - self.assertEqual(posixpath.expandvars(b"$foo bar"), b"bar bar") - self.assertEqual(posixpath.expandvars(b"${foo}bar"), b"barbar") - self.assertEqual(posixpath.expandvars(b"$[foo]bar"), b"$[foo]bar") - self.assertEqual(posixpath.expandvars(b"$bar bar"), b"$bar bar") - self.assertEqual(posixpath.expandvars(b"$?bar"), b"$?bar") - self.assertEqual(posixpath.expandvars(b"${foo}bar"), b"barbar") - self.assertEqual(posixpath.expandvars(b"$foo}bar"), b"bar}bar") - self.assertEqual(posixpath.expandvars(b"${foo"), b"${foo") - self.assertEqual(posixpath.expandvars(b"${{foo}}"), b"baz1}") - self.assertEqual(posixpath.expandvars(b"$foo$foo"), b"barbar") - self.assertEqual(posixpath.expandvars(b"$bar$bar"), b"$bar$bar") - self.assertRaises(TypeError, posixpath.expandvars) - def test_normpath(self): self.assertEqual(posixpath.normpath(""), ".") self.assertEqual(posixpath.normpath("/"), "/") @@ -475,19 +358,6 @@ class PosixPathTest(unittest.TestCase): self.assertEqual(posixpath.normpath(b"///..//./foo/.//bar"), b"/foo/bar") - self.assertRaises(TypeError, posixpath.normpath) - - def test_abspath(self): - self.assertIn("foo", posixpath.abspath("foo")) - self.assertIn(b"foo", posixpath.abspath(b"foo")) - - self.assertRaises(TypeError, posixpath.abspath) - - def test_realpath(self): - self.assertIn("foo", realpath("foo")) - self.assertIn(b"foo", realpath(b"foo")) - self.assertRaises(TypeError, posixpath.realpath) - if hasattr(os, "symlink"): def test_realpath_basic(self): # Basic operation. @@ -624,8 +494,15 @@ class PosixPathTest(unittest.TestCase): finally: os.getcwdb = real_getcwdb + +class PosixCommonTest(test_genericpath.CommonTest): + pathmodule = posixpath + attributes = ['relpath', 'samefile', 'sameopenfile', 'samestat'] + + def test_main(): - support.run_unittest(PosixPathTest) + support.run_unittest(PosixPathTest, PosixCommonTest) + if __name__=="__main__": test_main() diff --git a/Misc/NEWS b/Misc/NEWS index de9e4f2250d..70222809344 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -847,6 +847,9 @@ Documentation Tests ----- +- The four path modules (genericpath, macpath, ntpath, posixpath) share a + common TestCase for some tests: test_genericpath.CommonTest. + - Print platform information when running the whole test suite, or using the --verbose flag.