aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormrbean-bremen <hansemrbean@googlemail.com>2021-09-01 17:02:26 +0200
committermrbean-bremen <mrbean-bremen@users.noreply.github.com>2021-09-01 20:31:43 +0200
commite06472b0671d2f077cc41e9ab9cf38893ef0c97f (patch)
treefaf7f3e79dfe69e99cab55288ef83b6db6c8e43b
parent7419c6125278d0ab2a993076420a6376a15cc306 (diff)
downloadpyfakefs-e06472b0671d2f077cc41e9ab9cf38893ef0c97f.tar.gz
Fixed handling of alternative path separator in some functions
- affects os.path.split(), os.path.splitdrive() and glob.glob() - fixes #632
-rw-r--r--CHANGES.md5
-rw-r--r--pyfakefs/fake_filesystem.py48
-rw-r--r--pyfakefs/tests/example.py2
-rw-r--r--pyfakefs/tests/example_test.py2
-rw-r--r--pyfakefs/tests/fake_filesystem_glob_test.py6
-rw-r--r--pyfakefs/tests/fake_filesystem_test.py122
-rw-r--r--pyfakefs/tests/fake_filesystem_unittest_test.py23
7 files changed, 127 insertions, 81 deletions
diff --git a/CHANGES.md b/CHANGES.md
index c9a2f3d..83ce724 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -3,6 +3,11 @@ The released versions correspond to PyPi releases.
## Version 4.6.0 (as yet unreleased)
+### Fixes
+* fixed handling of alternative path separator in `os.path.split`,
+ `os.path.splitdrive` and `glob.glob`
+ (see [#632](../../issues/632))
+
## [Version 4.5.1](https://pypi.python.org/pypi/pyfakefs/4.5.1) (2021-08-29)
This is a bugfix release.
diff --git a/pyfakefs/fake_filesystem.py b/pyfakefs/fake_filesystem.py
index 19e30d1..f80de28 100644
--- a/pyfakefs/fake_filesystem.py
+++ b/pyfakefs/fake_filesystem.py
@@ -1587,31 +1587,18 @@ class FakeFilesystem:
(str) A duple (pathname, basename) for which pathname does not
end with a slash, and basename does not contain a slash.
"""
- full_path = path
- path = self.normcase(path)
- sep: AnyStr = self.get_path_separator(path)
+ path = make_string_path(path)
+ sep = self.get_path_separator(path)
+ alt_sep = self._alternative_path_separator(path)
+ seps = sep if alt_sep is None else sep + alt_sep
drive, path = self.splitdrive(path)
- path_components: List[AnyStr] = path.split(sep)
- if not path_components:
- return drive, matching_string(path, '')
- basename = path_components.pop()
- if not path_components:
- return drive, basename
- for component in path_components:
- if component:
- # The path is not the root; it contains a non-separator
- # component. Strip all trailing separators.
- while not path_components[-1]:
- path_components.pop()
- if not path_components:
- return drive, basename
- return drive + sep.join(path_components), basename
- # Root path. Collapse all leading separators.
- if drive and not basename:
- return full_path, basename
- if drive and len(drive) == 2:
- drive += sep
- return drive or sep, basename
+ i = len(path)
+ while i and path[i-1] not in seps:
+ i -= 1
+ head, tail = path[:i], path[i:] # now tail has no slashes
+ # remove trailing slashes from head, unless it's all slashes
+ head = head.rstrip(seps) or head
+ return drive + head, tail
def splitdrive(self, path: AnyStr) -> Tuple[AnyStr, AnyStr]:
"""Splits the path into the drive part and the rest of the path.
@@ -1630,17 +1617,17 @@ class FakeFilesystem:
path_str = make_string_path(path)
if self.is_windows_fs:
if len(path_str) >= 2:
- path_str = self.normcase(path_str)
+ norm_str = self.normcase(path_str)
sep = self.get_path_separator(path_str)
# UNC path_str handling
- if (path_str[0:2] == sep * 2) and (
- path_str[2:3] != sep):
+ if (norm_str[0:2] == sep * 2) and (
+ norm_str[2:3] != sep):
# UNC path_str handling - splits off the mount point
# instead of the drive
- sep_index = path_str.find(sep, 2)
+ sep_index = norm_str.find(sep, 2)
if sep_index == -1:
return path_str[:0], path_str
- sep_index2 = path_str.find(sep, sep_index + 1)
+ sep_index2 = norm_str.find(sep, sep_index + 1)
if sep_index2 == sep_index + 1:
return path_str[:0], path_str
if sep_index2 == -1:
@@ -2430,7 +2417,8 @@ class FakeFilesystem:
dir_path = self.make_string_path(directory_path)
dir_path = self.absnormpath(dir_path)
self._auto_mount_drive_if_needed(dir_path)
- if self.exists(dir_path, check_link=True):
+ if (self.exists(dir_path, check_link=True) and
+ dir_path not in self.mount_points):
self.raise_os_error(errno.EEXIST, dir_path)
path_components = self._path_components(dir_path)
current_dir = self.root
diff --git a/pyfakefs/tests/example.py b/pyfakefs/tests/example.py
index 5793cdd..09d7a3d 100644
--- a/pyfakefs/tests/example.py
+++ b/pyfakefs/tests/example.py
@@ -121,7 +121,7 @@ def get_glob(glob_path):
>>> import sys
>>> if sys.platform.startswith('win'):
... # Windows style path
- ... file_names == [r'\test\file1.txt', r'\test\file2.txt']
+ ... file_names == [r'/test\file1.txt', r'/test\file2.txt']
... else:
... # UNIX style path
... file_names == ['/test/file1.txt', '/test/file2.txt']
diff --git a/pyfakefs/tests/example_test.py b/pyfakefs/tests/example_test.py
index b44a695..91225d0 100644
--- a/pyfakefs/tests/example_test.py
+++ b/pyfakefs/tests/example_test.py
@@ -113,7 +113,7 @@ class TestExample(fake_filesystem_unittest.TestCase): # pylint: disable=R0904
matching_paths = sorted(example.get_glob('/test/dir1/dir*'))
if is_windows:
self.assertEqual(matching_paths,
- [r'\test\dir1\dir2a', r'\test\dir1\dir2b'])
+ [r'/test/dir1\dir2a', r'/test/dir1\dir2b'])
else:
self.assertEqual(matching_paths,
['/test/dir1/dir2a', '/test/dir1/dir2b'])
diff --git a/pyfakefs/tests/fake_filesystem_glob_test.py b/pyfakefs/tests/fake_filesystem_glob_test.py
index 87ccbe1..7432fa8 100644
--- a/pyfakefs/tests/fake_filesystem_glob_test.py
+++ b/pyfakefs/tests/fake_filesystem_glob_test.py
@@ -35,7 +35,7 @@ class FakeGlobUnitTest(fake_filesystem_unittest.TestCase):
self.assertEqual(glob.glob(''), [])
def test_glob_star(self):
- basedir = os.sep + 'xyzzy'
+ basedir = '/xyzzy'
self.assertEqual([os.path.join(basedir, 'subdir'),
os.path.join(basedir, 'subdir2'),
os.path.join(basedir, 'subfile')],
@@ -46,7 +46,7 @@ class FakeGlobUnitTest(fake_filesystem_unittest.TestCase):
self.assertEqual(['/xyzzy/subfile'], glob.glob('/xyzzy/subfile'))
def test_glob_question(self):
- basedir = os.sep + 'xyzzy'
+ basedir = '/xyzzy'
self.assertEqual([os.path.join(basedir, 'subdir'),
os.path.join(basedir, 'subdir2'),
os.path.join(basedir, 'subfile')],
@@ -60,7 +60,7 @@ class FakeGlobUnitTest(fake_filesystem_unittest.TestCase):
self.assertEqual([], glob.glob('nonexistent'))
def test_magic_dir(self):
- self.assertEqual([os.sep + '[Temp]'], glob.glob('/*emp*'))
+ self.assertEqual(['/[Temp]'], glob.glob('/*emp*'))
def test_glob1(self):
self.assertEqual(['[Temp]'], glob.glob1('/', '*Tem*'))
diff --git a/pyfakefs/tests/fake_filesystem_test.py b/pyfakefs/tests/fake_filesystem_test.py
index bb587ad..dfaff5f 100644
--- a/pyfakefs/tests/fake_filesystem_test.py
+++ b/pyfakefs/tests/fake_filesystem_test.py
@@ -857,7 +857,7 @@ class FakePathModuleTest(TestCase):
self.filesystem.create_file(abspath)
self.assertEqual(abspath, self.path.abspath(abspath))
self.assertEqual(abspath, self.path.abspath(filename))
- self.assertEqual(abspath, self.path.abspath(u'..!%s' % filename))
+ self.assertEqual(abspath, self.path.abspath('..!%s' % filename))
def test_abspath_windows(self):
self.check_abspath(is_windows=True)
@@ -1268,9 +1268,9 @@ class SplitPathTest(PathManipulationTestBase):
self.assertEqual(('|a|b', 'c'), self.filesystem.splitpath('|a|b|c'))
def test_root_separator_is_not_stripped(self):
- self.assertEqual(('|', ''), self.filesystem.splitpath('|||'))
+ self.assertEqual(('|||', ''), self.filesystem.splitpath('|||'))
self.assertEqual(('|', 'a'), self.filesystem.splitpath('|a'))
- self.assertEqual(('|', 'a'), self.filesystem.splitpath('|||a'))
+ self.assertEqual(('|||', 'a'), self.filesystem.splitpath('|||a'))
def test_empty_tail_if_path_ends_in_separator(self):
self.assertEqual(('a|b', ''), self.filesystem.splitpath('a|b|'))
@@ -1401,6 +1401,7 @@ class AlternativePathSeparatorTest(TestCase):
class DriveLetterSupportTest(TestCase):
def setUp(self):
self.filesystem = fake_filesystem.FakeFilesystem(path_separator='!')
+ self.filesystem.alternative_path_separator = '^'
self.filesystem.is_windows_fs = True
def test_initial_value(self):
@@ -1419,11 +1420,11 @@ class DriveLetterSupportTest(TestCase):
self.filesystem.normpath('!!foo!bar!!baz!!'))
def test_normalize_path_str(self):
- self.filesystem.cwd = u''
- self.assertEqual(u'c:!foo!bar',
- self.filesystem.absnormpath(u'c:!foo!!bar'))
- self.filesystem.cwd = u'c:!foo'
- self.assertEqual(u'c:!foo!bar', self.filesystem.absnormpath(u'bar'))
+ self.filesystem.cwd = ''
+ self.assertEqual('c:!foo!bar',
+ self.filesystem.absnormpath('c:!foo!!bar'))
+ self.filesystem.cwd = 'c:!foo'
+ self.assertEqual('c:!foo!bar', self.filesystem.absnormpath('bar'))
def test_normalize_path_bytes(self):
self.filesystem.cwd = b''
@@ -1433,20 +1434,30 @@ class DriveLetterSupportTest(TestCase):
self.assertEqual(b'c:!foo!bar', self.filesystem.absnormpath(b'bar'))
def test_split_path_str(self):
- self.assertEqual((u'c:!foo', u'bar'),
- self.filesystem.splitpath(u'c:!foo!bar'))
- self.assertEqual((u'c:!', u'foo'),
- self.filesystem.splitpath(u'c:!foo'))
- self.assertEqual((u'!foo', u'bar'),
- self.filesystem.splitpath(u'!foo!bar'))
- self.assertEqual((u'!', u'foo'),
- self.filesystem.splitpath(u'!foo'))
- self.assertEqual((u'c:foo', u'bar'),
- self.filesystem.splitpath(u'c:foo!bar'))
- self.assertEqual((u'c:', u'foo'),
- self.filesystem.splitpath(u'c:foo'))
- self.assertEqual((u'foo', u'bar'),
- self.filesystem.splitpath(u'foo!bar'))
+ self.assertEqual(('c:!foo', 'bar'),
+ self.filesystem.splitpath('c:!foo!bar'))
+ self.assertEqual(('c:!', 'foo'),
+ self.filesystem.splitpath('c:!foo'))
+ self.assertEqual(('!foo', 'bar'),
+ self.filesystem.splitpath('!foo!bar'))
+ self.assertEqual(('!', 'foo'),
+ self.filesystem.splitpath('!foo'))
+ self.assertEqual(('c:foo', 'bar'),
+ self.filesystem.splitpath('c:foo!bar'))
+ self.assertEqual(('c:', 'foo'),
+ self.filesystem.splitpath('c:foo'))
+ self.assertEqual(('foo', 'bar'),
+ self.filesystem.splitpath('foo!bar'))
+
+ def test_split_with_alt_separator(self):
+ self.assertEqual(('a^b', 'c'), self.filesystem.splitpath('a^b^c'))
+ self.assertEqual(('a^b!c', 'd'), self.filesystem.splitpath('a^b!c^d'))
+ self.assertEqual(('a^b!c', 'd'), self.filesystem.splitpath('a^b!c!d'))
+ self.assertEqual((b'a^b', b'c'), self.filesystem.splitpath(b'a^b^c'))
+ self.assertEqual((b'a^b!c', b'd'),
+ self.filesystem.splitpath(b'a^b!c^d'))
+ self.assertEqual((b'a^b!c', b'd'),
+ self.filesystem.splitpath(b'a^b!c!d'))
def test_split_path_bytes(self):
self.assertEqual((b'c:!foo', b'bar'),
@@ -1477,14 +1488,14 @@ class DriveLetterSupportTest(TestCase):
self.assertEqual(['c:'], self.filesystem._path_components('c:'))
def test_split_drive_str(self):
- self.assertEqual((u'c:', u'!foo!bar'),
- self.filesystem.splitdrive(u'c:!foo!bar'))
- self.assertEqual((u'', u'!foo!bar'),
- self.filesystem.splitdrive(u'!foo!bar'))
- self.assertEqual((u'c:', u'foo!bar'),
- self.filesystem.splitdrive(u'c:foo!bar'))
- self.assertEqual((u'', u'foo!bar'),
- self.filesystem.splitdrive(u'foo!bar'))
+ self.assertEqual(('c:', '!foo!bar'),
+ self.filesystem.splitdrive('c:!foo!bar'))
+ self.assertEqual(('', '!foo!bar'),
+ self.filesystem.splitdrive('!foo!bar'))
+ self.assertEqual(('c:', 'foo!bar'),
+ self.filesystem.splitdrive('c:foo!bar'))
+ self.assertEqual(('', 'foo!bar'),
+ self.filesystem.splitdrive('foo!bar'))
def test_split_drive_bytes(self):
self.assertEqual((b'c:', b'!foo!bar'),
@@ -1492,6 +1503,20 @@ class DriveLetterSupportTest(TestCase):
self.assertEqual((b'', b'!foo!bar'),
self.filesystem.splitdrive(b'!foo!bar'))
+ def test_split_drive_alt_sep(self):
+ self.assertEqual(('c:', '^foo^bar'),
+ self.filesystem.splitdrive('c:^foo^bar'))
+ self.assertEqual(('', 'foo^bar'),
+ self.filesystem.splitdrive('foo^bar'))
+ self.assertEqual(('', 'foo^bar!baz'),
+ self.filesystem.splitdrive('foo^bar!baz'))
+ self.assertEqual((b'c:', b'^foo^bar'),
+ self.filesystem.splitdrive(b'c:^foo^bar'))
+ self.assertEqual((b'', b'^foo^bar'),
+ self.filesystem.splitdrive(b'^foo^bar'))
+ self.assertEqual((b'', b'^foo^bar!baz'),
+ self.filesystem.splitdrive(b'^foo^bar!baz'))
+
def test_split_drive_with_unc_path(self):
self.assertEqual(('!!foo!bar', '!baz'),
self.filesystem.splitdrive('!!foo!bar!baz'))
@@ -1501,6 +1526,15 @@ class DriveLetterSupportTest(TestCase):
self.assertEqual(('!!foo!bar', '!!'),
self.filesystem.splitdrive('!!foo!bar!!'))
+ def test_split_drive_with_unc_path_alt_sep(self):
+ self.assertEqual(('^^foo^bar', '!baz'),
+ self.filesystem.splitdrive('^^foo^bar!baz'))
+ self.assertEqual(('', '^^foo'), self.filesystem.splitdrive('^^foo'))
+ self.assertEqual(('', '^^foo^^bar'),
+ self.filesystem.splitdrive('^^foo^^bar'))
+ self.assertEqual(('^^foo^bar', '^^'),
+ self.filesystem.splitdrive('^^foo^bar^^'))
+
def test_split_path_with_drive(self):
self.assertEqual(('d:!foo', 'baz'),
self.filesystem.splitpath('d:!foo!baz'))
@@ -1513,14 +1547,34 @@ class DriveLetterSupportTest(TestCase):
self.assertEqual(('c:!!', ''),
self.filesystem.splitpath('c:!!'))
+ def test_split_path_with_drive_alt_sep(self):
+ self.assertEqual(('d:^foo', 'baz'),
+ self.filesystem.splitpath('d:^foo^baz'))
+ self.assertEqual(('d:^foo^baz', ''),
+ self.filesystem.splitpath('d:^foo^baz^'))
+ self.assertEqual(('c:', ''),
+ self.filesystem.splitpath('c:'))
+ self.assertEqual(('c:^', ''),
+ self.filesystem.splitpath('c:^'))
+ self.assertEqual(('c:^^', ''),
+ self.filesystem.splitpath('c:^^'))
+
def test_split_path_with_unc_path(self):
- self.assertEqual(('!!foo!bar', 'baz'),
+ self.assertEqual(('!!foo!bar!', 'baz'),
self.filesystem.splitpath('!!foo!bar!baz'))
self.assertEqual(('!!foo!bar', ''),
self.filesystem.splitpath('!!foo!bar'))
self.assertEqual(('!!foo!bar!!', ''),
self.filesystem.splitpath('!!foo!bar!!'))
+ def test_split_path_with_unc_path_alt_sep(self):
+ self.assertEqual(('^^foo^bar^', 'baz'),
+ self.filesystem.splitpath('^^foo^bar^baz'))
+ self.assertEqual(('^^foo^bar', ''),
+ self.filesystem.splitpath('^^foo^bar'))
+ self.assertEqual(('^^foo^bar^^', ''),
+ self.filesystem.splitpath('^^foo^bar^^'))
+
class DiskSpaceTest(TestCase):
def setUp(self):
@@ -1563,16 +1617,16 @@ class DiskSpaceTest(TestCase):
self.assertEqual((100, 5, 95), self.filesystem.get_disk_usage())
def test_file_system_size_after_ascii_string_file_creation(self):
- self.filesystem.create_file('!foo!bar', contents=u'complicated')
+ self.filesystem.create_file('!foo!bar', contents='complicated')
self.assertEqual((100, 11, 89), self.filesystem.get_disk_usage())
def test_filesystem_size_after_2byte_unicode_file_creation(self):
- self.filesystem.create_file('!foo!bar', contents=u'сложно',
+ self.filesystem.create_file('!foo!bar', contents='сложно',
encoding='utf-8')
self.assertEqual((100, 12, 88), self.filesystem.get_disk_usage())
def test_filesystem_size_after_3byte_unicode_file_creation(self):
- self.filesystem.create_file('!foo!bar', contents=u'複雑',
+ self.filesystem.create_file('!foo!bar', contents='複雑',
encoding='utf-8')
self.assertEqual((100, 6, 94), self.filesystem.get_disk_usage())
diff --git a/pyfakefs/tests/fake_filesystem_unittest_test.py b/pyfakefs/tests/fake_filesystem_unittest_test.py
index 6b24332..f4da663 100644
--- a/pyfakefs/tests/fake_filesystem_unittest_test.py
+++ b/pyfakefs/tests/fake_filesystem_unittest_test.py
@@ -97,8 +97,8 @@ class TestPyfakefsUnittest(TestPyfakefsUnittestBase): # pylint: disable=R0904
self.assertTrue(self.fs.exists('/fake_file.txt'))
with open('/fake_file.txt') as f:
content = f.read()
- self.assertEqual(content, 'This test file was created using the '
- 'open() function.\n')
+ self.assertEqual('This test file was created using the '
+ 'open() function.\n', content)
def test_io_open(self):
"""Fake io module is bound"""
@@ -109,8 +109,8 @@ class TestPyfakefsUnittest(TestPyfakefsUnittestBase): # pylint: disable=R0904
self.assertTrue(self.fs.exists('/fake_file.txt'))
with open('/fake_file.txt') as f:
content = f.read()
- self.assertEqual(content, 'This test file was created using the '
- 'io.open() function.\n')
+ self.assertEqual('This test file was created using the '
+ 'io.open() function.\n', content)
def test_os(self):
"""Fake os module is bound"""
@@ -121,22 +121,21 @@ class TestPyfakefsUnittest(TestPyfakefsUnittestBase): # pylint: disable=R0904
def test_glob(self):
"""Fake glob module is bound"""
is_windows = sys.platform.startswith('win')
- self.assertEqual(glob.glob('/test/dir1/dir*'),
- [])
+ self.assertEqual([], glob.glob('/test/dir1/dir*'))
self.fs.create_dir('/test/dir1/dir2a')
matching_paths = glob.glob('/test/dir1/dir*')
if is_windows:
- self.assertEqual(matching_paths, [r'\test\dir1\dir2a'])
+ self.assertEqual([r'/test/dir1\dir2a'], matching_paths)
else:
- self.assertEqual(matching_paths, ['/test/dir1/dir2a'])
+ self.assertEqual(['/test/dir1/dir2a'], matching_paths)
self.fs.create_dir('/test/dir1/dir2b')
matching_paths = sorted(glob.glob('/test/dir1/dir*'))
if is_windows:
- self.assertEqual(matching_paths,
- [r'\test\dir1\dir2a', r'\test\dir1\dir2b'])
+ self.assertEqual([r'/test/dir1\dir2a', r'/test/dir1\dir2b'],
+ matching_paths)
else:
- self.assertEqual(matching_paths,
- ['/test/dir1/dir2a', '/test/dir1/dir2b'])
+ self.assertEqual(['/test/dir1/dir2a', '/test/dir1/dir2b'],
+ matching_paths)
def test_shutil(self):
"""Fake shutil module is bound"""