diff options
| author | Barney Gale <barney.gale@gmail.com> | 2024-01-09 23:52:15 (GMT) |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-01-09 23:52:15 (GMT) |
| commit | beb80d11ec0ddaf00a97f8a38ec9eae68e07c28e (patch) | |
| tree | 12fb69939ee1fc81d152f240c86bde0542b85545 /Lib/test/test_pathlib/test_pathlib.py | |
| parent | 57bdc6c30d2665c2760ff5a88487e57c8b3c397a (diff) | |
| download | cpython-beb80d11ec0ddaf00a97f8a38ec9eae68e07c28e.zip cpython-beb80d11ec0ddaf00a97f8a38ec9eae68e07c28e.tar.gz cpython-beb80d11ec0ddaf00a97f8a38ec9eae68e07c28e.tar.bz2 | |
GH-113528: Deoptimise `pathlib._abc.PurePathBase` (#113559)
Apply pathlib's normalization and performance tuning in `pathlib.PurePath`, but not `pathlib._abc.PurePathBase`.
With this change, the pathlib ABCs do not normalize away alternate path separators, empty segments, or dot segments. A single string given to the initialiser will round-trip by default, i.e. `str(PurePathBase(my_string)) == my_string`. Implementors can set their own path domain-specific normalization scheme by overriding `__str__()`
Eliminating path normalization makes maintaining and caching the path's parts and string representation both optional and not very useful, so this commit moves the `_drv`, `_root`, `_tail_cached` and `_str` slots from `PurePathBase` to `PurePath`. Only `_raw_paths` and `_resolving` slots remain in `PurePathBase`. This frees the ABCs from the burden of some of pathlib's hardest-to-understand code.
Diffstat (limited to 'Lib/test/test_pathlib/test_pathlib.py')
| -rw-r--r-- | Lib/test/test_pathlib/test_pathlib.py | 41 |
1 files changed, 41 insertions, 0 deletions
diff --git a/Lib/test/test_pathlib/test_pathlib.py b/Lib/test/test_pathlib/test_pathlib.py index 6e42122..04e6280 100644 --- a/Lib/test/test_pathlib/test_pathlib.py +++ b/Lib/test/test_pathlib/test_pathlib.py @@ -140,6 +140,8 @@ class PurePathTest(test_pathlib_abc.DummyPurePathTest): # The empty path points to '.' p = self.cls('') self.assertEqual(str(p), '.') + # Special case for the empty path. + self._check_str('.', ('',)) def test_parts_interning(self): P = self.cls @@ -300,6 +302,40 @@ class PurePathTest(test_pathlib_abc.DummyPurePathTest): self.assertEqual(q, p) self.assertEqual(repr(q), r) + def test_name_empty(self): + P = self.cls + self.assertEqual(P('').name, '') + self.assertEqual(P('.').name, '') + self.assertEqual(P('/a/b/.').name, 'b') + + def test_stem_empty(self): + P = self.cls + self.assertEqual(P('').stem, '') + self.assertEqual(P('.').stem, '') + + def test_with_name_empty(self): + P = self.cls + self.assertRaises(ValueError, P('').with_name, 'd.xml') + self.assertRaises(ValueError, P('.').with_name, 'd.xml') + self.assertRaises(ValueError, P('/').with_name, 'd.xml') + self.assertRaises(ValueError, P('a/b').with_name, '') + self.assertRaises(ValueError, P('a/b').with_name, '.') + + def test_with_stem_empty(self): + P = self.cls + self.assertRaises(ValueError, P('').with_stem, 'd') + self.assertRaises(ValueError, P('.').with_stem, 'd') + self.assertRaises(ValueError, P('/').with_stem, 'd') + self.assertRaises(ValueError, P('a/b').with_stem, '') + self.assertRaises(ValueError, P('a/b').with_stem, '.') + + def test_with_suffix_empty(self): + # Path doesn't have a "filename" component. + P = self.cls + self.assertRaises(ValueError, P('').with_suffix, '.gz') + self.assertRaises(ValueError, P('.').with_suffix, '.gz') + self.assertRaises(ValueError, P('/').with_suffix, '.gz') + def test_relative_to_several_args(self): P = self.cls p = P('a/b') @@ -313,6 +349,11 @@ class PurePathTest(test_pathlib_abc.DummyPurePathTest): with self.assertWarns(DeprecationWarning): p.is_relative_to('a', 'b') + def test_match_empty(self): + P = self.cls + self.assertRaises(ValueError, P('a').match, '') + self.assertRaises(ValueError, P('a').match, '.') + class PurePosixPathTest(PurePathTest): cls = pathlib.PurePosixPath |
