mirror of
				https://github.com/python/cpython.git
				synced 2025-10-31 18:28:49 +00:00 
			
		
		
		
	 d716ea34cb
			
		
	
	
		d716ea34cb
		
			
		
	
	
	
	
		
			
			When `pathlib._os.magic_open()` is called to open a path in binary mode, raise `ValueError` if any of the *encoding*, *errors* or *newline* arguments are given. This matches the `open()` built-in.
		
			
				
	
	
		
			321 lines
		
	
	
	
		
			14 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			321 lines
		
	
	
	
		
			14 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
| """
 | |
| Tests for pathlib.types._ReadablePath
 | |
| """
 | |
| 
 | |
| import collections.abc
 | |
| import io
 | |
| import unittest
 | |
| 
 | |
| from .support import is_pypi
 | |
| from .support.local_path import ReadableLocalPath, LocalPathGround
 | |
| from .support.zip_path import ReadableZipPath, ZipPathGround
 | |
| 
 | |
| if is_pypi:
 | |
|     from pathlib_abc import PathInfo, _ReadablePath
 | |
|     from pathlib_abc._os import magic_open
 | |
| else:
 | |
|     from pathlib.types import PathInfo, _ReadablePath
 | |
|     from pathlib._os import magic_open
 | |
| 
 | |
| 
 | |
| class ReadTestBase:
 | |
|     def setUp(self):
 | |
|         self.root = self.ground.setup()
 | |
|         self.ground.create_hierarchy(self.root)
 | |
| 
 | |
|     def tearDown(self):
 | |
|         self.ground.teardown(self.root)
 | |
| 
 | |
|     def test_is_readable(self):
 | |
|         self.assertIsInstance(self.root, _ReadablePath)
 | |
| 
 | |
|     def test_open_r(self):
 | |
|         p = self.root / 'fileA'
 | |
|         with magic_open(p, 'r') as f:
 | |
|             self.assertIsInstance(f, io.TextIOBase)
 | |
|             self.assertEqual(f.read(), 'this is file A\n')
 | |
| 
 | |
|     def test_open_rb(self):
 | |
|         p = self.root / 'fileA'
 | |
|         with magic_open(p, 'rb') as f:
 | |
|             self.assertEqual(f.read(), b'this is file A\n')
 | |
|         self.assertRaises(ValueError, magic_open, p, 'rb', encoding='utf8')
 | |
|         self.assertRaises(ValueError, magic_open, p, 'rb', errors='strict')
 | |
|         self.assertRaises(ValueError, magic_open, p, 'rb', newline='')
 | |
| 
 | |
|     def test_read_bytes(self):
 | |
|         p = self.root / 'fileA'
 | |
|         self.assertEqual(p.read_bytes(), b'this is file A\n')
 | |
| 
 | |
|     def test_read_text(self):
 | |
|         p = self.root / 'fileA'
 | |
|         self.assertEqual(p.read_text(), 'this is file A\n')
 | |
|         q = self.root / 'abc'
 | |
|         self.ground.create_file(q, b'\xe4bcdefg')
 | |
|         self.assertEqual(q.read_text(encoding='latin-1'), 'äbcdefg')
 | |
|         self.assertEqual(q.read_text(encoding='utf-8', errors='ignore'), 'bcdefg')
 | |
| 
 | |
|     def test_read_text_with_newlines(self):
 | |
|         p = self.root / 'abc'
 | |
|         self.ground.create_file(p, b'abcde\r\nfghlk\n\rmnopq')
 | |
|         # Check that `\n` character change nothing
 | |
|         self.assertEqual(p.read_text(newline='\n'), 'abcde\r\nfghlk\n\rmnopq')
 | |
|         # Check that `\r` character replaces `\n`
 | |
|         self.assertEqual(p.read_text(newline='\r'), 'abcde\r\nfghlk\n\rmnopq')
 | |
|         # Check that `\r\n` character replaces `\n`
 | |
|         self.assertEqual(p.read_text(newline='\r\n'), 'abcde\r\nfghlk\n\rmnopq')
 | |
| 
 | |
|     def test_iterdir(self):
 | |
|         expected = ['dirA', 'dirB', 'dirC', 'fileA']
 | |
|         if self.ground.can_symlink:
 | |
|             expected += ['linkA', 'linkB', 'brokenLink', 'brokenLinkLoop']
 | |
|         expected = {self.root.joinpath(name) for name in expected}
 | |
|         actual = set(self.root.iterdir())
 | |
|         self.assertEqual(actual, expected)
 | |
| 
 | |
|     def test_iterdir_nodir(self):
 | |
|         p = self.root / 'fileA'
 | |
|         self.assertRaises(OSError, p.iterdir)
 | |
| 
 | |
|     def test_iterdir_info(self):
 | |
|         for child in self.root.iterdir():
 | |
|             self.assertIsInstance(child.info, PathInfo)
 | |
|             self.assertTrue(child.info.exists(follow_symlinks=False))
 | |
| 
 | |
|     def test_glob(self):
 | |
|         if not self.ground.can_symlink:
 | |
|             self.skipTest("requires symlinks")
 | |
| 
 | |
|         p = self.root
 | |
|         sep = self.root.parser.sep
 | |
|         altsep = self.root.parser.altsep
 | |
|         def check(pattern, expected):
 | |
|             if altsep:
 | |
|                 expected = {name.replace(altsep, sep) for name in expected}
 | |
|             expected = {p.joinpath(name) for name in expected}
 | |
|             actual = set(p.glob(pattern, recurse_symlinks=True))
 | |
|             self.assertEqual(actual, expected)
 | |
| 
 | |
|         it = p.glob("fileA")
 | |
|         self.assertIsInstance(it, collections.abc.Iterator)
 | |
|         self.assertEqual(list(it), [p.joinpath("fileA")])
 | |
|         check("*A", ["dirA", "fileA", "linkA"])
 | |
|         check("*A", ['dirA', 'fileA', 'linkA'])
 | |
|         check("*B/*", ["dirB/fileB", "linkB/fileB"])
 | |
|         check("*B/*", ['dirB/fileB', 'linkB/fileB'])
 | |
|         check("brokenLink", ['brokenLink'])
 | |
|         check("brokenLinkLoop", ['brokenLinkLoop'])
 | |
|         check("**/", ["", "dirA/", "dirA/linkC/", "dirB/", "dirC/", "dirC/dirD/", "linkB/"])
 | |
|         check("**/*/", ["dirA/", "dirA/linkC/", "dirB/", "dirC/", "dirC/dirD/", "linkB/"])
 | |
|         check("*/", ["dirA/", "dirB/", "dirC/", "linkB/"])
 | |
|         check("*/dirD/**/", ["dirC/dirD/"])
 | |
|         check("*/dirD/**", ["dirC/dirD/", "dirC/dirD/fileD"])
 | |
|         check("dir*/**", ["dirA/", "dirA/linkC", "dirA/linkC/fileB", "dirB/", "dirB/fileB", "dirC/",
 | |
|                           "dirC/fileC", "dirC/dirD", "dirC/dirD/fileD", "dirC/novel.txt"])
 | |
|         check("dir*/**/", ["dirA/", "dirA/linkC/", "dirB/", "dirC/", "dirC/dirD/"])
 | |
|         check("dir*/**/..", ["dirA/..", "dirA/linkC/..", "dirB/..", "dirC/..", "dirC/dirD/.."])
 | |
|         check("dir*/*/**", ["dirA/linkC/", "dirA/linkC/fileB", "dirC/dirD/", "dirC/dirD/fileD"])
 | |
|         check("dir*/*/**/", ["dirA/linkC/", "dirC/dirD/"])
 | |
|         check("dir*/*/**/..", ["dirA/linkC/..", "dirC/dirD/.."])
 | |
|         check("dir*/*/..", ["dirC/dirD/..", "dirA/linkC/.."])
 | |
|         check("dir*/*/../dirD/**/", ["dirC/dirD/../dirD/"])
 | |
|         check("dir*/**/fileC", ["dirC/fileC"])
 | |
|         check("dir*/file*", ["dirB/fileB", "dirC/fileC"])
 | |
|         check("**/*/fileA", [])
 | |
|         check("fileB", [])
 | |
|         check("**/*/fileB", ["dirB/fileB", "dirA/linkC/fileB", "linkB/fileB"])
 | |
|         check("**/fileB", ["dirB/fileB", "dirA/linkC/fileB", "linkB/fileB"])
 | |
|         check("*/fileB", ["dirB/fileB", "linkB/fileB"])
 | |
|         check("*/fileB", ['dirB/fileB', 'linkB/fileB'])
 | |
|         check("**/file*",
 | |
|               ["fileA", "dirA/linkC/fileB", "dirB/fileB", "dirC/fileC", "dirC/dirD/fileD",
 | |
|                "linkB/fileB"])
 | |
|         with self.assertRaisesRegex(ValueError, 'Unacceptable pattern'):
 | |
|             list(p.glob(''))
 | |
| 
 | |
|     def test_walk_top_down(self):
 | |
|         it = self.root.walk()
 | |
| 
 | |
|         path, dirnames, filenames = next(it)
 | |
|         dirnames.sort()
 | |
|         filenames.sort()
 | |
|         self.assertEqual(path, self.root)
 | |
|         self.assertEqual(dirnames, ['dirA', 'dirB', 'dirC'])
 | |
|         self.assertEqual(filenames, ['brokenLink', 'brokenLinkLoop', 'fileA', 'linkA', 'linkB']
 | |
|                                     if self.ground.can_symlink else ['fileA'])
 | |
| 
 | |
|         path, dirnames, filenames = next(it)
 | |
|         self.assertEqual(path, self.root / 'dirA')
 | |
|         self.assertEqual(dirnames, [])
 | |
|         self.assertEqual(filenames, ['linkC'] if self.ground.can_symlink else [])
 | |
| 
 | |
|         path, dirnames, filenames = next(it)
 | |
|         self.assertEqual(path, self.root / 'dirB')
 | |
|         self.assertEqual(dirnames, [])
 | |
|         self.assertEqual(filenames, ['fileB'])
 | |
| 
 | |
|         path, dirnames, filenames = next(it)
 | |
|         filenames.sort()
 | |
|         self.assertEqual(path, self.root / 'dirC')
 | |
|         self.assertEqual(dirnames, ['dirD'])
 | |
|         self.assertEqual(filenames, ['fileC', 'novel.txt'])
 | |
| 
 | |
|         path, dirnames, filenames = next(it)
 | |
|         self.assertEqual(path, self.root / 'dirC' / 'dirD')
 | |
|         self.assertEqual(dirnames, [])
 | |
|         self.assertEqual(filenames, ['fileD'])
 | |
| 
 | |
|         self.assertRaises(StopIteration, next, it)
 | |
| 
 | |
|     def test_walk_prune(self):
 | |
|         expected = {self.root, self.root / 'dirA', self.root / 'dirC', self.root / 'dirC' / 'dirD'}
 | |
|         actual = set()
 | |
|         for path, dirnames, filenames in self.root.walk():
 | |
|             actual.add(path)
 | |
|             if path == self.root:
 | |
|                 dirnames.remove('dirB')
 | |
|         self.assertEqual(actual, expected)
 | |
| 
 | |
|     def test_walk_bottom_up(self):
 | |
|         seen_root = seen_dira = seen_dirb = seen_dirc = seen_dird = False
 | |
|         for path, dirnames, filenames in self.root.walk(top_down=False):
 | |
|             if path == self.root:
 | |
|                 self.assertFalse(seen_root)
 | |
|                 self.assertTrue(seen_dira)
 | |
|                 self.assertTrue(seen_dirb)
 | |
|                 self.assertTrue(seen_dirc)
 | |
|                 self.assertEqual(sorted(dirnames), ['dirA', 'dirB', 'dirC'])
 | |
|                 self.assertEqual(sorted(filenames),
 | |
|                                  ['brokenLink', 'brokenLinkLoop', 'fileA', 'linkA', 'linkB']
 | |
|                                  if self.ground.can_symlink else ['fileA'])
 | |
|                 seen_root = True
 | |
|             elif path == self.root / 'dirA':
 | |
|                 self.assertFalse(seen_root)
 | |
|                 self.assertFalse(seen_dira)
 | |
|                 self.assertEqual(dirnames, [])
 | |
|                 self.assertEqual(filenames, ['linkC'] if self.ground.can_symlink else [])
 | |
|                 seen_dira = True
 | |
|             elif path == self.root / 'dirB':
 | |
|                 self.assertFalse(seen_root)
 | |
|                 self.assertFalse(seen_dirb)
 | |
|                 self.assertEqual(dirnames, [])
 | |
|                 self.assertEqual(filenames, ['fileB'])
 | |
|                 seen_dirb = True
 | |
|             elif path == self.root / 'dirC':
 | |
|                 self.assertFalse(seen_root)
 | |
|                 self.assertFalse(seen_dirc)
 | |
|                 self.assertTrue(seen_dird)
 | |
|                 self.assertEqual(dirnames, ['dirD'])
 | |
|                 self.assertEqual(sorted(filenames), ['fileC', 'novel.txt'])
 | |
|                 seen_dirc = True
 | |
|             elif path == self.root / 'dirC' / 'dirD':
 | |
|                 self.assertFalse(seen_root)
 | |
|                 self.assertFalse(seen_dirc)
 | |
|                 self.assertFalse(seen_dird)
 | |
|                 self.assertEqual(dirnames, [])
 | |
|                 self.assertEqual(filenames, ['fileD'])
 | |
|                 seen_dird = True
 | |
|             else:
 | |
|                 raise AssertionError(f"Unexpected path: {path}")
 | |
|         self.assertTrue(seen_root)
 | |
| 
 | |
|     def test_info_exists(self):
 | |
|         p = self.root
 | |
|         self.assertTrue(p.info.exists())
 | |
|         self.assertTrue((p / 'dirA').info.exists())
 | |
|         self.assertTrue((p / 'dirA').info.exists(follow_symlinks=False))
 | |
|         self.assertTrue((p / 'fileA').info.exists())
 | |
|         self.assertTrue((p / 'fileA').info.exists(follow_symlinks=False))
 | |
|         self.assertFalse((p / 'non-existing').info.exists())
 | |
|         self.assertFalse((p / 'non-existing').info.exists(follow_symlinks=False))
 | |
|         if self.ground.can_symlink:
 | |
|             self.assertTrue((p / 'linkA').info.exists())
 | |
|             self.assertTrue((p / 'linkA').info.exists(follow_symlinks=False))
 | |
|             self.assertTrue((p / 'linkB').info.exists())
 | |
|             self.assertTrue((p / 'linkB').info.exists(follow_symlinks=True))
 | |
|             self.assertFalse((p / 'brokenLink').info.exists())
 | |
|             self.assertTrue((p / 'brokenLink').info.exists(follow_symlinks=False))
 | |
|             self.assertFalse((p / 'brokenLinkLoop').info.exists())
 | |
|             self.assertTrue((p / 'brokenLinkLoop').info.exists(follow_symlinks=False))
 | |
|         self.assertFalse((p / 'fileA\udfff').info.exists())
 | |
|         self.assertFalse((p / 'fileA\udfff').info.exists(follow_symlinks=False))
 | |
|         self.assertFalse((p / 'fileA\x00').info.exists())
 | |
|         self.assertFalse((p / 'fileA\x00').info.exists(follow_symlinks=False))
 | |
| 
 | |
|     def test_info_is_dir(self):
 | |
|         p = self.root
 | |
|         self.assertTrue((p / 'dirA').info.is_dir())
 | |
|         self.assertTrue((p / 'dirA').info.is_dir(follow_symlinks=False))
 | |
|         self.assertFalse((p / 'fileA').info.is_dir())
 | |
|         self.assertFalse((p / 'fileA').info.is_dir(follow_symlinks=False))
 | |
|         self.assertFalse((p / 'non-existing').info.is_dir())
 | |
|         self.assertFalse((p / 'non-existing').info.is_dir(follow_symlinks=False))
 | |
|         if self.ground.can_symlink:
 | |
|             self.assertFalse((p / 'linkA').info.is_dir())
 | |
|             self.assertFalse((p / 'linkA').info.is_dir(follow_symlinks=False))
 | |
|             self.assertTrue((p / 'linkB').info.is_dir())
 | |
|             self.assertFalse((p / 'linkB').info.is_dir(follow_symlinks=False))
 | |
|             self.assertFalse((p / 'brokenLink').info.is_dir())
 | |
|             self.assertFalse((p / 'brokenLink').info.is_dir(follow_symlinks=False))
 | |
|             self.assertFalse((p / 'brokenLinkLoop').info.is_dir())
 | |
|             self.assertFalse((p / 'brokenLinkLoop').info.is_dir(follow_symlinks=False))
 | |
|         self.assertFalse((p / 'dirA\udfff').info.is_dir())
 | |
|         self.assertFalse((p / 'dirA\udfff').info.is_dir(follow_symlinks=False))
 | |
|         self.assertFalse((p / 'dirA\x00').info.is_dir())
 | |
|         self.assertFalse((p / 'dirA\x00').info.is_dir(follow_symlinks=False))
 | |
| 
 | |
|     def test_info_is_file(self):
 | |
|         p = self.root
 | |
|         self.assertTrue((p / 'fileA').info.is_file())
 | |
|         self.assertTrue((p / 'fileA').info.is_file(follow_symlinks=False))
 | |
|         self.assertFalse((p / 'dirA').info.is_file())
 | |
|         self.assertFalse((p / 'dirA').info.is_file(follow_symlinks=False))
 | |
|         self.assertFalse((p / 'non-existing').info.is_file())
 | |
|         self.assertFalse((p / 'non-existing').info.is_file(follow_symlinks=False))
 | |
|         if self.ground.can_symlink:
 | |
|             self.assertTrue((p / 'linkA').info.is_file())
 | |
|             self.assertFalse((p / 'linkA').info.is_file(follow_symlinks=False))
 | |
|             self.assertFalse((p / 'linkB').info.is_file())
 | |
|             self.assertFalse((p / 'linkB').info.is_file(follow_symlinks=False))
 | |
|             self.assertFalse((p / 'brokenLink').info.is_file())
 | |
|             self.assertFalse((p / 'brokenLink').info.is_file(follow_symlinks=False))
 | |
|             self.assertFalse((p / 'brokenLinkLoop').info.is_file())
 | |
|             self.assertFalse((p / 'brokenLinkLoop').info.is_file(follow_symlinks=False))
 | |
|         self.assertFalse((p / 'fileA\udfff').info.is_file())
 | |
|         self.assertFalse((p / 'fileA\udfff').info.is_file(follow_symlinks=False))
 | |
|         self.assertFalse((p / 'fileA\x00').info.is_file())
 | |
|         self.assertFalse((p / 'fileA\x00').info.is_file(follow_symlinks=False))
 | |
| 
 | |
|     def test_info_is_symlink(self):
 | |
|         p = self.root
 | |
|         self.assertFalse((p / 'fileA').info.is_symlink())
 | |
|         self.assertFalse((p / 'dirA').info.is_symlink())
 | |
|         self.assertFalse((p / 'non-existing').info.is_symlink())
 | |
|         if self.ground.can_symlink:
 | |
|             self.assertTrue((p / 'linkA').info.is_symlink())
 | |
|             self.assertTrue((p / 'linkB').info.is_symlink())
 | |
|             self.assertTrue((p / 'brokenLink').info.is_symlink())
 | |
|             self.assertFalse((p / 'linkA\udfff').info.is_symlink())
 | |
|             self.assertFalse((p / 'linkA\x00').info.is_symlink())
 | |
|             self.assertTrue((p / 'brokenLinkLoop').info.is_symlink())
 | |
|         self.assertFalse((p / 'fileA\udfff').info.is_symlink())
 | |
|         self.assertFalse((p / 'fileA\x00').info.is_symlink())
 | |
| 
 | |
| 
 | |
| class ZipPathReadTest(ReadTestBase, unittest.TestCase):
 | |
|     ground = ZipPathGround(ReadableZipPath)
 | |
| 
 | |
| 
 | |
| class LocalPathReadTest(ReadTestBase, unittest.TestCase):
 | |
|     ground = LocalPathGround(ReadableLocalPath)
 | |
| 
 | |
| 
 | |
| if not is_pypi:
 | |
|     from pathlib import Path
 | |
| 
 | |
|     class PathReadTest(ReadTestBase, unittest.TestCase):
 | |
|         ground = LocalPathGround(Path)
 | |
| 
 | |
| 
 | |
| if __name__ == "__main__":
 | |
|     unittest.main()
 |