| 
									
										
										
										
											2024-01-08 19:31:52 +00:00
										 |  |  | import collections | 
					
						
							| 
									
										
										
										
											2023-12-16 19:04:33 +00:00
										 |  |  | import io | 
					
						
							|  |  |  | import os | 
					
						
							|  |  |  | import errno | 
					
						
							|  |  |  | import stat | 
					
						
							|  |  |  | import unittest | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-01-14 21:49:53 +00:00
										 |  |  | from pathlib._abc import UnsupportedOperation, PathModuleBase, PurePathBase, PathBase | 
					
						
							| 
									
										
										
										
											2023-12-22 20:59:17 +00:00
										 |  |  | import posixpath | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-12-16 19:04:33 +00:00
										 |  |  | from test.support.os_helper import TESTFN | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-01-26 22:29:28 +00:00
										 |  |  | _tests_needing_posix = set() | 
					
						
							|  |  |  | _tests_needing_windows = set() | 
					
						
							|  |  |  | _tests_needing_symlinks = set() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def needs_posix(fn): | 
					
						
							|  |  |  |     """Decorator that marks a test as requiring a POSIX-flavoured path class.""" | 
					
						
							|  |  |  |     _tests_needing_posix.add(fn.__name__) | 
					
						
							|  |  |  |     return fn | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def needs_windows(fn): | 
					
						
							|  |  |  |     """Decorator that marks a test as requiring a Windows-flavoured path class.""" | 
					
						
							|  |  |  |     _tests_needing_windows.add(fn.__name__) | 
					
						
							|  |  |  |     return fn | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def needs_symlinks(fn): | 
					
						
							|  |  |  |     """Decorator that marks a test as requiring a path class that supports symlinks.""" | 
					
						
							|  |  |  |     _tests_needing_symlinks.add(fn.__name__) | 
					
						
							|  |  |  |     return fn | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-12-16 19:04:33 +00:00
										 |  |  | class UnsupportedOperationTest(unittest.TestCase): | 
					
						
							|  |  |  |     def test_is_notimplemented(self): | 
					
						
							| 
									
										
										
										
											2023-12-22 20:59:17 +00:00
										 |  |  |         self.assertTrue(issubclass(UnsupportedOperation, NotImplementedError)) | 
					
						
							|  |  |  |         self.assertTrue(isinstance(UnsupportedOperation(), NotImplementedError)) | 
					
						
							| 
									
										
										
										
											2023-12-16 19:04:33 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-01-14 21:49:53 +00:00
										 |  |  | class PathModuleBaseTest(unittest.TestCase): | 
					
						
							|  |  |  |     cls = PathModuleBase | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_unsupported_operation(self): | 
					
						
							|  |  |  |         m = self.cls() | 
					
						
							|  |  |  |         e = UnsupportedOperation | 
					
						
							|  |  |  |         with self.assertRaises(e): | 
					
						
							|  |  |  |             m.sep | 
					
						
							|  |  |  |         self.assertRaises(e, m.join, 'foo') | 
					
						
							|  |  |  |         self.assertRaises(e, m.split, 'foo') | 
					
						
							| 
									
										
										
										
											2024-01-14 23:06:04 +00:00
										 |  |  |         self.assertRaises(e, m.splitdrive, 'foo') | 
					
						
							| 
									
										
										
										
											2024-01-14 21:49:53 +00:00
										 |  |  |         self.assertRaises(e, m.normcase, 'foo') | 
					
						
							|  |  |  |         self.assertRaises(e, m.isabs, 'foo') | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-12-16 19:04:33 +00:00
										 |  |  | # | 
					
						
							|  |  |  | # Tests for the pure classes. | 
					
						
							|  |  |  | # | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class PurePathBaseTest(unittest.TestCase): | 
					
						
							| 
									
										
										
										
											2023-12-22 20:59:17 +00:00
										 |  |  |     cls = PurePathBase | 
					
						
							| 
									
										
										
										
											2023-12-16 19:04:33 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-01-14 21:49:53 +00:00
										 |  |  |     def test_unsupported_operation_pure(self): | 
					
						
							|  |  |  |         p = self.cls('foo') | 
					
						
							|  |  |  |         e = UnsupportedOperation | 
					
						
							|  |  |  |         with self.assertRaises(e): | 
					
						
							|  |  |  |             p.drive | 
					
						
							|  |  |  |         with self.assertRaises(e): | 
					
						
							|  |  |  |             p.root | 
					
						
							|  |  |  |         with self.assertRaises(e): | 
					
						
							|  |  |  |             p.anchor | 
					
						
							|  |  |  |         with self.assertRaises(e): | 
					
						
							|  |  |  |             p.parts | 
					
						
							|  |  |  |         with self.assertRaises(e): | 
					
						
							|  |  |  |             p.parent | 
					
						
							|  |  |  |         with self.assertRaises(e): | 
					
						
							|  |  |  |             p.parents | 
					
						
							|  |  |  |         with self.assertRaises(e): | 
					
						
							|  |  |  |             p.name | 
					
						
							|  |  |  |         with self.assertRaises(e): | 
					
						
							|  |  |  |             p.stem | 
					
						
							|  |  |  |         with self.assertRaises(e): | 
					
						
							|  |  |  |             p.suffix | 
					
						
							|  |  |  |         with self.assertRaises(e): | 
					
						
							|  |  |  |             p.suffixes | 
					
						
							|  |  |  |         with self.assertRaises(e): | 
					
						
							|  |  |  |             p / 'bar' | 
					
						
							|  |  |  |         with self.assertRaises(e): | 
					
						
							|  |  |  |             'bar' / p | 
					
						
							|  |  |  |         self.assertRaises(e, p.joinpath, 'bar') | 
					
						
							|  |  |  |         self.assertRaises(e, p.with_name, 'bar') | 
					
						
							|  |  |  |         self.assertRaises(e, p.with_stem, 'bar') | 
					
						
							|  |  |  |         self.assertRaises(e, p.with_suffix, '.txt') | 
					
						
							|  |  |  |         self.assertRaises(e, p.relative_to, '') | 
					
						
							|  |  |  |         self.assertRaises(e, p.is_relative_to, '') | 
					
						
							|  |  |  |         self.assertRaises(e, p.is_absolute) | 
					
						
							|  |  |  |         self.assertRaises(e, p.match, '*') | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-12-16 19:04:33 +00:00
										 |  |  |     def test_magic_methods(self): | 
					
						
							|  |  |  |         P = self.cls | 
					
						
							|  |  |  |         self.assertFalse(hasattr(P, '__fspath__')) | 
					
						
							|  |  |  |         self.assertFalse(hasattr(P, '__bytes__')) | 
					
						
							|  |  |  |         self.assertIs(P.__reduce__, object.__reduce__) | 
					
						
							| 
									
										
										
										
											2023-12-22 15:11:16 +00:00
										 |  |  |         self.assertIs(P.__repr__, object.__repr__) | 
					
						
							| 
									
										
										
										
											2023-12-16 19:04:33 +00:00
										 |  |  |         self.assertIs(P.__hash__, object.__hash__) | 
					
						
							|  |  |  |         self.assertIs(P.__eq__, object.__eq__) | 
					
						
							|  |  |  |         self.assertIs(P.__lt__, object.__lt__) | 
					
						
							|  |  |  |         self.assertIs(P.__le__, object.__le__) | 
					
						
							|  |  |  |         self.assertIs(P.__gt__, object.__gt__) | 
					
						
							|  |  |  |         self.assertIs(P.__ge__, object.__ge__) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-12-22 18:09:50 +00:00
										 |  |  |     def test_pathmod(self): | 
					
						
							| 
									
										
										
										
											2024-01-14 21:49:53 +00:00
										 |  |  |         self.assertIsInstance(self.cls.pathmod, PathModuleBase) | 
					
						
							| 
									
										
										
										
											2023-12-22 18:09:50 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-12-16 19:04:33 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-12-22 20:59:17 +00:00
										 |  |  | class DummyPurePath(PurePathBase): | 
					
						
							| 
									
										
										
										
											2024-01-08 19:31:52 +00:00
										 |  |  |     __slots__ = () | 
					
						
							| 
									
										
										
										
											2024-01-14 21:49:53 +00:00
										 |  |  |     pathmod = posixpath | 
					
						
							| 
									
										
										
										
											2024-01-08 19:31:52 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-12-16 19:04:33 +00:00
										 |  |  |     def __eq__(self, other): | 
					
						
							|  |  |  |         if not isinstance(other, DummyPurePath): | 
					
						
							|  |  |  |             return NotImplemented | 
					
						
							|  |  |  |         return str(self) == str(other) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def __hash__(self): | 
					
						
							|  |  |  |         return hash(str(self)) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-01-06 17:02:36 +00:00
										 |  |  |     def __repr__(self): | 
					
						
							|  |  |  |         return "{}({!r})".format(self.__class__.__name__, self.as_posix()) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-12-16 19:04:33 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | class DummyPurePathTest(unittest.TestCase): | 
					
						
							|  |  |  |     cls = DummyPurePath | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-12-22 18:09:50 +00:00
										 |  |  |     # Use a base path that's unrelated to any real filesystem path. | 
					
						
							|  |  |  |     base = f'/this/path/kills/fascists/{TESTFN}' | 
					
						
							| 
									
										
										
										
											2023-12-17 00:07:32 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-12-16 19:04:33 +00:00
										 |  |  |     def setUp(self): | 
					
						
							| 
									
										
										
										
											2024-01-26 22:29:28 +00:00
										 |  |  |         name = self.id().split('.')[-1] | 
					
						
							|  |  |  |         if name in _tests_needing_posix and self.cls.pathmod is not posixpath: | 
					
						
							|  |  |  |             self.skipTest('requires POSIX-flavoured path class') | 
					
						
							|  |  |  |         if name in _tests_needing_windows and self.cls.pathmod is posixpath: | 
					
						
							|  |  |  |             self.skipTest('requires Windows-flavoured path class') | 
					
						
							| 
									
										
										
										
											2023-12-16 19:04:33 +00:00
										 |  |  |         p = self.cls('a') | 
					
						
							|  |  |  |         self.pathmod = p.pathmod | 
					
						
							|  |  |  |         self.sep = self.pathmod.sep | 
					
						
							|  |  |  |         self.altsep = self.pathmod.altsep | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_constructor_common(self): | 
					
						
							|  |  |  |         P = self.cls | 
					
						
							|  |  |  |         p = P('a') | 
					
						
							|  |  |  |         self.assertIsInstance(p, P) | 
					
						
							|  |  |  |         P('a', 'b', 'c') | 
					
						
							|  |  |  |         P('/a', 'b', 'c') | 
					
						
							|  |  |  |         P('a/b/c') | 
					
						
							|  |  |  |         P('/a/b/c') | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-01-31 00:59:33 +00:00
										 |  |  |     def test_bytes(self): | 
					
						
							|  |  |  |         P = self.cls | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             P(b'a') | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             P(b'a', 'b') | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             P('a', b'b') | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             P('a').joinpath(b'b') | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             P('a') / b'b' | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             b'a' / P('b') | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             P('a').match(b'b') | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             P('a').relative_to(b'b') | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             P('a').with_name(b'b') | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             P('a').with_stem(b'b') | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             P('a').with_suffix(b'b') | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-12-16 19:04:33 +00:00
										 |  |  |     def _check_str_subclass(self, *args): | 
					
						
							|  |  |  |         # Issue #21127: it should be possible to construct a PurePath object | 
					
						
							|  |  |  |         # from a str subclass instance, and it then gets converted to | 
					
						
							|  |  |  |         # a pure str object. | 
					
						
							|  |  |  |         class StrSubclass(str): | 
					
						
							|  |  |  |             pass | 
					
						
							|  |  |  |         P = self.cls | 
					
						
							|  |  |  |         p = P(*(StrSubclass(x) for x in args)) | 
					
						
							|  |  |  |         self.assertEqual(p, P(*args)) | 
					
						
							|  |  |  |         for part in p.parts: | 
					
						
							|  |  |  |             self.assertIs(type(part), str) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_str_subclass_common(self): | 
					
						
							|  |  |  |         self._check_str_subclass('') | 
					
						
							|  |  |  |         self._check_str_subclass('.') | 
					
						
							|  |  |  |         self._check_str_subclass('a') | 
					
						
							|  |  |  |         self._check_str_subclass('a/b.txt') | 
					
						
							|  |  |  |         self._check_str_subclass('/a/b.txt') | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-01-27 02:16:17 +00:00
										 |  |  |     @needs_windows | 
					
						
							|  |  |  |     def test_str_subclass_windows(self): | 
					
						
							|  |  |  |         self._check_str_subclass('.\\a:b') | 
					
						
							|  |  |  |         self._check_str_subclass('c:') | 
					
						
							|  |  |  |         self._check_str_subclass('c:a') | 
					
						
							|  |  |  |         self._check_str_subclass('c:a\\b.txt') | 
					
						
							|  |  |  |         self._check_str_subclass('c:\\') | 
					
						
							|  |  |  |         self._check_str_subclass('c:\\a') | 
					
						
							|  |  |  |         self._check_str_subclass('c:\\a\\b.txt') | 
					
						
							|  |  |  |         self._check_str_subclass('\\\\some\\share') | 
					
						
							|  |  |  |         self._check_str_subclass('\\\\some\\share\\a') | 
					
						
							|  |  |  |         self._check_str_subclass('\\\\some\\share\\a\\b.txt') | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-12-16 19:04:33 +00:00
										 |  |  |     def test_with_segments_common(self): | 
					
						
							|  |  |  |         class P(self.cls): | 
					
						
							|  |  |  |             def __init__(self, *pathsegments, session_id): | 
					
						
							|  |  |  |                 super().__init__(*pathsegments) | 
					
						
							|  |  |  |                 self.session_id = session_id | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             def with_segments(self, *pathsegments): | 
					
						
							|  |  |  |                 return type(self)(*pathsegments, session_id=self.session_id) | 
					
						
							|  |  |  |         p = P('foo', 'bar', session_id=42) | 
					
						
							|  |  |  |         self.assertEqual(42, (p / 'foo').session_id) | 
					
						
							|  |  |  |         self.assertEqual(42, ('foo' / p).session_id) | 
					
						
							|  |  |  |         self.assertEqual(42, p.joinpath('foo').session_id) | 
					
						
							|  |  |  |         self.assertEqual(42, p.with_name('foo').session_id) | 
					
						
							|  |  |  |         self.assertEqual(42, p.with_stem('foo').session_id) | 
					
						
							|  |  |  |         self.assertEqual(42, p.with_suffix('.foo').session_id) | 
					
						
							|  |  |  |         self.assertEqual(42, p.with_segments('foo').session_id) | 
					
						
							|  |  |  |         self.assertEqual(42, p.relative_to('foo').session_id) | 
					
						
							|  |  |  |         self.assertEqual(42, p.parent.session_id) | 
					
						
							|  |  |  |         for parent in p.parents: | 
					
						
							|  |  |  |             self.assertEqual(42, parent.session_id) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_join_common(self): | 
					
						
							|  |  |  |         P = self.cls | 
					
						
							|  |  |  |         p = P('a/b') | 
					
						
							|  |  |  |         pp = p.joinpath('c') | 
					
						
							|  |  |  |         self.assertEqual(pp, P('a/b/c')) | 
					
						
							|  |  |  |         self.assertIs(type(pp), type(p)) | 
					
						
							|  |  |  |         pp = p.joinpath('c', 'd') | 
					
						
							|  |  |  |         self.assertEqual(pp, P('a/b/c/d')) | 
					
						
							|  |  |  |         pp = p.joinpath('/c') | 
					
						
							|  |  |  |         self.assertEqual(pp, P('/c')) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-01-27 02:16:17 +00:00
										 |  |  |     @needs_posix | 
					
						
							|  |  |  |     def test_join_posix(self): | 
					
						
							|  |  |  |         P = self.cls | 
					
						
							|  |  |  |         p = P('//a') | 
					
						
							|  |  |  |         pp = p.joinpath('b') | 
					
						
							|  |  |  |         self.assertEqual(pp, P('//a/b')) | 
					
						
							|  |  |  |         pp = P('/a').joinpath('//c') | 
					
						
							|  |  |  |         self.assertEqual(pp, P('//c')) | 
					
						
							|  |  |  |         pp = P('//a').joinpath('/c') | 
					
						
							|  |  |  |         self.assertEqual(pp, P('/c')) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     @needs_windows | 
					
						
							|  |  |  |     def test_join_windows(self): | 
					
						
							|  |  |  |         P = self.cls | 
					
						
							|  |  |  |         p = P('C:/a/b') | 
					
						
							|  |  |  |         pp = p.joinpath('x/y') | 
					
						
							|  |  |  |         self.assertEqual(pp, P('C:/a/b/x/y')) | 
					
						
							|  |  |  |         pp = p.joinpath('/x/y') | 
					
						
							|  |  |  |         self.assertEqual(pp, P('C:/x/y')) | 
					
						
							|  |  |  |         # Joining with a different drive => the first path is ignored, even | 
					
						
							|  |  |  |         # if the second path is relative. | 
					
						
							|  |  |  |         pp = p.joinpath('D:x/y') | 
					
						
							|  |  |  |         self.assertEqual(pp, P('D:x/y')) | 
					
						
							|  |  |  |         pp = p.joinpath('D:/x/y') | 
					
						
							|  |  |  |         self.assertEqual(pp, P('D:/x/y')) | 
					
						
							|  |  |  |         pp = p.joinpath('//host/share/x/y') | 
					
						
							|  |  |  |         self.assertEqual(pp, P('//host/share/x/y')) | 
					
						
							|  |  |  |         # Joining with the same drive => the first path is appended to if | 
					
						
							|  |  |  |         # the second path is relative. | 
					
						
							|  |  |  |         pp = p.joinpath('c:x/y') | 
					
						
							|  |  |  |         self.assertEqual(pp, P('C:/a/b/x/y')) | 
					
						
							|  |  |  |         pp = p.joinpath('c:/x/y') | 
					
						
							|  |  |  |         self.assertEqual(pp, P('C:/x/y')) | 
					
						
							|  |  |  |         # Joining with files with NTFS data streams => the filename should | 
					
						
							|  |  |  |         # not be parsed as a drive letter | 
					
						
							|  |  |  |         pp = p.joinpath(P('./d:s')) | 
					
						
							|  |  |  |         self.assertEqual(pp, P('C:/a/b/d:s')) | 
					
						
							|  |  |  |         pp = p.joinpath(P('./dd:s')) | 
					
						
							|  |  |  |         self.assertEqual(pp, P('C:/a/b/dd:s')) | 
					
						
							|  |  |  |         pp = p.joinpath(P('E:d:s')) | 
					
						
							|  |  |  |         self.assertEqual(pp, P('E:d:s')) | 
					
						
							|  |  |  |         # Joining onto a UNC path with no root | 
					
						
							|  |  |  |         pp = P('//').joinpath('server') | 
					
						
							|  |  |  |         self.assertEqual(pp, P('//server')) | 
					
						
							|  |  |  |         pp = P('//server').joinpath('share') | 
					
						
							|  |  |  |         self.assertEqual(pp, P('//server/share')) | 
					
						
							|  |  |  |         pp = P('//./BootPartition').joinpath('Windows') | 
					
						
							|  |  |  |         self.assertEqual(pp, P('//./BootPartition/Windows')) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-12-16 19:04:33 +00:00
										 |  |  |     def test_div_common(self): | 
					
						
							|  |  |  |         # Basically the same as joinpath(). | 
					
						
							|  |  |  |         P = self.cls | 
					
						
							|  |  |  |         p = P('a/b') | 
					
						
							|  |  |  |         pp = p / 'c' | 
					
						
							|  |  |  |         self.assertEqual(pp, P('a/b/c')) | 
					
						
							|  |  |  |         self.assertIs(type(pp), type(p)) | 
					
						
							|  |  |  |         pp = p / 'c/d' | 
					
						
							|  |  |  |         self.assertEqual(pp, P('a/b/c/d')) | 
					
						
							|  |  |  |         pp = p / 'c' / 'd' | 
					
						
							|  |  |  |         self.assertEqual(pp, P('a/b/c/d')) | 
					
						
							|  |  |  |         pp = 'c' / p / 'd' | 
					
						
							|  |  |  |         self.assertEqual(pp, P('c/a/b/d')) | 
					
						
							|  |  |  |         pp = p/ '/c' | 
					
						
							|  |  |  |         self.assertEqual(pp, P('/c')) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-01-27 02:16:17 +00:00
										 |  |  |     @needs_posix | 
					
						
							|  |  |  |     def test_div_posix(self): | 
					
						
							|  |  |  |         # Basically the same as joinpath(). | 
					
						
							|  |  |  |         P = self.cls | 
					
						
							|  |  |  |         p = P('//a') | 
					
						
							|  |  |  |         pp = p / 'b' | 
					
						
							|  |  |  |         self.assertEqual(pp, P('//a/b')) | 
					
						
							|  |  |  |         pp = P('/a') / '//c' | 
					
						
							|  |  |  |         self.assertEqual(pp, P('//c')) | 
					
						
							|  |  |  |         pp = P('//a') / '/c' | 
					
						
							|  |  |  |         self.assertEqual(pp, P('/c')) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     @needs_windows | 
					
						
							|  |  |  |     def test_div_windows(self): | 
					
						
							|  |  |  |         # Basically the same as joinpath(). | 
					
						
							|  |  |  |         P = self.cls | 
					
						
							|  |  |  |         p = P('C:/a/b') | 
					
						
							|  |  |  |         self.assertEqual(p / 'x/y', P('C:/a/b/x/y')) | 
					
						
							|  |  |  |         self.assertEqual(p / 'x' / 'y', P('C:/a/b/x/y')) | 
					
						
							|  |  |  |         self.assertEqual(p / '/x/y', P('C:/x/y')) | 
					
						
							|  |  |  |         self.assertEqual(p / '/x' / 'y', P('C:/x/y')) | 
					
						
							|  |  |  |         # Joining with a different drive => the first path is ignored, even | 
					
						
							|  |  |  |         # if the second path is relative. | 
					
						
							|  |  |  |         self.assertEqual(p / 'D:x/y', P('D:x/y')) | 
					
						
							|  |  |  |         self.assertEqual(p / 'D:' / 'x/y', P('D:x/y')) | 
					
						
							|  |  |  |         self.assertEqual(p / 'D:/x/y', P('D:/x/y')) | 
					
						
							|  |  |  |         self.assertEqual(p / 'D:' / '/x/y', P('D:/x/y')) | 
					
						
							|  |  |  |         self.assertEqual(p / '//host/share/x/y', P('//host/share/x/y')) | 
					
						
							|  |  |  |         # Joining with the same drive => the first path is appended to if | 
					
						
							|  |  |  |         # the second path is relative. | 
					
						
							|  |  |  |         self.assertEqual(p / 'c:x/y', P('C:/a/b/x/y')) | 
					
						
							|  |  |  |         self.assertEqual(p / 'c:/x/y', P('C:/x/y')) | 
					
						
							|  |  |  |         # Joining with files with NTFS data streams => the filename should | 
					
						
							|  |  |  |         # not be parsed as a drive letter | 
					
						
							|  |  |  |         self.assertEqual(p / P('./d:s'), P('C:/a/b/d:s')) | 
					
						
							|  |  |  |         self.assertEqual(p / P('./dd:s'), P('C:/a/b/dd:s')) | 
					
						
							|  |  |  |         self.assertEqual(p / P('E:d:s'), P('E:d:s')) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-12-16 19:04:33 +00:00
										 |  |  |     def _check_str(self, expected, args): | 
					
						
							|  |  |  |         p = self.cls(*args) | 
					
						
							|  |  |  |         self.assertEqual(str(p), expected.replace('/', self.sep)) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_str_common(self): | 
					
						
							|  |  |  |         # Canonicalized paths roundtrip. | 
					
						
							|  |  |  |         for pathstr in ('a', 'a/b', 'a/b/c', '/', '/a/b', '/a/b/c'): | 
					
						
							|  |  |  |             self._check_str(pathstr, (pathstr,)) | 
					
						
							|  |  |  |         # Other tests for str() are in test_equivalences(). | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-01-27 02:16:17 +00:00
										 |  |  |     @needs_windows | 
					
						
							|  |  |  |     def test_str_windows(self): | 
					
						
							|  |  |  |         p = self.cls('a/b/c') | 
					
						
							|  |  |  |         self.assertEqual(str(p), 'a\\b\\c') | 
					
						
							|  |  |  |         p = self.cls('c:/a/b/c') | 
					
						
							|  |  |  |         self.assertEqual(str(p), 'c:\\a\\b\\c') | 
					
						
							|  |  |  |         p = self.cls('//a/b') | 
					
						
							|  |  |  |         self.assertEqual(str(p), '\\\\a\\b\\') | 
					
						
							|  |  |  |         p = self.cls('//a/b/c') | 
					
						
							|  |  |  |         self.assertEqual(str(p), '\\\\a\\b\\c') | 
					
						
							|  |  |  |         p = self.cls('//a/b/c/d') | 
					
						
							|  |  |  |         self.assertEqual(str(p), '\\\\a\\b\\c\\d') | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-12-16 19:04:33 +00:00
										 |  |  |     def test_as_posix_common(self): | 
					
						
							|  |  |  |         P = self.cls | 
					
						
							|  |  |  |         for pathstr in ('a', 'a/b', 'a/b/c', '/', '/a/b', '/a/b/c'): | 
					
						
							|  |  |  |             self.assertEqual(P(pathstr).as_posix(), pathstr) | 
					
						
							|  |  |  |         # Other tests for as_posix() are in test_equivalences(). | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-01-06 17:03:07 +00:00
										 |  |  |     def test_match_empty(self): | 
					
						
							| 
									
										
										
										
											2023-12-16 19:04:33 +00:00
										 |  |  |         P = self.cls | 
					
						
							|  |  |  |         self.assertRaises(ValueError, P('a').match, '') | 
					
						
							| 
									
										
										
										
											2024-01-06 17:03:07 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_match_common(self): | 
					
						
							|  |  |  |         P = self.cls | 
					
						
							| 
									
										
										
										
											2023-12-16 19:04:33 +00:00
										 |  |  |         # Simple relative pattern. | 
					
						
							|  |  |  |         self.assertTrue(P('b.py').match('b.py')) | 
					
						
							|  |  |  |         self.assertTrue(P('a/b.py').match('b.py')) | 
					
						
							|  |  |  |         self.assertTrue(P('/a/b.py').match('b.py')) | 
					
						
							|  |  |  |         self.assertFalse(P('a.py').match('b.py')) | 
					
						
							|  |  |  |         self.assertFalse(P('b/py').match('b.py')) | 
					
						
							|  |  |  |         self.assertFalse(P('/a.py').match('b.py')) | 
					
						
							|  |  |  |         self.assertFalse(P('b.py/c').match('b.py')) | 
					
						
							|  |  |  |         # Wildcard relative pattern. | 
					
						
							|  |  |  |         self.assertTrue(P('b.py').match('*.py')) | 
					
						
							|  |  |  |         self.assertTrue(P('a/b.py').match('*.py')) | 
					
						
							|  |  |  |         self.assertTrue(P('/a/b.py').match('*.py')) | 
					
						
							|  |  |  |         self.assertFalse(P('b.pyc').match('*.py')) | 
					
						
							|  |  |  |         self.assertFalse(P('b./py').match('*.py')) | 
					
						
							|  |  |  |         self.assertFalse(P('b.py/c').match('*.py')) | 
					
						
							|  |  |  |         # Multi-part relative pattern. | 
					
						
							|  |  |  |         self.assertTrue(P('ab/c.py').match('a*/*.py')) | 
					
						
							|  |  |  |         self.assertTrue(P('/d/ab/c.py').match('a*/*.py')) | 
					
						
							|  |  |  |         self.assertFalse(P('a.py').match('a*/*.py')) | 
					
						
							|  |  |  |         self.assertFalse(P('/dab/c.py').match('a*/*.py')) | 
					
						
							|  |  |  |         self.assertFalse(P('ab/c.py/d').match('a*/*.py')) | 
					
						
							|  |  |  |         # Absolute pattern. | 
					
						
							|  |  |  |         self.assertTrue(P('/b.py').match('/*.py')) | 
					
						
							|  |  |  |         self.assertFalse(P('b.py').match('/*.py')) | 
					
						
							|  |  |  |         self.assertFalse(P('a/b.py').match('/*.py')) | 
					
						
							|  |  |  |         self.assertFalse(P('/a/b.py').match('/*.py')) | 
					
						
							|  |  |  |         # Multi-part absolute pattern. | 
					
						
							|  |  |  |         self.assertTrue(P('/a/b.py').match('/a/*.py')) | 
					
						
							|  |  |  |         self.assertFalse(P('/ab.py').match('/a/*.py')) | 
					
						
							|  |  |  |         self.assertFalse(P('/a/b/c.py').match('/a/*.py')) | 
					
						
							|  |  |  |         # Multi-part glob-style pattern. | 
					
						
							| 
									
										
										
										
											2024-01-26 01:12:46 +00:00
										 |  |  |         self.assertFalse(P('/a/b/c.py').match('/**/*.py')) | 
					
						
							| 
									
										
										
										
											2023-12-16 19:04:33 +00:00
										 |  |  |         self.assertTrue(P('/a/b/c.py').match('/a/**/*.py')) | 
					
						
							|  |  |  |         # Case-sensitive flag | 
					
						
							|  |  |  |         self.assertFalse(P('A.py').match('a.PY', case_sensitive=True)) | 
					
						
							|  |  |  |         self.assertTrue(P('A.py').match('a.PY', case_sensitive=False)) | 
					
						
							|  |  |  |         self.assertFalse(P('c:/a/B.Py').match('C:/A/*.pY', case_sensitive=True)) | 
					
						
							|  |  |  |         self.assertTrue(P('/a/b/c.py').match('/A/*/*.Py', case_sensitive=False)) | 
					
						
							|  |  |  |         # Matching against empty path | 
					
						
							| 
									
										
										
										
											2024-01-10 01:12:58 +00:00
										 |  |  |         self.assertFalse(P('').match('*')) | 
					
						
							| 
									
										
										
										
											2024-01-26 01:12:46 +00:00
										 |  |  |         self.assertFalse(P('').match('**')) | 
					
						
							| 
									
										
										
										
											2024-01-10 01:12:58 +00:00
										 |  |  |         self.assertFalse(P('').match('**/*')) | 
					
						
							| 
									
										
										
										
											2023-12-16 19:04:33 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-01-27 02:16:17 +00:00
										 |  |  |     @needs_posix | 
					
						
							|  |  |  |     def test_match_posix(self): | 
					
						
							|  |  |  |         P = self.cls | 
					
						
							|  |  |  |         self.assertFalse(P('A.py').match('a.PY')) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     @needs_windows | 
					
						
							|  |  |  |     def test_match_windows(self): | 
					
						
							|  |  |  |         P = self.cls | 
					
						
							|  |  |  |         # Absolute patterns. | 
					
						
							|  |  |  |         self.assertTrue(P('c:/b.py').match('*:/*.py')) | 
					
						
							|  |  |  |         self.assertTrue(P('c:/b.py').match('c:/*.py')) | 
					
						
							|  |  |  |         self.assertFalse(P('d:/b.py').match('c:/*.py'))  # wrong drive | 
					
						
							|  |  |  |         self.assertFalse(P('b.py').match('/*.py')) | 
					
						
							|  |  |  |         self.assertFalse(P('b.py').match('c:*.py')) | 
					
						
							|  |  |  |         self.assertFalse(P('b.py').match('c:/*.py')) | 
					
						
							|  |  |  |         self.assertFalse(P('c:b.py').match('/*.py')) | 
					
						
							|  |  |  |         self.assertFalse(P('c:b.py').match('c:/*.py')) | 
					
						
							|  |  |  |         self.assertFalse(P('/b.py').match('c:*.py')) | 
					
						
							|  |  |  |         self.assertFalse(P('/b.py').match('c:/*.py')) | 
					
						
							|  |  |  |         # UNC patterns. | 
					
						
							|  |  |  |         self.assertTrue(P('//some/share/a.py').match('//*/*/*.py')) | 
					
						
							|  |  |  |         self.assertTrue(P('//some/share/a.py').match('//some/share/*.py')) | 
					
						
							|  |  |  |         self.assertFalse(P('//other/share/a.py').match('//some/share/*.py')) | 
					
						
							|  |  |  |         self.assertFalse(P('//some/share/a/b.py').match('//some/share/*.py')) | 
					
						
							|  |  |  |         # Case-insensitivity. | 
					
						
							|  |  |  |         self.assertTrue(P('B.py').match('b.PY')) | 
					
						
							|  |  |  |         self.assertTrue(P('c:/a/B.Py').match('C:/A/*.pY')) | 
					
						
							|  |  |  |         self.assertTrue(P('//Some/Share/B.Py').match('//somE/sharE/*.pY')) | 
					
						
							|  |  |  |         # Path anchor doesn't match pattern anchor | 
					
						
							|  |  |  |         self.assertFalse(P('c:/b.py').match('/*.py'))  # 'c:/' vs '/' | 
					
						
							|  |  |  |         self.assertFalse(P('c:/b.py').match('c:*.py'))  # 'c:/' vs 'c:' | 
					
						
							|  |  |  |         self.assertFalse(P('//some/share/a.py').match('/*.py'))  # '//some/share/' vs '/' | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-01-26 01:12:46 +00:00
										 |  |  |     def test_full_match_common(self): | 
					
						
							|  |  |  |         P = self.cls | 
					
						
							|  |  |  |         # Simple relative pattern. | 
					
						
							|  |  |  |         self.assertTrue(P('b.py').full_match('b.py')) | 
					
						
							|  |  |  |         self.assertFalse(P('a/b.py').full_match('b.py')) | 
					
						
							|  |  |  |         self.assertFalse(P('/a/b.py').full_match('b.py')) | 
					
						
							|  |  |  |         self.assertFalse(P('a.py').full_match('b.py')) | 
					
						
							|  |  |  |         self.assertFalse(P('b/py').full_match('b.py')) | 
					
						
							|  |  |  |         self.assertFalse(P('/a.py').full_match('b.py')) | 
					
						
							|  |  |  |         self.assertFalse(P('b.py/c').full_match('b.py')) | 
					
						
							|  |  |  |         # Wildcard relative pattern. | 
					
						
							|  |  |  |         self.assertTrue(P('b.py').full_match('*.py')) | 
					
						
							|  |  |  |         self.assertFalse(P('a/b.py').full_match('*.py')) | 
					
						
							|  |  |  |         self.assertFalse(P('/a/b.py').full_match('*.py')) | 
					
						
							|  |  |  |         self.assertFalse(P('b.pyc').full_match('*.py')) | 
					
						
							|  |  |  |         self.assertFalse(P('b./py').full_match('*.py')) | 
					
						
							|  |  |  |         self.assertFalse(P('b.py/c').full_match('*.py')) | 
					
						
							|  |  |  |         # Multi-part relative pattern. | 
					
						
							|  |  |  |         self.assertTrue(P('ab/c.py').full_match('a*/*.py')) | 
					
						
							|  |  |  |         self.assertFalse(P('/d/ab/c.py').full_match('a*/*.py')) | 
					
						
							|  |  |  |         self.assertFalse(P('a.py').full_match('a*/*.py')) | 
					
						
							|  |  |  |         self.assertFalse(P('/dab/c.py').full_match('a*/*.py')) | 
					
						
							|  |  |  |         self.assertFalse(P('ab/c.py/d').full_match('a*/*.py')) | 
					
						
							|  |  |  |         # Absolute pattern. | 
					
						
							|  |  |  |         self.assertTrue(P('/b.py').full_match('/*.py')) | 
					
						
							|  |  |  |         self.assertFalse(P('b.py').full_match('/*.py')) | 
					
						
							|  |  |  |         self.assertFalse(P('a/b.py').full_match('/*.py')) | 
					
						
							|  |  |  |         self.assertFalse(P('/a/b.py').full_match('/*.py')) | 
					
						
							|  |  |  |         # Multi-part absolute pattern. | 
					
						
							|  |  |  |         self.assertTrue(P('/a/b.py').full_match('/a/*.py')) | 
					
						
							|  |  |  |         self.assertFalse(P('/ab.py').full_match('/a/*.py')) | 
					
						
							|  |  |  |         self.assertFalse(P('/a/b/c.py').full_match('/a/*.py')) | 
					
						
							|  |  |  |         # Multi-part glob-style pattern. | 
					
						
							|  |  |  |         self.assertTrue(P('a').full_match('**')) | 
					
						
							|  |  |  |         self.assertTrue(P('c.py').full_match('**')) | 
					
						
							|  |  |  |         self.assertTrue(P('a/b/c.py').full_match('**')) | 
					
						
							|  |  |  |         self.assertTrue(P('/a/b/c.py').full_match('**')) | 
					
						
							|  |  |  |         self.assertTrue(P('/a/b/c.py').full_match('/**')) | 
					
						
							|  |  |  |         self.assertTrue(P('/a/b/c.py').full_match('/a/**')) | 
					
						
							|  |  |  |         self.assertTrue(P('/a/b/c.py').full_match('**/*.py')) | 
					
						
							|  |  |  |         self.assertTrue(P('/a/b/c.py').full_match('/**/*.py')) | 
					
						
							|  |  |  |         self.assertTrue(P('/a/b/c.py').full_match('/a/**/*.py')) | 
					
						
							|  |  |  |         self.assertTrue(P('/a/b/c.py').full_match('/a/b/**/*.py')) | 
					
						
							|  |  |  |         self.assertTrue(P('/a/b/c.py').full_match('/**/**/**/**/*.py')) | 
					
						
							|  |  |  |         self.assertFalse(P('c.py').full_match('**/a.py')) | 
					
						
							|  |  |  |         self.assertFalse(P('c.py').full_match('c/**')) | 
					
						
							|  |  |  |         self.assertFalse(P('a/b/c.py').full_match('**/a')) | 
					
						
							|  |  |  |         self.assertFalse(P('a/b/c.py').full_match('**/a/b')) | 
					
						
							|  |  |  |         self.assertFalse(P('a/b/c.py').full_match('**/a/b/c')) | 
					
						
							|  |  |  |         self.assertFalse(P('a/b/c.py').full_match('**/a/b/c.')) | 
					
						
							|  |  |  |         self.assertFalse(P('a/b/c.py').full_match('**/a/b/c./**')) | 
					
						
							|  |  |  |         self.assertFalse(P('a/b/c.py').full_match('**/a/b/c./**')) | 
					
						
							|  |  |  |         self.assertFalse(P('a/b/c.py').full_match('/a/b/c.py/**')) | 
					
						
							|  |  |  |         self.assertFalse(P('a/b/c.py').full_match('/**/a/b/c.py')) | 
					
						
							|  |  |  |         self.assertRaises(ValueError, P('a').full_match, '**a/b/c') | 
					
						
							|  |  |  |         self.assertRaises(ValueError, P('a').full_match, 'a/b/c**') | 
					
						
							|  |  |  |         # Case-sensitive flag | 
					
						
							|  |  |  |         self.assertFalse(P('A.py').full_match('a.PY', case_sensitive=True)) | 
					
						
							|  |  |  |         self.assertTrue(P('A.py').full_match('a.PY', case_sensitive=False)) | 
					
						
							|  |  |  |         self.assertFalse(P('c:/a/B.Py').full_match('C:/A/*.pY', case_sensitive=True)) | 
					
						
							|  |  |  |         self.assertTrue(P('/a/b/c.py').full_match('/A/*/*.Py', case_sensitive=False)) | 
					
						
							|  |  |  |         # Matching against empty path | 
					
						
							|  |  |  |         self.assertFalse(P('').full_match('*')) | 
					
						
							|  |  |  |         self.assertTrue(P('').full_match('**')) | 
					
						
							|  |  |  |         self.assertFalse(P('').full_match('**/*')) | 
					
						
							|  |  |  |         # Matching with empty pattern | 
					
						
							|  |  |  |         self.assertTrue(P('').full_match('')) | 
					
						
							|  |  |  |         self.assertTrue(P('.').full_match('.')) | 
					
						
							|  |  |  |         self.assertFalse(P('/').full_match('')) | 
					
						
							|  |  |  |         self.assertFalse(P('/').full_match('.')) | 
					
						
							|  |  |  |         self.assertFalse(P('foo').full_match('')) | 
					
						
							|  |  |  |         self.assertFalse(P('foo').full_match('.')) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-12-16 19:04:33 +00:00
										 |  |  |     def test_parts_common(self): | 
					
						
							|  |  |  |         # `parts` returns a tuple. | 
					
						
							|  |  |  |         sep = self.sep | 
					
						
							|  |  |  |         P = self.cls | 
					
						
							|  |  |  |         p = P('a/b') | 
					
						
							|  |  |  |         parts = p.parts | 
					
						
							|  |  |  |         self.assertEqual(parts, ('a', 'b')) | 
					
						
							|  |  |  |         # When the path is absolute, the anchor is a separate part. | 
					
						
							|  |  |  |         p = P('/a/b') | 
					
						
							|  |  |  |         parts = p.parts | 
					
						
							|  |  |  |         self.assertEqual(parts, (sep, 'a', 'b')) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-01-27 02:16:17 +00:00
										 |  |  |     @needs_windows | 
					
						
							|  |  |  |     def test_parts_windows(self): | 
					
						
							|  |  |  |         P = self.cls | 
					
						
							|  |  |  |         p = P('c:a/b') | 
					
						
							|  |  |  |         parts = p.parts | 
					
						
							|  |  |  |         self.assertEqual(parts, ('c:', 'a', 'b')) | 
					
						
							|  |  |  |         p = P('c:/a/b') | 
					
						
							|  |  |  |         parts = p.parts | 
					
						
							|  |  |  |         self.assertEqual(parts, ('c:\\', 'a', 'b')) | 
					
						
							|  |  |  |         p = P('//a/b/c/d') | 
					
						
							|  |  |  |         parts = p.parts | 
					
						
							|  |  |  |         self.assertEqual(parts, ('\\\\a\\b\\', 'c', 'd')) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-12-16 19:04:33 +00:00
										 |  |  |     def test_parent_common(self): | 
					
						
							|  |  |  |         # Relative | 
					
						
							|  |  |  |         P = self.cls | 
					
						
							|  |  |  |         p = P('a/b/c') | 
					
						
							|  |  |  |         self.assertEqual(p.parent, P('a/b')) | 
					
						
							|  |  |  |         self.assertEqual(p.parent.parent, P('a')) | 
					
						
							| 
									
										
										
										
											2024-01-10 01:12:58 +00:00
										 |  |  |         self.assertEqual(p.parent.parent.parent, P('')) | 
					
						
							|  |  |  |         self.assertEqual(p.parent.parent.parent.parent, P('')) | 
					
						
							| 
									
										
										
										
											2023-12-16 19:04:33 +00:00
										 |  |  |         # Anchored | 
					
						
							|  |  |  |         p = P('/a/b/c') | 
					
						
							|  |  |  |         self.assertEqual(p.parent, P('/a/b')) | 
					
						
							|  |  |  |         self.assertEqual(p.parent.parent, P('/a')) | 
					
						
							|  |  |  |         self.assertEqual(p.parent.parent.parent, P('/')) | 
					
						
							|  |  |  |         self.assertEqual(p.parent.parent.parent.parent, P('/')) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-01-27 02:16:17 +00:00
										 |  |  |     @needs_windows | 
					
						
							|  |  |  |     def test_parent_windows(self): | 
					
						
							|  |  |  |         # Anchored | 
					
						
							|  |  |  |         P = self.cls | 
					
						
							|  |  |  |         p = P('z:a/b/c') | 
					
						
							|  |  |  |         self.assertEqual(p.parent, P('z:a/b')) | 
					
						
							|  |  |  |         self.assertEqual(p.parent.parent, P('z:a')) | 
					
						
							|  |  |  |         self.assertEqual(p.parent.parent.parent, P('z:')) | 
					
						
							|  |  |  |         self.assertEqual(p.parent.parent.parent.parent, P('z:')) | 
					
						
							|  |  |  |         p = P('z:/a/b/c') | 
					
						
							|  |  |  |         self.assertEqual(p.parent, P('z:/a/b')) | 
					
						
							|  |  |  |         self.assertEqual(p.parent.parent, P('z:/a')) | 
					
						
							|  |  |  |         self.assertEqual(p.parent.parent.parent, P('z:/')) | 
					
						
							|  |  |  |         self.assertEqual(p.parent.parent.parent.parent, P('z:/')) | 
					
						
							|  |  |  |         p = P('//a/b/c/d') | 
					
						
							|  |  |  |         self.assertEqual(p.parent, P('//a/b/c')) | 
					
						
							|  |  |  |         self.assertEqual(p.parent.parent, P('//a/b')) | 
					
						
							|  |  |  |         self.assertEqual(p.parent.parent.parent, P('//a/b')) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-12-16 19:04:33 +00:00
										 |  |  |     def test_parents_common(self): | 
					
						
							|  |  |  |         # Relative | 
					
						
							|  |  |  |         P = self.cls | 
					
						
							|  |  |  |         p = P('a/b/c') | 
					
						
							|  |  |  |         par = p.parents | 
					
						
							|  |  |  |         self.assertEqual(len(par), 3) | 
					
						
							|  |  |  |         self.assertEqual(par[0], P('a/b')) | 
					
						
							|  |  |  |         self.assertEqual(par[1], P('a')) | 
					
						
							| 
									
										
										
										
											2024-01-09 23:52:15 +00:00
										 |  |  |         self.assertEqual(par[2], P('')) | 
					
						
							|  |  |  |         self.assertEqual(par[-1], P('')) | 
					
						
							| 
									
										
										
										
											2023-12-16 19:04:33 +00:00
										 |  |  |         self.assertEqual(par[-2], P('a')) | 
					
						
							|  |  |  |         self.assertEqual(par[-3], P('a/b')) | 
					
						
							|  |  |  |         self.assertEqual(par[0:1], (P('a/b'),)) | 
					
						
							|  |  |  |         self.assertEqual(par[:2], (P('a/b'), P('a'))) | 
					
						
							|  |  |  |         self.assertEqual(par[:-1], (P('a/b'), P('a'))) | 
					
						
							| 
									
										
										
										
											2024-01-09 23:52:15 +00:00
										 |  |  |         self.assertEqual(par[1:], (P('a'), P(''))) | 
					
						
							|  |  |  |         self.assertEqual(par[::2], (P('a/b'), P(''))) | 
					
						
							|  |  |  |         self.assertEqual(par[::-1], (P(''), P('a'), P('a/b'))) | 
					
						
							|  |  |  |         self.assertEqual(list(par), [P('a/b'), P('a'), P('')]) | 
					
						
							| 
									
										
										
										
											2023-12-16 19:04:33 +00:00
										 |  |  |         with self.assertRaises(IndexError): | 
					
						
							|  |  |  |             par[-4] | 
					
						
							|  |  |  |         with self.assertRaises(IndexError): | 
					
						
							|  |  |  |             par[3] | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             par[0] = p | 
					
						
							|  |  |  |         # Anchored | 
					
						
							|  |  |  |         p = P('/a/b/c') | 
					
						
							|  |  |  |         par = p.parents | 
					
						
							|  |  |  |         self.assertEqual(len(par), 3) | 
					
						
							|  |  |  |         self.assertEqual(par[0], P('/a/b')) | 
					
						
							|  |  |  |         self.assertEqual(par[1], P('/a')) | 
					
						
							|  |  |  |         self.assertEqual(par[2], P('/')) | 
					
						
							|  |  |  |         self.assertEqual(par[-1], P('/')) | 
					
						
							|  |  |  |         self.assertEqual(par[-2], P('/a')) | 
					
						
							|  |  |  |         self.assertEqual(par[-3], P('/a/b')) | 
					
						
							|  |  |  |         self.assertEqual(par[0:1], (P('/a/b'),)) | 
					
						
							|  |  |  |         self.assertEqual(par[:2], (P('/a/b'), P('/a'))) | 
					
						
							|  |  |  |         self.assertEqual(par[:-1], (P('/a/b'), P('/a'))) | 
					
						
							|  |  |  |         self.assertEqual(par[1:], (P('/a'), P('/'))) | 
					
						
							|  |  |  |         self.assertEqual(par[::2], (P('/a/b'), P('/'))) | 
					
						
							|  |  |  |         self.assertEqual(par[::-1], (P('/'), P('/a'), P('/a/b'))) | 
					
						
							|  |  |  |         self.assertEqual(list(par), [P('/a/b'), P('/a'), P('/')]) | 
					
						
							|  |  |  |         with self.assertRaises(IndexError): | 
					
						
							|  |  |  |             par[-4] | 
					
						
							|  |  |  |         with self.assertRaises(IndexError): | 
					
						
							|  |  |  |             par[3] | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-01-27 02:16:17 +00:00
										 |  |  |     @needs_windows | 
					
						
							|  |  |  |     def test_parents_windows(self): | 
					
						
							|  |  |  |         # Anchored | 
					
						
							|  |  |  |         P = self.cls | 
					
						
							|  |  |  |         p = P('z:a/b/') | 
					
						
							|  |  |  |         par = p.parents | 
					
						
							|  |  |  |         self.assertEqual(len(par), 2) | 
					
						
							|  |  |  |         self.assertEqual(par[0], P('z:a')) | 
					
						
							|  |  |  |         self.assertEqual(par[1], P('z:')) | 
					
						
							|  |  |  |         self.assertEqual(par[0:1], (P('z:a'),)) | 
					
						
							|  |  |  |         self.assertEqual(par[:-1], (P('z:a'),)) | 
					
						
							|  |  |  |         self.assertEqual(par[:2], (P('z:a'), P('z:'))) | 
					
						
							|  |  |  |         self.assertEqual(par[1:], (P('z:'),)) | 
					
						
							|  |  |  |         self.assertEqual(par[::2], (P('z:a'),)) | 
					
						
							|  |  |  |         self.assertEqual(par[::-1], (P('z:'), P('z:a'))) | 
					
						
							|  |  |  |         self.assertEqual(list(par), [P('z:a'), P('z:')]) | 
					
						
							|  |  |  |         with self.assertRaises(IndexError): | 
					
						
							|  |  |  |             par[2] | 
					
						
							|  |  |  |         p = P('z:/a/b/') | 
					
						
							|  |  |  |         par = p.parents | 
					
						
							|  |  |  |         self.assertEqual(len(par), 2) | 
					
						
							|  |  |  |         self.assertEqual(par[0], P('z:/a')) | 
					
						
							|  |  |  |         self.assertEqual(par[1], P('z:/')) | 
					
						
							|  |  |  |         self.assertEqual(par[0:1], (P('z:/a'),)) | 
					
						
							|  |  |  |         self.assertEqual(par[0:-1], (P('z:/a'),)) | 
					
						
							|  |  |  |         self.assertEqual(par[:2], (P('z:/a'), P('z:/'))) | 
					
						
							|  |  |  |         self.assertEqual(par[1:], (P('z:/'),)) | 
					
						
							|  |  |  |         self.assertEqual(par[::2], (P('z:/a'),)) | 
					
						
							|  |  |  |         self.assertEqual(par[::-1], (P('z:/'), P('z:/a'),)) | 
					
						
							|  |  |  |         self.assertEqual(list(par), [P('z:/a'), P('z:/')]) | 
					
						
							|  |  |  |         with self.assertRaises(IndexError): | 
					
						
							|  |  |  |             par[2] | 
					
						
							|  |  |  |         p = P('//a/b/c/d') | 
					
						
							|  |  |  |         par = p.parents | 
					
						
							|  |  |  |         self.assertEqual(len(par), 2) | 
					
						
							|  |  |  |         self.assertEqual(par[0], P('//a/b/c')) | 
					
						
							|  |  |  |         self.assertEqual(par[1], P('//a/b')) | 
					
						
							|  |  |  |         self.assertEqual(par[0:1], (P('//a/b/c'),)) | 
					
						
							|  |  |  |         self.assertEqual(par[0:-1], (P('//a/b/c'),)) | 
					
						
							|  |  |  |         self.assertEqual(par[:2], (P('//a/b/c'), P('//a/b'))) | 
					
						
							|  |  |  |         self.assertEqual(par[1:], (P('//a/b'),)) | 
					
						
							|  |  |  |         self.assertEqual(par[::2], (P('//a/b/c'),)) | 
					
						
							|  |  |  |         self.assertEqual(par[::-1], (P('//a/b'), P('//a/b/c'))) | 
					
						
							|  |  |  |         self.assertEqual(list(par), [P('//a/b/c'), P('//a/b')]) | 
					
						
							|  |  |  |         with self.assertRaises(IndexError): | 
					
						
							|  |  |  |             par[2] | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-12-16 19:04:33 +00:00
										 |  |  |     def test_drive_common(self): | 
					
						
							|  |  |  |         P = self.cls | 
					
						
							|  |  |  |         self.assertEqual(P('a/b').drive, '') | 
					
						
							|  |  |  |         self.assertEqual(P('/a/b').drive, '') | 
					
						
							|  |  |  |         self.assertEqual(P('').drive, '') | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-01-27 02:16:17 +00:00
										 |  |  |     @needs_windows | 
					
						
							|  |  |  |     def test_drive_windows(self): | 
					
						
							|  |  |  |         P = self.cls | 
					
						
							|  |  |  |         self.assertEqual(P('c:').drive, 'c:') | 
					
						
							|  |  |  |         self.assertEqual(P('c:a/b').drive, 'c:') | 
					
						
							|  |  |  |         self.assertEqual(P('c:/').drive, 'c:') | 
					
						
							|  |  |  |         self.assertEqual(P('c:/a/b/').drive, 'c:') | 
					
						
							|  |  |  |         self.assertEqual(P('//a/b').drive, '\\\\a\\b') | 
					
						
							|  |  |  |         self.assertEqual(P('//a/b/').drive, '\\\\a\\b') | 
					
						
							|  |  |  |         self.assertEqual(P('//a/b/c/d').drive, '\\\\a\\b') | 
					
						
							|  |  |  |         self.assertEqual(P('./c:a').drive, '') | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-12-16 19:04:33 +00:00
										 |  |  |     def test_root_common(self): | 
					
						
							|  |  |  |         P = self.cls | 
					
						
							|  |  |  |         sep = self.sep | 
					
						
							|  |  |  |         self.assertEqual(P('').root, '') | 
					
						
							|  |  |  |         self.assertEqual(P('a/b').root, '') | 
					
						
							|  |  |  |         self.assertEqual(P('/').root, sep) | 
					
						
							|  |  |  |         self.assertEqual(P('/a/b').root, sep) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-01-27 02:16:17 +00:00
										 |  |  |     @needs_posix | 
					
						
							|  |  |  |     def test_root_posix(self): | 
					
						
							|  |  |  |         P = self.cls | 
					
						
							|  |  |  |         self.assertEqual(P('/a/b').root, '/') | 
					
						
							|  |  |  |         # POSIX special case for two leading slashes. | 
					
						
							|  |  |  |         self.assertEqual(P('//a/b').root, '//') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     @needs_windows | 
					
						
							|  |  |  |     def test_root_windows(self): | 
					
						
							|  |  |  |         P = self.cls | 
					
						
							|  |  |  |         self.assertEqual(P('c:').root, '') | 
					
						
							|  |  |  |         self.assertEqual(P('c:a/b').root, '') | 
					
						
							|  |  |  |         self.assertEqual(P('c:/').root, '\\') | 
					
						
							|  |  |  |         self.assertEqual(P('c:/a/b/').root, '\\') | 
					
						
							|  |  |  |         self.assertEqual(P('//a/b').root, '\\') | 
					
						
							|  |  |  |         self.assertEqual(P('//a/b/').root, '\\') | 
					
						
							|  |  |  |         self.assertEqual(P('//a/b/c/d').root, '\\') | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-12-16 19:04:33 +00:00
										 |  |  |     def test_anchor_common(self): | 
					
						
							|  |  |  |         P = self.cls | 
					
						
							|  |  |  |         sep = self.sep | 
					
						
							|  |  |  |         self.assertEqual(P('').anchor, '') | 
					
						
							|  |  |  |         self.assertEqual(P('a/b').anchor, '') | 
					
						
							|  |  |  |         self.assertEqual(P('/').anchor, sep) | 
					
						
							|  |  |  |         self.assertEqual(P('/a/b').anchor, sep) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-01-27 02:16:17 +00:00
										 |  |  |     @needs_windows | 
					
						
							|  |  |  |     def test_anchor_windows(self): | 
					
						
							|  |  |  |         P = self.cls | 
					
						
							|  |  |  |         self.assertEqual(P('c:').anchor, 'c:') | 
					
						
							|  |  |  |         self.assertEqual(P('c:a/b').anchor, 'c:') | 
					
						
							|  |  |  |         self.assertEqual(P('c:/').anchor, 'c:\\') | 
					
						
							|  |  |  |         self.assertEqual(P('c:/a/b/').anchor, 'c:\\') | 
					
						
							|  |  |  |         self.assertEqual(P('//a/b').anchor, '\\\\a\\b\\') | 
					
						
							|  |  |  |         self.assertEqual(P('//a/b/').anchor, '\\\\a\\b\\') | 
					
						
							|  |  |  |         self.assertEqual(P('//a/b/c/d').anchor, '\\\\a\\b\\') | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-01-06 17:03:07 +00:00
										 |  |  |     def test_name_empty(self): | 
					
						
							| 
									
										
										
										
											2023-12-16 19:04:33 +00:00
										 |  |  |         P = self.cls | 
					
						
							|  |  |  |         self.assertEqual(P('').name, '') | 
					
						
							| 
									
										
										
										
											2024-01-09 23:52:15 +00:00
										 |  |  |         self.assertEqual(P('.').name, '.') | 
					
						
							|  |  |  |         self.assertEqual(P('/a/b/.').name, '.') | 
					
						
							| 
									
										
										
										
											2024-01-06 17:03:07 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_name_common(self): | 
					
						
							|  |  |  |         P = self.cls | 
					
						
							| 
									
										
										
										
											2023-12-16 19:04:33 +00:00
										 |  |  |         self.assertEqual(P('/').name, '') | 
					
						
							|  |  |  |         self.assertEqual(P('a/b').name, 'b') | 
					
						
							|  |  |  |         self.assertEqual(P('/a/b').name, 'b') | 
					
						
							|  |  |  |         self.assertEqual(P('a/b.py').name, 'b.py') | 
					
						
							|  |  |  |         self.assertEqual(P('/a/b.py').name, 'b.py') | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-01-27 02:16:17 +00:00
										 |  |  |     @needs_windows | 
					
						
							|  |  |  |     def test_name_windows(self): | 
					
						
							|  |  |  |         P = self.cls | 
					
						
							|  |  |  |         self.assertEqual(P('c:').name, '') | 
					
						
							|  |  |  |         self.assertEqual(P('c:/').name, '') | 
					
						
							|  |  |  |         self.assertEqual(P('c:a/b').name, 'b') | 
					
						
							|  |  |  |         self.assertEqual(P('c:/a/b').name, 'b') | 
					
						
							|  |  |  |         self.assertEqual(P('c:a/b.py').name, 'b.py') | 
					
						
							|  |  |  |         self.assertEqual(P('c:/a/b.py').name, 'b.py') | 
					
						
							|  |  |  |         self.assertEqual(P('//My.py/Share.php').name, '') | 
					
						
							|  |  |  |         self.assertEqual(P('//My.py/Share.php/a/b').name, 'b') | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-12-16 19:04:33 +00:00
										 |  |  |     def test_suffix_common(self): | 
					
						
							|  |  |  |         P = self.cls | 
					
						
							|  |  |  |         self.assertEqual(P('').suffix, '') | 
					
						
							|  |  |  |         self.assertEqual(P('.').suffix, '') | 
					
						
							|  |  |  |         self.assertEqual(P('..').suffix, '') | 
					
						
							|  |  |  |         self.assertEqual(P('/').suffix, '') | 
					
						
							|  |  |  |         self.assertEqual(P('a/b').suffix, '') | 
					
						
							|  |  |  |         self.assertEqual(P('/a/b').suffix, '') | 
					
						
							|  |  |  |         self.assertEqual(P('/a/b/.').suffix, '') | 
					
						
							|  |  |  |         self.assertEqual(P('a/b.py').suffix, '.py') | 
					
						
							|  |  |  |         self.assertEqual(P('/a/b.py').suffix, '.py') | 
					
						
							|  |  |  |         self.assertEqual(P('a/.hgrc').suffix, '') | 
					
						
							|  |  |  |         self.assertEqual(P('/a/.hgrc').suffix, '') | 
					
						
							|  |  |  |         self.assertEqual(P('a/.hg.rc').suffix, '.rc') | 
					
						
							|  |  |  |         self.assertEqual(P('/a/.hg.rc').suffix, '.rc') | 
					
						
							|  |  |  |         self.assertEqual(P('a/b.tar.gz').suffix, '.gz') | 
					
						
							|  |  |  |         self.assertEqual(P('/a/b.tar.gz').suffix, '.gz') | 
					
						
							|  |  |  |         self.assertEqual(P('a/Some name. Ending with a dot.').suffix, '') | 
					
						
							|  |  |  |         self.assertEqual(P('/a/Some name. Ending with a dot.').suffix, '') | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-01-27 02:16:17 +00:00
										 |  |  |     @needs_windows | 
					
						
							|  |  |  |     def test_suffix_windows(self): | 
					
						
							|  |  |  |         P = self.cls | 
					
						
							|  |  |  |         self.assertEqual(P('c:').suffix, '') | 
					
						
							|  |  |  |         self.assertEqual(P('c:/').suffix, '') | 
					
						
							|  |  |  |         self.assertEqual(P('c:a/b').suffix, '') | 
					
						
							|  |  |  |         self.assertEqual(P('c:/a/b').suffix, '') | 
					
						
							|  |  |  |         self.assertEqual(P('c:a/b.py').suffix, '.py') | 
					
						
							|  |  |  |         self.assertEqual(P('c:/a/b.py').suffix, '.py') | 
					
						
							|  |  |  |         self.assertEqual(P('c:a/.hgrc').suffix, '') | 
					
						
							|  |  |  |         self.assertEqual(P('c:/a/.hgrc').suffix, '') | 
					
						
							|  |  |  |         self.assertEqual(P('c:a/.hg.rc').suffix, '.rc') | 
					
						
							|  |  |  |         self.assertEqual(P('c:/a/.hg.rc').suffix, '.rc') | 
					
						
							|  |  |  |         self.assertEqual(P('c:a/b.tar.gz').suffix, '.gz') | 
					
						
							|  |  |  |         self.assertEqual(P('c:/a/b.tar.gz').suffix, '.gz') | 
					
						
							|  |  |  |         self.assertEqual(P('c:a/Some name. Ending with a dot.').suffix, '') | 
					
						
							|  |  |  |         self.assertEqual(P('c:/a/Some name. Ending with a dot.').suffix, '') | 
					
						
							|  |  |  |         self.assertEqual(P('//My.py/Share.php').suffix, '') | 
					
						
							|  |  |  |         self.assertEqual(P('//My.py/Share.php/a/b').suffix, '') | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-12-16 19:04:33 +00:00
										 |  |  |     def test_suffixes_common(self): | 
					
						
							|  |  |  |         P = self.cls | 
					
						
							|  |  |  |         self.assertEqual(P('').suffixes, []) | 
					
						
							|  |  |  |         self.assertEqual(P('.').suffixes, []) | 
					
						
							|  |  |  |         self.assertEqual(P('/').suffixes, []) | 
					
						
							|  |  |  |         self.assertEqual(P('a/b').suffixes, []) | 
					
						
							|  |  |  |         self.assertEqual(P('/a/b').suffixes, []) | 
					
						
							|  |  |  |         self.assertEqual(P('/a/b/.').suffixes, []) | 
					
						
							|  |  |  |         self.assertEqual(P('a/b.py').suffixes, ['.py']) | 
					
						
							|  |  |  |         self.assertEqual(P('/a/b.py').suffixes, ['.py']) | 
					
						
							|  |  |  |         self.assertEqual(P('a/.hgrc').suffixes, []) | 
					
						
							|  |  |  |         self.assertEqual(P('/a/.hgrc').suffixes, []) | 
					
						
							|  |  |  |         self.assertEqual(P('a/.hg.rc').suffixes, ['.rc']) | 
					
						
							|  |  |  |         self.assertEqual(P('/a/.hg.rc').suffixes, ['.rc']) | 
					
						
							|  |  |  |         self.assertEqual(P('a/b.tar.gz').suffixes, ['.tar', '.gz']) | 
					
						
							|  |  |  |         self.assertEqual(P('/a/b.tar.gz').suffixes, ['.tar', '.gz']) | 
					
						
							|  |  |  |         self.assertEqual(P('a/Some name. Ending with a dot.').suffixes, []) | 
					
						
							|  |  |  |         self.assertEqual(P('/a/Some name. Ending with a dot.').suffixes, []) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-01-27 02:16:17 +00:00
										 |  |  |     @needs_windows | 
					
						
							|  |  |  |     def test_suffixes_windows(self): | 
					
						
							|  |  |  |         P = self.cls | 
					
						
							|  |  |  |         self.assertEqual(P('c:').suffixes, []) | 
					
						
							|  |  |  |         self.assertEqual(P('c:/').suffixes, []) | 
					
						
							|  |  |  |         self.assertEqual(P('c:a/b').suffixes, []) | 
					
						
							|  |  |  |         self.assertEqual(P('c:/a/b').suffixes, []) | 
					
						
							|  |  |  |         self.assertEqual(P('c:a/b.py').suffixes, ['.py']) | 
					
						
							|  |  |  |         self.assertEqual(P('c:/a/b.py').suffixes, ['.py']) | 
					
						
							|  |  |  |         self.assertEqual(P('c:a/.hgrc').suffixes, []) | 
					
						
							|  |  |  |         self.assertEqual(P('c:/a/.hgrc').suffixes, []) | 
					
						
							|  |  |  |         self.assertEqual(P('c:a/.hg.rc').suffixes, ['.rc']) | 
					
						
							|  |  |  |         self.assertEqual(P('c:/a/.hg.rc').suffixes, ['.rc']) | 
					
						
							|  |  |  |         self.assertEqual(P('c:a/b.tar.gz').suffixes, ['.tar', '.gz']) | 
					
						
							|  |  |  |         self.assertEqual(P('c:/a/b.tar.gz').suffixes, ['.tar', '.gz']) | 
					
						
							|  |  |  |         self.assertEqual(P('//My.py/Share.php').suffixes, []) | 
					
						
							|  |  |  |         self.assertEqual(P('//My.py/Share.php/a/b').suffixes, []) | 
					
						
							|  |  |  |         self.assertEqual(P('c:a/Some name. Ending with a dot.').suffixes, []) | 
					
						
							|  |  |  |         self.assertEqual(P('c:/a/Some name. Ending with a dot.').suffixes, []) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-01-06 17:03:07 +00:00
										 |  |  |     def test_stem_empty(self): | 
					
						
							| 
									
										
										
										
											2023-12-16 19:04:33 +00:00
										 |  |  |         P = self.cls | 
					
						
							|  |  |  |         self.assertEqual(P('').stem, '') | 
					
						
							| 
									
										
										
										
											2024-01-09 23:52:15 +00:00
										 |  |  |         self.assertEqual(P('.').stem, '.') | 
					
						
							| 
									
										
										
										
											2024-01-06 17:03:07 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_stem_common(self): | 
					
						
							|  |  |  |         P = self.cls | 
					
						
							| 
									
										
										
										
											2023-12-16 19:04:33 +00:00
										 |  |  |         self.assertEqual(P('..').stem, '..') | 
					
						
							|  |  |  |         self.assertEqual(P('/').stem, '') | 
					
						
							|  |  |  |         self.assertEqual(P('a/b').stem, 'b') | 
					
						
							|  |  |  |         self.assertEqual(P('a/b.py').stem, 'b') | 
					
						
							|  |  |  |         self.assertEqual(P('a/.hgrc').stem, '.hgrc') | 
					
						
							|  |  |  |         self.assertEqual(P('a/.hg.rc').stem, '.hg') | 
					
						
							|  |  |  |         self.assertEqual(P('a/b.tar.gz').stem, 'b.tar') | 
					
						
							|  |  |  |         self.assertEqual(P('a/Some name. Ending with a dot.').stem, | 
					
						
							|  |  |  |                          'Some name. Ending with a dot.') | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-01-27 02:16:17 +00:00
										 |  |  |     @needs_windows | 
					
						
							|  |  |  |     def test_stem_windows(self): | 
					
						
							|  |  |  |         P = self.cls | 
					
						
							|  |  |  |         self.assertEqual(P('c:').stem, '') | 
					
						
							|  |  |  |         self.assertEqual(P('c:.').stem, '') | 
					
						
							|  |  |  |         self.assertEqual(P('c:..').stem, '..') | 
					
						
							|  |  |  |         self.assertEqual(P('c:/').stem, '') | 
					
						
							|  |  |  |         self.assertEqual(P('c:a/b').stem, 'b') | 
					
						
							|  |  |  |         self.assertEqual(P('c:a/b.py').stem, 'b') | 
					
						
							|  |  |  |         self.assertEqual(P('c:a/.hgrc').stem, '.hgrc') | 
					
						
							|  |  |  |         self.assertEqual(P('c:a/.hg.rc').stem, '.hg') | 
					
						
							|  |  |  |         self.assertEqual(P('c:a/b.tar.gz').stem, 'b.tar') | 
					
						
							|  |  |  |         self.assertEqual(P('c:a/Some name. Ending with a dot.').stem, | 
					
						
							|  |  |  |                          'Some name. Ending with a dot.') | 
					
						
							| 
									
										
										
										
											2023-12-16 19:04:33 +00:00
										 |  |  |     def test_with_name_common(self): | 
					
						
							|  |  |  |         P = self.cls | 
					
						
							|  |  |  |         self.assertEqual(P('a/b').with_name('d.xml'), P('a/d.xml')) | 
					
						
							|  |  |  |         self.assertEqual(P('/a/b').with_name('d.xml'), P('/a/d.xml')) | 
					
						
							|  |  |  |         self.assertEqual(P('a/b.py').with_name('d.xml'), P('a/d.xml')) | 
					
						
							|  |  |  |         self.assertEqual(P('/a/b.py').with_name('d.xml'), P('/a/d.xml')) | 
					
						
							|  |  |  |         self.assertEqual(P('a/Dot ending.').with_name('d.xml'), P('a/d.xml')) | 
					
						
							|  |  |  |         self.assertEqual(P('/a/Dot ending.').with_name('d.xml'), P('/a/d.xml')) | 
					
						
							| 
									
										
										
										
											2024-01-06 17:03:07 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-01-27 02:16:17 +00:00
										 |  |  |     @needs_windows | 
					
						
							|  |  |  |     def test_with_name_windows(self): | 
					
						
							|  |  |  |         P = self.cls | 
					
						
							|  |  |  |         self.assertEqual(P('c:a/b').with_name('d.xml'), P('c:a/d.xml')) | 
					
						
							|  |  |  |         self.assertEqual(P('c:/a/b').with_name('d.xml'), P('c:/a/d.xml')) | 
					
						
							|  |  |  |         self.assertEqual(P('c:a/Dot ending.').with_name('d.xml'), P('c:a/d.xml')) | 
					
						
							|  |  |  |         self.assertEqual(P('c:/a/Dot ending.').with_name('d.xml'), P('c:/a/d.xml')) | 
					
						
							|  |  |  |         self.assertRaises(ValueError, P('c:').with_name, 'd.xml') | 
					
						
							|  |  |  |         self.assertRaises(ValueError, P('c:/').with_name, 'd.xml') | 
					
						
							|  |  |  |         self.assertRaises(ValueError, P('//My/Share').with_name, 'd.xml') | 
					
						
							|  |  |  |         self.assertEqual(str(P('a').with_name('d:')), '.\\d:') | 
					
						
							|  |  |  |         self.assertEqual(str(P('a').with_name('d:e')), '.\\d:e') | 
					
						
							|  |  |  |         self.assertEqual(P('c:a/b').with_name('d:'), P('c:a/d:')) | 
					
						
							|  |  |  |         self.assertEqual(P('c:a/b').with_name('d:e'), P('c:a/d:e')) | 
					
						
							|  |  |  |         self.assertRaises(ValueError, P('c:a/b').with_name, 'd:/e') | 
					
						
							|  |  |  |         self.assertRaises(ValueError, P('c:a/b').with_name, '//My/Share') | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-01-06 17:03:07 +00:00
										 |  |  |     def test_with_name_empty(self): | 
					
						
							|  |  |  |         P = self.cls | 
					
						
							| 
									
										
										
										
											2024-01-09 23:52:15 +00:00
										 |  |  |         self.assertEqual(P('').with_name('d.xml'), P('d.xml')) | 
					
						
							|  |  |  |         self.assertEqual(P('.').with_name('d.xml'), P('d.xml')) | 
					
						
							|  |  |  |         self.assertEqual(P('/').with_name('d.xml'), P('/d.xml')) | 
					
						
							|  |  |  |         self.assertEqual(P('a/b').with_name(''), P('a/')) | 
					
						
							|  |  |  |         self.assertEqual(P('a/b').with_name('.'), P('a/.')) | 
					
						
							| 
									
										
										
										
											2024-01-06 17:03:07 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_with_name_seps(self): | 
					
						
							|  |  |  |         P = self.cls | 
					
						
							| 
									
										
										
										
											2023-12-16 19:04:33 +00:00
										 |  |  |         self.assertRaises(ValueError, P('a/b').with_name, '/c') | 
					
						
							|  |  |  |         self.assertRaises(ValueError, P('a/b').with_name, 'c/') | 
					
						
							|  |  |  |         self.assertRaises(ValueError, P('a/b').with_name, 'c/d') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_with_stem_common(self): | 
					
						
							|  |  |  |         P = self.cls | 
					
						
							|  |  |  |         self.assertEqual(P('a/b').with_stem('d'), P('a/d')) | 
					
						
							|  |  |  |         self.assertEqual(P('/a/b').with_stem('d'), P('/a/d')) | 
					
						
							|  |  |  |         self.assertEqual(P('a/b.py').with_stem('d'), P('a/d.py')) | 
					
						
							|  |  |  |         self.assertEqual(P('/a/b.py').with_stem('d'), P('/a/d.py')) | 
					
						
							|  |  |  |         self.assertEqual(P('/a/b.tar.gz').with_stem('d'), P('/a/d.gz')) | 
					
						
							|  |  |  |         self.assertEqual(P('a/Dot ending.').with_stem('d'), P('a/d')) | 
					
						
							|  |  |  |         self.assertEqual(P('/a/Dot ending.').with_stem('d'), P('/a/d')) | 
					
						
							| 
									
										
										
										
											2024-01-06 17:03:07 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-01-27 02:16:17 +00:00
										 |  |  |     @needs_windows | 
					
						
							|  |  |  |     def test_with_stem_windows(self): | 
					
						
							|  |  |  |         P = self.cls | 
					
						
							|  |  |  |         self.assertEqual(P('c:a/b').with_stem('d'), P('c:a/d')) | 
					
						
							|  |  |  |         self.assertEqual(P('c:/a/b').with_stem('d'), P('c:/a/d')) | 
					
						
							|  |  |  |         self.assertEqual(P('c:a/Dot ending.').with_stem('d'), P('c:a/d')) | 
					
						
							|  |  |  |         self.assertEqual(P('c:/a/Dot ending.').with_stem('d'), P('c:/a/d')) | 
					
						
							|  |  |  |         self.assertRaises(ValueError, P('c:').with_stem, 'd') | 
					
						
							|  |  |  |         self.assertRaises(ValueError, P('c:/').with_stem, 'd') | 
					
						
							|  |  |  |         self.assertRaises(ValueError, P('//My/Share').with_stem, 'd') | 
					
						
							|  |  |  |         self.assertEqual(str(P('a').with_stem('d:')), '.\\d:') | 
					
						
							|  |  |  |         self.assertEqual(str(P('a').with_stem('d:e')), '.\\d:e') | 
					
						
							|  |  |  |         self.assertEqual(P('c:a/b').with_stem('d:'), P('c:a/d:')) | 
					
						
							|  |  |  |         self.assertEqual(P('c:a/b').with_stem('d:e'), P('c:a/d:e')) | 
					
						
							|  |  |  |         self.assertRaises(ValueError, P('c:a/b').with_stem, 'd:/e') | 
					
						
							|  |  |  |         self.assertRaises(ValueError, P('c:a/b').with_stem, '//My/Share') | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-01-06 17:03:07 +00:00
										 |  |  |     def test_with_stem_empty(self): | 
					
						
							|  |  |  |         P = self.cls | 
					
						
							| 
									
										
										
										
											2024-01-09 23:52:15 +00:00
										 |  |  |         self.assertEqual(P('').with_stem('d'), P('d')) | 
					
						
							|  |  |  |         self.assertEqual(P('.').with_stem('d'), P('d')) | 
					
						
							|  |  |  |         self.assertEqual(P('/').with_stem('d'), P('/d')) | 
					
						
							|  |  |  |         self.assertEqual(P('a/b').with_stem(''), P('a/')) | 
					
						
							|  |  |  |         self.assertEqual(P('a/b').with_stem('.'), P('a/.')) | 
					
						
							| 
									
										
										
										
											2024-01-06 17:03:07 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_with_stem_seps(self): | 
					
						
							|  |  |  |         P = self.cls | 
					
						
							| 
									
										
										
										
											2023-12-16 19:04:33 +00:00
										 |  |  |         self.assertRaises(ValueError, P('a/b').with_stem, '/c') | 
					
						
							|  |  |  |         self.assertRaises(ValueError, P('a/b').with_stem, 'c/') | 
					
						
							|  |  |  |         self.assertRaises(ValueError, P('a/b').with_stem, 'c/d') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_with_suffix_common(self): | 
					
						
							|  |  |  |         P = self.cls | 
					
						
							|  |  |  |         self.assertEqual(P('a/b').with_suffix('.gz'), P('a/b.gz')) | 
					
						
							|  |  |  |         self.assertEqual(P('/a/b').with_suffix('.gz'), P('/a/b.gz')) | 
					
						
							|  |  |  |         self.assertEqual(P('a/b.py').with_suffix('.gz'), P('a/b.gz')) | 
					
						
							|  |  |  |         self.assertEqual(P('/a/b.py').with_suffix('.gz'), P('/a/b.gz')) | 
					
						
							|  |  |  |         # Stripping suffix. | 
					
						
							|  |  |  |         self.assertEqual(P('a/b.py').with_suffix(''), P('a/b')) | 
					
						
							|  |  |  |         self.assertEqual(P('/a/b').with_suffix(''), P('/a/b')) | 
					
						
							| 
									
										
										
										
											2024-01-06 17:03:07 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-01-27 02:16:17 +00:00
										 |  |  |     @needs_windows | 
					
						
							|  |  |  |     def test_with_suffix_windows(self): | 
					
						
							|  |  |  |         P = self.cls | 
					
						
							|  |  |  |         self.assertEqual(P('c:a/b').with_suffix('.gz'), P('c:a/b.gz')) | 
					
						
							|  |  |  |         self.assertEqual(P('c:/a/b').with_suffix('.gz'), P('c:/a/b.gz')) | 
					
						
							|  |  |  |         self.assertEqual(P('c:a/b.py').with_suffix('.gz'), P('c:a/b.gz')) | 
					
						
							|  |  |  |         self.assertEqual(P('c:/a/b.py').with_suffix('.gz'), P('c:/a/b.gz')) | 
					
						
							|  |  |  |         # Path doesn't have a "filename" component. | 
					
						
							|  |  |  |         self.assertRaises(ValueError, P('').with_suffix, '.gz') | 
					
						
							|  |  |  |         self.assertRaises(ValueError, P('.').with_suffix, '.gz') | 
					
						
							|  |  |  |         self.assertRaises(ValueError, P('/').with_suffix, '.gz') | 
					
						
							|  |  |  |         self.assertRaises(ValueError, P('//My/Share').with_suffix, '.gz') | 
					
						
							|  |  |  |         # Invalid suffix. | 
					
						
							|  |  |  |         self.assertRaises(ValueError, P('c:a/b').with_suffix, 'gz') | 
					
						
							|  |  |  |         self.assertRaises(ValueError, P('c:a/b').with_suffix, '/') | 
					
						
							|  |  |  |         self.assertRaises(ValueError, P('c:a/b').with_suffix, '\\') | 
					
						
							|  |  |  |         self.assertRaises(ValueError, P('c:a/b').with_suffix, 'c:') | 
					
						
							|  |  |  |         self.assertRaises(ValueError, P('c:a/b').with_suffix, '/.gz') | 
					
						
							|  |  |  |         self.assertRaises(ValueError, P('c:a/b').with_suffix, '\\.gz') | 
					
						
							|  |  |  |         self.assertRaises(ValueError, P('c:a/b').with_suffix, 'c:.gz') | 
					
						
							|  |  |  |         self.assertRaises(ValueError, P('c:a/b').with_suffix, 'c/d') | 
					
						
							|  |  |  |         self.assertRaises(ValueError, P('c:a/b').with_suffix, 'c\\d') | 
					
						
							|  |  |  |         self.assertRaises(ValueError, P('c:a/b').with_suffix, '.c/d') | 
					
						
							|  |  |  |         self.assertRaises(ValueError, P('c:a/b').with_suffix, '.c\\d') | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-01-06 17:03:07 +00:00
										 |  |  |     def test_with_suffix_empty(self): | 
					
						
							|  |  |  |         P = self.cls | 
					
						
							| 
									
										
										
										
											2023-12-16 19:04:33 +00:00
										 |  |  |         # Path doesn't have a "filename" component. | 
					
						
							| 
									
										
										
										
											2024-01-30 14:25:16 +00:00
										 |  |  |         self.assertRaises(ValueError, P('').with_suffix, '.gz') | 
					
						
							|  |  |  |         self.assertRaises(ValueError, P('/').with_suffix, '.gz') | 
					
						
							| 
									
										
										
										
											2024-01-06 17:03:07 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_with_suffix_seps(self): | 
					
						
							|  |  |  |         P = self.cls | 
					
						
							| 
									
										
										
										
											2023-12-16 19:04:33 +00:00
										 |  |  |         # Invalid suffix. | 
					
						
							|  |  |  |         self.assertRaises(ValueError, P('a/b').with_suffix, 'gz') | 
					
						
							|  |  |  |         self.assertRaises(ValueError, P('a/b').with_suffix, '/') | 
					
						
							|  |  |  |         self.assertRaises(ValueError, P('a/b').with_suffix, '.') | 
					
						
							|  |  |  |         self.assertRaises(ValueError, P('a/b').with_suffix, '/.gz') | 
					
						
							|  |  |  |         self.assertRaises(ValueError, P('a/b').with_suffix, 'c/d') | 
					
						
							|  |  |  |         self.assertRaises(ValueError, P('a/b').with_suffix, '.c/.d') | 
					
						
							|  |  |  |         self.assertRaises(ValueError, P('a/b').with_suffix, './.d') | 
					
						
							|  |  |  |         self.assertRaises(ValueError, P('a/b').with_suffix, '.d/.') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_relative_to_common(self): | 
					
						
							|  |  |  |         P = self.cls | 
					
						
							|  |  |  |         p = P('a/b') | 
					
						
							|  |  |  |         self.assertRaises(TypeError, p.relative_to) | 
					
						
							|  |  |  |         self.assertRaises(TypeError, p.relative_to, b'a') | 
					
						
							| 
									
										
										
										
											2024-01-10 01:12:58 +00:00
										 |  |  |         self.assertEqual(p.relative_to(P('')), P('a/b')) | 
					
						
							| 
									
										
										
										
											2023-12-16 19:04:33 +00:00
										 |  |  |         self.assertEqual(p.relative_to(''), P('a/b')) | 
					
						
							|  |  |  |         self.assertEqual(p.relative_to(P('a')), P('b')) | 
					
						
							|  |  |  |         self.assertEqual(p.relative_to('a'), P('b')) | 
					
						
							|  |  |  |         self.assertEqual(p.relative_to('a/'), P('b')) | 
					
						
							| 
									
										
										
										
											2024-01-10 01:12:58 +00:00
										 |  |  |         self.assertEqual(p.relative_to(P('a/b')), P('')) | 
					
						
							|  |  |  |         self.assertEqual(p.relative_to('a/b'), P('')) | 
					
						
							|  |  |  |         self.assertEqual(p.relative_to(P(''), walk_up=True), P('a/b')) | 
					
						
							| 
									
										
										
										
											2023-12-16 19:04:33 +00:00
										 |  |  |         self.assertEqual(p.relative_to('', walk_up=True), P('a/b')) | 
					
						
							|  |  |  |         self.assertEqual(p.relative_to(P('a'), walk_up=True), P('b')) | 
					
						
							|  |  |  |         self.assertEqual(p.relative_to('a', walk_up=True), P('b')) | 
					
						
							|  |  |  |         self.assertEqual(p.relative_to('a/', walk_up=True), P('b')) | 
					
						
							| 
									
										
										
										
											2024-01-10 01:12:58 +00:00
										 |  |  |         self.assertEqual(p.relative_to(P('a/b'), walk_up=True), P('')) | 
					
						
							|  |  |  |         self.assertEqual(p.relative_to('a/b', walk_up=True), P('')) | 
					
						
							| 
									
										
										
										
											2023-12-16 19:04:33 +00:00
										 |  |  |         self.assertEqual(p.relative_to(P('a/c'), walk_up=True), P('../b')) | 
					
						
							|  |  |  |         self.assertEqual(p.relative_to('a/c', walk_up=True), P('../b')) | 
					
						
							|  |  |  |         self.assertEqual(p.relative_to(P('a/b/c'), walk_up=True), P('..')) | 
					
						
							|  |  |  |         self.assertEqual(p.relative_to('a/b/c', walk_up=True), P('..')) | 
					
						
							|  |  |  |         self.assertEqual(p.relative_to(P('c'), walk_up=True), P('../a/b')) | 
					
						
							|  |  |  |         self.assertEqual(p.relative_to('c', walk_up=True), P('../a/b')) | 
					
						
							|  |  |  |         # Unrelated paths. | 
					
						
							|  |  |  |         self.assertRaises(ValueError, p.relative_to, P('c')) | 
					
						
							|  |  |  |         self.assertRaises(ValueError, p.relative_to, P('a/b/c')) | 
					
						
							|  |  |  |         self.assertRaises(ValueError, p.relative_to, P('a/c')) | 
					
						
							|  |  |  |         self.assertRaises(ValueError, p.relative_to, P('/a')) | 
					
						
							|  |  |  |         self.assertRaises(ValueError, p.relative_to, P("../a")) | 
					
						
							|  |  |  |         self.assertRaises(ValueError, p.relative_to, P("a/..")) | 
					
						
							|  |  |  |         self.assertRaises(ValueError, p.relative_to, P("/a/..")) | 
					
						
							|  |  |  |         self.assertRaises(ValueError, p.relative_to, P('/'), walk_up=True) | 
					
						
							|  |  |  |         self.assertRaises(ValueError, p.relative_to, P('/a'), walk_up=True) | 
					
						
							|  |  |  |         self.assertRaises(ValueError, p.relative_to, P("../a"), walk_up=True) | 
					
						
							|  |  |  |         self.assertRaises(ValueError, p.relative_to, P("a/.."), walk_up=True) | 
					
						
							|  |  |  |         self.assertRaises(ValueError, p.relative_to, P("/a/.."), walk_up=True) | 
					
						
							|  |  |  |         p = P('/a/b') | 
					
						
							|  |  |  |         self.assertEqual(p.relative_to(P('/')), P('a/b')) | 
					
						
							|  |  |  |         self.assertEqual(p.relative_to('/'), P('a/b')) | 
					
						
							|  |  |  |         self.assertEqual(p.relative_to(P('/a')), P('b')) | 
					
						
							|  |  |  |         self.assertEqual(p.relative_to('/a'), P('b')) | 
					
						
							|  |  |  |         self.assertEqual(p.relative_to('/a/'), P('b')) | 
					
						
							| 
									
										
										
										
											2024-01-10 01:12:58 +00:00
										 |  |  |         self.assertEqual(p.relative_to(P('/a/b')), P('')) | 
					
						
							|  |  |  |         self.assertEqual(p.relative_to('/a/b'), P('')) | 
					
						
							| 
									
										
										
										
											2023-12-16 19:04:33 +00:00
										 |  |  |         self.assertEqual(p.relative_to(P('/'), walk_up=True), P('a/b')) | 
					
						
							|  |  |  |         self.assertEqual(p.relative_to('/', walk_up=True), P('a/b')) | 
					
						
							|  |  |  |         self.assertEqual(p.relative_to(P('/a'), walk_up=True), P('b')) | 
					
						
							|  |  |  |         self.assertEqual(p.relative_to('/a', walk_up=True), P('b')) | 
					
						
							|  |  |  |         self.assertEqual(p.relative_to('/a/', walk_up=True), P('b')) | 
					
						
							| 
									
										
										
										
											2024-01-10 01:12:58 +00:00
										 |  |  |         self.assertEqual(p.relative_to(P('/a/b'), walk_up=True), P('')) | 
					
						
							|  |  |  |         self.assertEqual(p.relative_to('/a/b', walk_up=True), P('')) | 
					
						
							| 
									
										
										
										
											2023-12-16 19:04:33 +00:00
										 |  |  |         self.assertEqual(p.relative_to(P('/a/c'), walk_up=True), P('../b')) | 
					
						
							|  |  |  |         self.assertEqual(p.relative_to('/a/c', walk_up=True), P('../b')) | 
					
						
							|  |  |  |         self.assertEqual(p.relative_to(P('/a/b/c'), walk_up=True), P('..')) | 
					
						
							|  |  |  |         self.assertEqual(p.relative_to('/a/b/c', walk_up=True), P('..')) | 
					
						
							|  |  |  |         self.assertEqual(p.relative_to(P('/c'), walk_up=True), P('../a/b')) | 
					
						
							|  |  |  |         self.assertEqual(p.relative_to('/c', walk_up=True), P('../a/b')) | 
					
						
							|  |  |  |         # Unrelated paths. | 
					
						
							|  |  |  |         self.assertRaises(ValueError, p.relative_to, P('/c')) | 
					
						
							|  |  |  |         self.assertRaises(ValueError, p.relative_to, P('/a/b/c')) | 
					
						
							|  |  |  |         self.assertRaises(ValueError, p.relative_to, P('/a/c')) | 
					
						
							| 
									
										
										
										
											2024-01-10 01:12:58 +00:00
										 |  |  |         self.assertRaises(ValueError, p.relative_to, P('')) | 
					
						
							| 
									
										
										
										
											2023-12-16 19:04:33 +00:00
										 |  |  |         self.assertRaises(ValueError, p.relative_to, '') | 
					
						
							|  |  |  |         self.assertRaises(ValueError, p.relative_to, P('a')) | 
					
						
							|  |  |  |         self.assertRaises(ValueError, p.relative_to, P("../a")) | 
					
						
							|  |  |  |         self.assertRaises(ValueError, p.relative_to, P("a/..")) | 
					
						
							|  |  |  |         self.assertRaises(ValueError, p.relative_to, P("/a/..")) | 
					
						
							|  |  |  |         self.assertRaises(ValueError, p.relative_to, P(''), walk_up=True) | 
					
						
							|  |  |  |         self.assertRaises(ValueError, p.relative_to, P('a'), walk_up=True) | 
					
						
							|  |  |  |         self.assertRaises(ValueError, p.relative_to, P("../a"), walk_up=True) | 
					
						
							|  |  |  |         self.assertRaises(ValueError, p.relative_to, P("a/.."), walk_up=True) | 
					
						
							|  |  |  |         self.assertRaises(ValueError, p.relative_to, P("/a/.."), walk_up=True) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-01-27 02:16:17 +00:00
										 |  |  |     @needs_windows | 
					
						
							|  |  |  |     def test_relative_to_windows(self): | 
					
						
							|  |  |  |         P = self.cls | 
					
						
							|  |  |  |         p = P('C:Foo/Bar') | 
					
						
							|  |  |  |         self.assertEqual(p.relative_to(P('c:')), P('Foo/Bar')) | 
					
						
							|  |  |  |         self.assertEqual(p.relative_to('c:'), P('Foo/Bar')) | 
					
						
							|  |  |  |         self.assertEqual(p.relative_to(P('c:foO')), P('Bar')) | 
					
						
							|  |  |  |         self.assertEqual(p.relative_to('c:foO'), P('Bar')) | 
					
						
							|  |  |  |         self.assertEqual(p.relative_to('c:foO/'), P('Bar')) | 
					
						
							|  |  |  |         self.assertEqual(p.relative_to(P('c:foO/baR')), P()) | 
					
						
							|  |  |  |         self.assertEqual(p.relative_to('c:foO/baR'), P()) | 
					
						
							|  |  |  |         self.assertEqual(p.relative_to(P('c:'), walk_up=True), P('Foo/Bar')) | 
					
						
							|  |  |  |         self.assertEqual(p.relative_to('c:', walk_up=True), P('Foo/Bar')) | 
					
						
							|  |  |  |         self.assertEqual(p.relative_to(P('c:foO'), walk_up=True), P('Bar')) | 
					
						
							|  |  |  |         self.assertEqual(p.relative_to('c:foO', walk_up=True), P('Bar')) | 
					
						
							|  |  |  |         self.assertEqual(p.relative_to('c:foO/', walk_up=True), P('Bar')) | 
					
						
							|  |  |  |         self.assertEqual(p.relative_to(P('c:foO/baR'), walk_up=True), P()) | 
					
						
							|  |  |  |         self.assertEqual(p.relative_to('c:foO/baR', walk_up=True), P()) | 
					
						
							|  |  |  |         self.assertEqual(p.relative_to(P('C:Foo/Bar/Baz'), walk_up=True), P('..')) | 
					
						
							|  |  |  |         self.assertEqual(p.relative_to(P('C:Foo/Baz'), walk_up=True), P('../Bar')) | 
					
						
							|  |  |  |         self.assertEqual(p.relative_to(P('C:Baz/Bar'), walk_up=True), P('../../Foo/Bar')) | 
					
						
							|  |  |  |         # Unrelated paths. | 
					
						
							|  |  |  |         self.assertRaises(ValueError, p.relative_to, P()) | 
					
						
							|  |  |  |         self.assertRaises(ValueError, p.relative_to, '') | 
					
						
							|  |  |  |         self.assertRaises(ValueError, p.relative_to, P('d:')) | 
					
						
							|  |  |  |         self.assertRaises(ValueError, p.relative_to, P('/')) | 
					
						
							|  |  |  |         self.assertRaises(ValueError, p.relative_to, P('Foo')) | 
					
						
							|  |  |  |         self.assertRaises(ValueError, p.relative_to, P('/Foo')) | 
					
						
							|  |  |  |         self.assertRaises(ValueError, p.relative_to, P('C:/Foo')) | 
					
						
							|  |  |  |         self.assertRaises(ValueError, p.relative_to, P('C:Foo/Bar/Baz')) | 
					
						
							|  |  |  |         self.assertRaises(ValueError, p.relative_to, P('C:Foo/Baz')) | 
					
						
							|  |  |  |         self.assertRaises(ValueError, p.relative_to, P(), walk_up=True) | 
					
						
							|  |  |  |         self.assertRaises(ValueError, p.relative_to, '', walk_up=True) | 
					
						
							|  |  |  |         self.assertRaises(ValueError, p.relative_to, P('d:'), walk_up=True) | 
					
						
							|  |  |  |         self.assertRaises(ValueError, p.relative_to, P('/'), walk_up=True) | 
					
						
							|  |  |  |         self.assertRaises(ValueError, p.relative_to, P('Foo'), walk_up=True) | 
					
						
							|  |  |  |         self.assertRaises(ValueError, p.relative_to, P('/Foo'), walk_up=True) | 
					
						
							|  |  |  |         self.assertRaises(ValueError, p.relative_to, P('C:/Foo'), walk_up=True) | 
					
						
							|  |  |  |         p = P('C:/Foo/Bar') | 
					
						
							|  |  |  |         self.assertEqual(p.relative_to(P('c:/')), P('Foo/Bar')) | 
					
						
							|  |  |  |         self.assertEqual(p.relative_to('c:/'), P('Foo/Bar')) | 
					
						
							|  |  |  |         self.assertEqual(p.relative_to(P('c:/foO')), P('Bar')) | 
					
						
							|  |  |  |         self.assertEqual(p.relative_to('c:/foO'), P('Bar')) | 
					
						
							|  |  |  |         self.assertEqual(p.relative_to('c:/foO/'), P('Bar')) | 
					
						
							|  |  |  |         self.assertEqual(p.relative_to(P('c:/foO/baR')), P()) | 
					
						
							|  |  |  |         self.assertEqual(p.relative_to('c:/foO/baR'), P()) | 
					
						
							|  |  |  |         self.assertEqual(p.relative_to(P('c:/'), walk_up=True), P('Foo/Bar')) | 
					
						
							|  |  |  |         self.assertEqual(p.relative_to('c:/', walk_up=True), P('Foo/Bar')) | 
					
						
							|  |  |  |         self.assertEqual(p.relative_to(P('c:/foO'), walk_up=True), P('Bar')) | 
					
						
							|  |  |  |         self.assertEqual(p.relative_to('c:/foO', walk_up=True), P('Bar')) | 
					
						
							|  |  |  |         self.assertEqual(p.relative_to('c:/foO/', walk_up=True), P('Bar')) | 
					
						
							|  |  |  |         self.assertEqual(p.relative_to(P('c:/foO/baR'), walk_up=True), P()) | 
					
						
							|  |  |  |         self.assertEqual(p.relative_to('c:/foO/baR', walk_up=True), P()) | 
					
						
							|  |  |  |         self.assertEqual(p.relative_to('C:/Baz', walk_up=True), P('../Foo/Bar')) | 
					
						
							|  |  |  |         self.assertEqual(p.relative_to('C:/Foo/Bar/Baz', walk_up=True), P('..')) | 
					
						
							|  |  |  |         self.assertEqual(p.relative_to('C:/Foo/Baz', walk_up=True), P('../Bar')) | 
					
						
							|  |  |  |         # Unrelated paths. | 
					
						
							|  |  |  |         self.assertRaises(ValueError, p.relative_to, 'c:') | 
					
						
							|  |  |  |         self.assertRaises(ValueError, p.relative_to, P('c:')) | 
					
						
							|  |  |  |         self.assertRaises(ValueError, p.relative_to, P('C:/Baz')) | 
					
						
							|  |  |  |         self.assertRaises(ValueError, p.relative_to, P('C:/Foo/Bar/Baz')) | 
					
						
							|  |  |  |         self.assertRaises(ValueError, p.relative_to, P('C:/Foo/Baz')) | 
					
						
							|  |  |  |         self.assertRaises(ValueError, p.relative_to, P('C:Foo')) | 
					
						
							|  |  |  |         self.assertRaises(ValueError, p.relative_to, P('d:')) | 
					
						
							|  |  |  |         self.assertRaises(ValueError, p.relative_to, P('d:/')) | 
					
						
							|  |  |  |         self.assertRaises(ValueError, p.relative_to, P('/')) | 
					
						
							|  |  |  |         self.assertRaises(ValueError, p.relative_to, P('/Foo')) | 
					
						
							|  |  |  |         self.assertRaises(ValueError, p.relative_to, P('//C/Foo')) | 
					
						
							|  |  |  |         self.assertRaises(ValueError, p.relative_to, 'c:', walk_up=True) | 
					
						
							|  |  |  |         self.assertRaises(ValueError, p.relative_to, P('c:'), walk_up=True) | 
					
						
							|  |  |  |         self.assertRaises(ValueError, p.relative_to, P('C:Foo'), walk_up=True) | 
					
						
							|  |  |  |         self.assertRaises(ValueError, p.relative_to, P('d:'), walk_up=True) | 
					
						
							|  |  |  |         self.assertRaises(ValueError, p.relative_to, P('d:/'), walk_up=True) | 
					
						
							|  |  |  |         self.assertRaises(ValueError, p.relative_to, P('/'), walk_up=True) | 
					
						
							|  |  |  |         self.assertRaises(ValueError, p.relative_to, P('/Foo'), walk_up=True) | 
					
						
							|  |  |  |         self.assertRaises(ValueError, p.relative_to, P('//C/Foo'), walk_up=True) | 
					
						
							|  |  |  |         # UNC paths. | 
					
						
							|  |  |  |         p = P('//Server/Share/Foo/Bar') | 
					
						
							|  |  |  |         self.assertEqual(p.relative_to(P('//sErver/sHare')), P('Foo/Bar')) | 
					
						
							|  |  |  |         self.assertEqual(p.relative_to('//sErver/sHare'), P('Foo/Bar')) | 
					
						
							|  |  |  |         self.assertEqual(p.relative_to('//sErver/sHare/'), P('Foo/Bar')) | 
					
						
							|  |  |  |         self.assertEqual(p.relative_to(P('//sErver/sHare/Foo')), P('Bar')) | 
					
						
							|  |  |  |         self.assertEqual(p.relative_to('//sErver/sHare/Foo'), P('Bar')) | 
					
						
							|  |  |  |         self.assertEqual(p.relative_to('//sErver/sHare/Foo/'), P('Bar')) | 
					
						
							|  |  |  |         self.assertEqual(p.relative_to(P('//sErver/sHare/Foo/Bar')), P()) | 
					
						
							|  |  |  |         self.assertEqual(p.relative_to('//sErver/sHare/Foo/Bar'), P()) | 
					
						
							|  |  |  |         self.assertEqual(p.relative_to(P('//sErver/sHare'), walk_up=True), P('Foo/Bar')) | 
					
						
							|  |  |  |         self.assertEqual(p.relative_to('//sErver/sHare', walk_up=True), P('Foo/Bar')) | 
					
						
							|  |  |  |         self.assertEqual(p.relative_to('//sErver/sHare/', walk_up=True), P('Foo/Bar')) | 
					
						
							|  |  |  |         self.assertEqual(p.relative_to(P('//sErver/sHare/Foo'), walk_up=True), P('Bar')) | 
					
						
							|  |  |  |         self.assertEqual(p.relative_to('//sErver/sHare/Foo', walk_up=True), P('Bar')) | 
					
						
							|  |  |  |         self.assertEqual(p.relative_to('//sErver/sHare/Foo/', walk_up=True), P('Bar')) | 
					
						
							|  |  |  |         self.assertEqual(p.relative_to(P('//sErver/sHare/Foo/Bar'), walk_up=True), P()) | 
					
						
							|  |  |  |         self.assertEqual(p.relative_to('//sErver/sHare/Foo/Bar', walk_up=True), P()) | 
					
						
							|  |  |  |         self.assertEqual(p.relative_to(P('//sErver/sHare/bar'), walk_up=True), P('../Foo/Bar')) | 
					
						
							|  |  |  |         self.assertEqual(p.relative_to('//sErver/sHare/bar', walk_up=True), P('../Foo/Bar')) | 
					
						
							|  |  |  |         # Unrelated paths. | 
					
						
							|  |  |  |         self.assertRaises(ValueError, p.relative_to, P('/Server/Share/Foo')) | 
					
						
							|  |  |  |         self.assertRaises(ValueError, p.relative_to, P('c:/Server/Share/Foo')) | 
					
						
							|  |  |  |         self.assertRaises(ValueError, p.relative_to, P('//z/Share/Foo')) | 
					
						
							|  |  |  |         self.assertRaises(ValueError, p.relative_to, P('//Server/z/Foo')) | 
					
						
							|  |  |  |         self.assertRaises(ValueError, p.relative_to, P('/Server/Share/Foo'), walk_up=True) | 
					
						
							|  |  |  |         self.assertRaises(ValueError, p.relative_to, P('c:/Server/Share/Foo'), walk_up=True) | 
					
						
							|  |  |  |         self.assertRaises(ValueError, p.relative_to, P('//z/Share/Foo'), walk_up=True) | 
					
						
							|  |  |  |         self.assertRaises(ValueError, p.relative_to, P('//Server/z/Foo'), walk_up=True) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-12-16 19:04:33 +00:00
										 |  |  |     def test_is_relative_to_common(self): | 
					
						
							|  |  |  |         P = self.cls | 
					
						
							|  |  |  |         p = P('a/b') | 
					
						
							|  |  |  |         self.assertRaises(TypeError, p.is_relative_to) | 
					
						
							|  |  |  |         self.assertRaises(TypeError, p.is_relative_to, b'a') | 
					
						
							| 
									
										
										
										
											2024-01-10 01:12:58 +00:00
										 |  |  |         self.assertTrue(p.is_relative_to(P(''))) | 
					
						
							| 
									
										
										
										
											2023-12-16 19:04:33 +00:00
										 |  |  |         self.assertTrue(p.is_relative_to('')) | 
					
						
							|  |  |  |         self.assertTrue(p.is_relative_to(P('a'))) | 
					
						
							|  |  |  |         self.assertTrue(p.is_relative_to('a/')) | 
					
						
							|  |  |  |         self.assertTrue(p.is_relative_to(P('a/b'))) | 
					
						
							|  |  |  |         self.assertTrue(p.is_relative_to('a/b')) | 
					
						
							|  |  |  |         # Unrelated paths. | 
					
						
							|  |  |  |         self.assertFalse(p.is_relative_to(P('c'))) | 
					
						
							|  |  |  |         self.assertFalse(p.is_relative_to(P('a/b/c'))) | 
					
						
							|  |  |  |         self.assertFalse(p.is_relative_to(P('a/c'))) | 
					
						
							|  |  |  |         self.assertFalse(p.is_relative_to(P('/a'))) | 
					
						
							|  |  |  |         p = P('/a/b') | 
					
						
							|  |  |  |         self.assertTrue(p.is_relative_to(P('/'))) | 
					
						
							|  |  |  |         self.assertTrue(p.is_relative_to('/')) | 
					
						
							|  |  |  |         self.assertTrue(p.is_relative_to(P('/a'))) | 
					
						
							|  |  |  |         self.assertTrue(p.is_relative_to('/a')) | 
					
						
							|  |  |  |         self.assertTrue(p.is_relative_to('/a/')) | 
					
						
							|  |  |  |         self.assertTrue(p.is_relative_to(P('/a/b'))) | 
					
						
							|  |  |  |         self.assertTrue(p.is_relative_to('/a/b')) | 
					
						
							|  |  |  |         # Unrelated paths. | 
					
						
							|  |  |  |         self.assertFalse(p.is_relative_to(P('/c'))) | 
					
						
							|  |  |  |         self.assertFalse(p.is_relative_to(P('/a/b/c'))) | 
					
						
							|  |  |  |         self.assertFalse(p.is_relative_to(P('/a/c'))) | 
					
						
							| 
									
										
										
										
											2024-01-10 01:12:58 +00:00
										 |  |  |         self.assertFalse(p.is_relative_to(P(''))) | 
					
						
							| 
									
										
										
										
											2023-12-16 19:04:33 +00:00
										 |  |  |         self.assertFalse(p.is_relative_to('')) | 
					
						
							|  |  |  |         self.assertFalse(p.is_relative_to(P('a'))) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-01-27 02:16:17 +00:00
										 |  |  |     @needs_windows | 
					
						
							|  |  |  |     def test_is_relative_to_windows(self): | 
					
						
							|  |  |  |         P = self.cls | 
					
						
							|  |  |  |         p = P('C:Foo/Bar') | 
					
						
							|  |  |  |         self.assertTrue(p.is_relative_to(P('c:'))) | 
					
						
							|  |  |  |         self.assertTrue(p.is_relative_to('c:')) | 
					
						
							|  |  |  |         self.assertTrue(p.is_relative_to(P('c:foO'))) | 
					
						
							|  |  |  |         self.assertTrue(p.is_relative_to('c:foO')) | 
					
						
							|  |  |  |         self.assertTrue(p.is_relative_to('c:foO/')) | 
					
						
							|  |  |  |         self.assertTrue(p.is_relative_to(P('c:foO/baR'))) | 
					
						
							|  |  |  |         self.assertTrue(p.is_relative_to('c:foO/baR')) | 
					
						
							|  |  |  |         # Unrelated paths. | 
					
						
							|  |  |  |         self.assertFalse(p.is_relative_to(P())) | 
					
						
							|  |  |  |         self.assertFalse(p.is_relative_to('')) | 
					
						
							|  |  |  |         self.assertFalse(p.is_relative_to(P('d:'))) | 
					
						
							|  |  |  |         self.assertFalse(p.is_relative_to(P('/'))) | 
					
						
							|  |  |  |         self.assertFalse(p.is_relative_to(P('Foo'))) | 
					
						
							|  |  |  |         self.assertFalse(p.is_relative_to(P('/Foo'))) | 
					
						
							|  |  |  |         self.assertFalse(p.is_relative_to(P('C:/Foo'))) | 
					
						
							|  |  |  |         self.assertFalse(p.is_relative_to(P('C:Foo/Bar/Baz'))) | 
					
						
							|  |  |  |         self.assertFalse(p.is_relative_to(P('C:Foo/Baz'))) | 
					
						
							|  |  |  |         p = P('C:/Foo/Bar') | 
					
						
							|  |  |  |         self.assertTrue(p.is_relative_to(P('c:/'))) | 
					
						
							|  |  |  |         self.assertTrue(p.is_relative_to(P('c:/foO'))) | 
					
						
							|  |  |  |         self.assertTrue(p.is_relative_to('c:/foO/')) | 
					
						
							|  |  |  |         self.assertTrue(p.is_relative_to(P('c:/foO/baR'))) | 
					
						
							|  |  |  |         self.assertTrue(p.is_relative_to('c:/foO/baR')) | 
					
						
							|  |  |  |         # Unrelated paths. | 
					
						
							|  |  |  |         self.assertFalse(p.is_relative_to('c:')) | 
					
						
							|  |  |  |         self.assertFalse(p.is_relative_to(P('C:/Baz'))) | 
					
						
							|  |  |  |         self.assertFalse(p.is_relative_to(P('C:/Foo/Bar/Baz'))) | 
					
						
							|  |  |  |         self.assertFalse(p.is_relative_to(P('C:/Foo/Baz'))) | 
					
						
							|  |  |  |         self.assertFalse(p.is_relative_to(P('C:Foo'))) | 
					
						
							|  |  |  |         self.assertFalse(p.is_relative_to(P('d:'))) | 
					
						
							|  |  |  |         self.assertFalse(p.is_relative_to(P('d:/'))) | 
					
						
							|  |  |  |         self.assertFalse(p.is_relative_to(P('/'))) | 
					
						
							|  |  |  |         self.assertFalse(p.is_relative_to(P('/Foo'))) | 
					
						
							|  |  |  |         self.assertFalse(p.is_relative_to(P('//C/Foo'))) | 
					
						
							|  |  |  |         # UNC paths. | 
					
						
							|  |  |  |         p = P('//Server/Share/Foo/Bar') | 
					
						
							|  |  |  |         self.assertTrue(p.is_relative_to(P('//sErver/sHare'))) | 
					
						
							|  |  |  |         self.assertTrue(p.is_relative_to('//sErver/sHare')) | 
					
						
							|  |  |  |         self.assertTrue(p.is_relative_to('//sErver/sHare/')) | 
					
						
							|  |  |  |         self.assertTrue(p.is_relative_to(P('//sErver/sHare/Foo'))) | 
					
						
							|  |  |  |         self.assertTrue(p.is_relative_to('//sErver/sHare/Foo')) | 
					
						
							|  |  |  |         self.assertTrue(p.is_relative_to('//sErver/sHare/Foo/')) | 
					
						
							|  |  |  |         self.assertTrue(p.is_relative_to(P('//sErver/sHare/Foo/Bar'))) | 
					
						
							|  |  |  |         self.assertTrue(p.is_relative_to('//sErver/sHare/Foo/Bar')) | 
					
						
							|  |  |  |         # Unrelated paths. | 
					
						
							|  |  |  |         self.assertFalse(p.is_relative_to(P('/Server/Share/Foo'))) | 
					
						
							|  |  |  |         self.assertFalse(p.is_relative_to(P('c:/Server/Share/Foo'))) | 
					
						
							|  |  |  |         self.assertFalse(p.is_relative_to(P('//z/Share/Foo'))) | 
					
						
							|  |  |  |         self.assertFalse(p.is_relative_to(P('//Server/z/Foo'))) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     @needs_posix | 
					
						
							|  |  |  |     def test_is_absolute_posix(self): | 
					
						
							|  |  |  |         P = self.cls | 
					
						
							|  |  |  |         self.assertFalse(P('').is_absolute()) | 
					
						
							|  |  |  |         self.assertFalse(P('a').is_absolute()) | 
					
						
							|  |  |  |         self.assertFalse(P('a/b/').is_absolute()) | 
					
						
							|  |  |  |         self.assertTrue(P('/').is_absolute()) | 
					
						
							|  |  |  |         self.assertTrue(P('/a').is_absolute()) | 
					
						
							|  |  |  |         self.assertTrue(P('/a/b/').is_absolute()) | 
					
						
							|  |  |  |         self.assertTrue(P('//a').is_absolute()) | 
					
						
							|  |  |  |         self.assertTrue(P('//a/b').is_absolute()) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     @needs_windows | 
					
						
							|  |  |  |     def test_is_absolute_windows(self): | 
					
						
							|  |  |  |         P = self.cls | 
					
						
							|  |  |  |         # Under NT, only paths with both a drive and a root are absolute. | 
					
						
							|  |  |  |         self.assertFalse(P().is_absolute()) | 
					
						
							|  |  |  |         self.assertFalse(P('a').is_absolute()) | 
					
						
							|  |  |  |         self.assertFalse(P('a/b/').is_absolute()) | 
					
						
							|  |  |  |         self.assertFalse(P('/').is_absolute()) | 
					
						
							|  |  |  |         self.assertFalse(P('/a').is_absolute()) | 
					
						
							|  |  |  |         self.assertFalse(P('/a/b/').is_absolute()) | 
					
						
							|  |  |  |         self.assertFalse(P('c:').is_absolute()) | 
					
						
							|  |  |  |         self.assertFalse(P('c:a').is_absolute()) | 
					
						
							|  |  |  |         self.assertFalse(P('c:a/b/').is_absolute()) | 
					
						
							|  |  |  |         self.assertTrue(P('c:/').is_absolute()) | 
					
						
							|  |  |  |         self.assertTrue(P('c:/a').is_absolute()) | 
					
						
							|  |  |  |         self.assertTrue(P('c:/a/b/').is_absolute()) | 
					
						
							|  |  |  |         # UNC paths are absolute by definition. | 
					
						
							|  |  |  |         self.assertTrue(P('//').is_absolute()) | 
					
						
							|  |  |  |         self.assertTrue(P('//a').is_absolute()) | 
					
						
							|  |  |  |         self.assertTrue(P('//a/b').is_absolute()) | 
					
						
							|  |  |  |         self.assertTrue(P('//a/b/').is_absolute()) | 
					
						
							|  |  |  |         self.assertTrue(P('//a/b/c').is_absolute()) | 
					
						
							|  |  |  |         self.assertTrue(P('//a/b/c/d').is_absolute()) | 
					
						
							|  |  |  |         self.assertTrue(P('//?/UNC/').is_absolute()) | 
					
						
							|  |  |  |         self.assertTrue(P('//?/UNC/spam').is_absolute()) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-12-16 19:04:33 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | # | 
					
						
							|  |  |  | # Tests for the virtual classes. | 
					
						
							|  |  |  | # | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class PathBaseTest(PurePathBaseTest): | 
					
						
							| 
									
										
										
										
											2023-12-22 20:59:17 +00:00
										 |  |  |     cls = PathBase | 
					
						
							| 
									
										
										
										
											2023-12-16 19:04:33 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_unsupported_operation(self): | 
					
						
							|  |  |  |         P = self.cls | 
					
						
							| 
									
										
										
										
											2024-01-10 01:12:58 +00:00
										 |  |  |         p = self.cls('') | 
					
						
							| 
									
										
										
										
											2023-12-22 20:59:17 +00:00
										 |  |  |         e = UnsupportedOperation | 
					
						
							| 
									
										
										
										
											2023-12-16 19:04:33 +00:00
										 |  |  |         self.assertRaises(e, p.stat) | 
					
						
							|  |  |  |         self.assertRaises(e, p.lstat) | 
					
						
							|  |  |  |         self.assertRaises(e, p.exists) | 
					
						
							|  |  |  |         self.assertRaises(e, p.samefile, 'foo') | 
					
						
							|  |  |  |         self.assertRaises(e, p.is_dir) | 
					
						
							|  |  |  |         self.assertRaises(e, p.is_file) | 
					
						
							|  |  |  |         self.assertRaises(e, p.is_mount) | 
					
						
							|  |  |  |         self.assertRaises(e, p.is_symlink) | 
					
						
							|  |  |  |         self.assertRaises(e, p.is_block_device) | 
					
						
							|  |  |  |         self.assertRaises(e, p.is_char_device) | 
					
						
							|  |  |  |         self.assertRaises(e, p.is_fifo) | 
					
						
							|  |  |  |         self.assertRaises(e, p.is_socket) | 
					
						
							|  |  |  |         self.assertRaises(e, p.open) | 
					
						
							|  |  |  |         self.assertRaises(e, p.read_bytes) | 
					
						
							|  |  |  |         self.assertRaises(e, p.read_text) | 
					
						
							|  |  |  |         self.assertRaises(e, p.write_bytes, b'foo') | 
					
						
							|  |  |  |         self.assertRaises(e, p.write_text, 'foo') | 
					
						
							|  |  |  |         self.assertRaises(e, p.iterdir) | 
					
						
							|  |  |  |         self.assertRaises(e, p.glob, '*') | 
					
						
							|  |  |  |         self.assertRaises(e, p.rglob, '*') | 
					
						
							|  |  |  |         self.assertRaises(e, lambda: list(p.walk())) | 
					
						
							|  |  |  |         self.assertRaises(e, p.absolute) | 
					
						
							|  |  |  |         self.assertRaises(e, P.cwd) | 
					
						
							|  |  |  |         self.assertRaises(e, p.expanduser) | 
					
						
							|  |  |  |         self.assertRaises(e, p.home) | 
					
						
							|  |  |  |         self.assertRaises(e, p.readlink) | 
					
						
							|  |  |  |         self.assertRaises(e, p.symlink_to, 'foo') | 
					
						
							|  |  |  |         self.assertRaises(e, p.hardlink_to, 'foo') | 
					
						
							|  |  |  |         self.assertRaises(e, p.mkdir) | 
					
						
							|  |  |  |         self.assertRaises(e, p.touch) | 
					
						
							|  |  |  |         self.assertRaises(e, p.rename, 'foo') | 
					
						
							|  |  |  |         self.assertRaises(e, p.replace, 'foo') | 
					
						
							|  |  |  |         self.assertRaises(e, p.chmod, 0o755) | 
					
						
							|  |  |  |         self.assertRaises(e, p.lchmod, 0o755) | 
					
						
							|  |  |  |         self.assertRaises(e, p.unlink) | 
					
						
							|  |  |  |         self.assertRaises(e, p.rmdir) | 
					
						
							|  |  |  |         self.assertRaises(e, p.owner) | 
					
						
							|  |  |  |         self.assertRaises(e, p.group) | 
					
						
							|  |  |  |         self.assertRaises(e, p.as_uri) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_as_uri_common(self): | 
					
						
							| 
									
										
										
										
											2023-12-22 20:59:17 +00:00
										 |  |  |         e = UnsupportedOperation | 
					
						
							| 
									
										
										
										
											2024-01-10 01:12:58 +00:00
										 |  |  |         self.assertRaises(e, self.cls('').as_uri) | 
					
						
							| 
									
										
										
										
											2023-12-16 19:04:33 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_fspath_common(self): | 
					
						
							| 
									
										
										
										
											2024-01-10 01:12:58 +00:00
										 |  |  |         self.assertRaises(TypeError, os.fspath, self.cls('')) | 
					
						
							| 
									
										
										
										
											2023-12-16 19:04:33 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_as_bytes_common(self): | 
					
						
							| 
									
										
										
										
											2024-01-10 01:12:58 +00:00
										 |  |  |         self.assertRaises(TypeError, bytes, self.cls('')) | 
					
						
							| 
									
										
										
										
											2023-12-16 19:04:33 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class DummyPathIO(io.BytesIO): | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  |     Used by DummyPath to implement `open('w')` | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def __init__(self, files, path): | 
					
						
							|  |  |  |         super().__init__() | 
					
						
							|  |  |  |         self.files = files | 
					
						
							|  |  |  |         self.path = path | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def close(self): | 
					
						
							|  |  |  |         self.files[self.path] = self.getvalue() | 
					
						
							|  |  |  |         super().close() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-01-08 19:31:52 +00:00
										 |  |  | DummyPathStatResult = collections.namedtuple( | 
					
						
							|  |  |  |     'DummyPathStatResult', | 
					
						
							|  |  |  |     'st_mode st_ino st_dev st_nlink st_uid st_gid st_size st_atime st_mtime st_ctime') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-12-22 20:59:17 +00:00
										 |  |  | class DummyPath(PathBase): | 
					
						
							| 
									
										
										
										
											2023-12-16 19:04:33 +00:00
										 |  |  |     """
 | 
					
						
							|  |  |  |     Simple implementation of PathBase that keeps files and directories in | 
					
						
							|  |  |  |     memory. | 
					
						
							|  |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2024-01-08 19:31:52 +00:00
										 |  |  |     __slots__ = () | 
					
						
							| 
									
										
										
										
											2024-01-14 21:49:53 +00:00
										 |  |  |     pathmod = posixpath | 
					
						
							| 
									
										
										
										
											2024-01-08 19:31:52 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-12-16 19:04:33 +00:00
										 |  |  |     _files = {} | 
					
						
							|  |  |  |     _directories = {} | 
					
						
							|  |  |  |     _symlinks = {} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def __eq__(self, other): | 
					
						
							|  |  |  |         if not isinstance(other, DummyPath): | 
					
						
							|  |  |  |             return NotImplemented | 
					
						
							|  |  |  |         return str(self) == str(other) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def __hash__(self): | 
					
						
							|  |  |  |         return hash(str(self)) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-01-06 17:02:36 +00:00
										 |  |  |     def __repr__(self): | 
					
						
							|  |  |  |         return "{}({!r})".format(self.__class__.__name__, self.as_posix()) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-12-16 19:04:33 +00:00
										 |  |  |     def stat(self, *, follow_symlinks=True): | 
					
						
							|  |  |  |         if follow_symlinks: | 
					
						
							|  |  |  |             path = str(self.resolve()) | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             path = str(self.parent.resolve() / self.name) | 
					
						
							|  |  |  |         if path in self._files: | 
					
						
							|  |  |  |             st_mode = stat.S_IFREG | 
					
						
							|  |  |  |         elif path in self._directories: | 
					
						
							|  |  |  |             st_mode = stat.S_IFDIR | 
					
						
							|  |  |  |         elif path in self._symlinks: | 
					
						
							|  |  |  |             st_mode = stat.S_IFLNK | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             raise FileNotFoundError(errno.ENOENT, "Not found", str(self)) | 
					
						
							| 
									
										
										
										
											2024-01-08 19:31:52 +00:00
										 |  |  |         return DummyPathStatResult(st_mode, hash(str(self)), 0, 0, 0, 0, 0, 0, 0, 0) | 
					
						
							| 
									
										
										
										
											2023-12-16 19:04:33 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def open(self, mode='r', buffering=-1, encoding=None, | 
					
						
							|  |  |  |              errors=None, newline=None): | 
					
						
							|  |  |  |         if buffering != -1: | 
					
						
							|  |  |  |             raise NotImplementedError | 
					
						
							|  |  |  |         path_obj = self.resolve() | 
					
						
							|  |  |  |         path = str(path_obj) | 
					
						
							|  |  |  |         name = path_obj.name | 
					
						
							|  |  |  |         parent = str(path_obj.parent) | 
					
						
							|  |  |  |         if path in self._directories: | 
					
						
							|  |  |  |             raise IsADirectoryError(errno.EISDIR, "Is a directory", path) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         text = 'b' not in mode | 
					
						
							|  |  |  |         mode = ''.join(c for c in mode if c not in 'btU') | 
					
						
							|  |  |  |         if mode == 'r': | 
					
						
							|  |  |  |             if path not in self._files: | 
					
						
							|  |  |  |                 raise FileNotFoundError(errno.ENOENT, "File not found", path) | 
					
						
							|  |  |  |             stream = io.BytesIO(self._files[path]) | 
					
						
							|  |  |  |         elif mode == 'w': | 
					
						
							|  |  |  |             if parent not in self._directories: | 
					
						
							|  |  |  |                 raise FileNotFoundError(errno.ENOENT, "File not found", parent) | 
					
						
							|  |  |  |             stream = DummyPathIO(self._files, path) | 
					
						
							|  |  |  |             self._files[path] = b'' | 
					
						
							|  |  |  |             self._directories[parent].add(name) | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             raise NotImplementedError | 
					
						
							|  |  |  |         if text: | 
					
						
							|  |  |  |             stream = io.TextIOWrapper(stream, encoding=encoding, errors=errors, newline=newline) | 
					
						
							|  |  |  |         return stream | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def iterdir(self): | 
					
						
							|  |  |  |         path = str(self.resolve()) | 
					
						
							|  |  |  |         if path in self._files: | 
					
						
							|  |  |  |             raise NotADirectoryError(errno.ENOTDIR, "Not a directory", path) | 
					
						
							|  |  |  |         elif path in self._directories: | 
					
						
							|  |  |  |             return (self / name for name in self._directories[path]) | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             raise FileNotFoundError(errno.ENOENT, "File not found", path) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def mkdir(self, mode=0o777, parents=False, exist_ok=False): | 
					
						
							|  |  |  |         path = str(self.resolve()) | 
					
						
							|  |  |  |         if path in self._directories: | 
					
						
							|  |  |  |             if exist_ok: | 
					
						
							|  |  |  |                 return | 
					
						
							|  |  |  |             else: | 
					
						
							|  |  |  |                 raise FileExistsError(errno.EEXIST, "File exists", path) | 
					
						
							|  |  |  |         try: | 
					
						
							|  |  |  |             if self.name: | 
					
						
							|  |  |  |                 self._directories[str(self.parent)].add(self.name) | 
					
						
							|  |  |  |             self._directories[path] = set() | 
					
						
							|  |  |  |         except KeyError: | 
					
						
							|  |  |  |             if not parents: | 
					
						
							|  |  |  |                 raise FileNotFoundError(errno.ENOENT, "File not found", str(self.parent)) from None | 
					
						
							|  |  |  |             self.parent.mkdir(parents=True, exist_ok=True) | 
					
						
							|  |  |  |             self.mkdir(mode, parents=False, exist_ok=exist_ok) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class DummyPathTest(DummyPurePathTest): | 
					
						
							|  |  |  |     """Tests for PathBase methods that use stat(), open() and iterdir().""" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     cls = DummyPath | 
					
						
							|  |  |  |     can_symlink = False | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-12-17 00:07:32 +00:00
										 |  |  |     # (self.base) | 
					
						
							| 
									
										
										
										
											2023-12-16 19:04:33 +00:00
										 |  |  |     #  | | 
					
						
							|  |  |  |     #  |-- brokenLink -> non-existing | 
					
						
							|  |  |  |     #  |-- dirA | 
					
						
							|  |  |  |     #  |   `-- linkC -> ../dirB | 
					
						
							|  |  |  |     #  |-- dirB | 
					
						
							|  |  |  |     #  |   |-- fileB | 
					
						
							|  |  |  |     #  |   `-- linkD -> ../dirB | 
					
						
							|  |  |  |     #  |-- dirC | 
					
						
							|  |  |  |     #  |   |-- dirD | 
					
						
							|  |  |  |     #  |   |   `-- fileD | 
					
						
							|  |  |  |     #  |   `-- fileC | 
					
						
							|  |  |  |     #  |   `-- novel.txt | 
					
						
							|  |  |  |     #  |-- dirE  # No permissions | 
					
						
							|  |  |  |     #  |-- fileA | 
					
						
							|  |  |  |     #  |-- linkA -> fileA | 
					
						
							|  |  |  |     #  |-- linkB -> dirB | 
					
						
							|  |  |  |     #  `-- brokenLinkLoop -> brokenLinkLoop | 
					
						
							|  |  |  |     # | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def setUp(self): | 
					
						
							|  |  |  |         super().setUp() | 
					
						
							| 
									
										
										
										
											2024-01-26 22:29:28 +00:00
										 |  |  |         name = self.id().split('.')[-1] | 
					
						
							|  |  |  |         if name in _tests_needing_symlinks and not self.can_symlink: | 
					
						
							|  |  |  |             self.skipTest('requires symlinks') | 
					
						
							| 
									
										
										
										
											2023-12-16 19:04:33 +00:00
										 |  |  |         pathmod = self.cls.pathmod | 
					
						
							| 
									
										
										
										
											2023-12-17 00:07:32 +00:00
										 |  |  |         p = self.cls(self.base) | 
					
						
							| 
									
										
										
										
											2023-12-16 19:04:33 +00:00
										 |  |  |         p.mkdir(parents=True) | 
					
						
							|  |  |  |         p.joinpath('dirA').mkdir() | 
					
						
							|  |  |  |         p.joinpath('dirB').mkdir() | 
					
						
							|  |  |  |         p.joinpath('dirC').mkdir() | 
					
						
							|  |  |  |         p.joinpath('dirC', 'dirD').mkdir() | 
					
						
							|  |  |  |         p.joinpath('dirE').mkdir() | 
					
						
							|  |  |  |         with p.joinpath('fileA').open('wb') as f: | 
					
						
							|  |  |  |             f.write(b"this is file A\n") | 
					
						
							|  |  |  |         with p.joinpath('dirB', 'fileB').open('wb') as f: | 
					
						
							|  |  |  |             f.write(b"this is file B\n") | 
					
						
							|  |  |  |         with p.joinpath('dirC', 'fileC').open('wb') as f: | 
					
						
							|  |  |  |             f.write(b"this is file C\n") | 
					
						
							|  |  |  |         with p.joinpath('dirC', 'novel.txt').open('wb') as f: | 
					
						
							|  |  |  |             f.write(b"this is a novel\n") | 
					
						
							|  |  |  |         with p.joinpath('dirC', 'dirD', 'fileD').open('wb') as f: | 
					
						
							|  |  |  |             f.write(b"this is file D\n") | 
					
						
							|  |  |  |         if self.can_symlink: | 
					
						
							|  |  |  |             p.joinpath('linkA').symlink_to('fileA') | 
					
						
							|  |  |  |             p.joinpath('brokenLink').symlink_to('non-existing') | 
					
						
							|  |  |  |             p.joinpath('linkB').symlink_to('dirB') | 
					
						
							|  |  |  |             p.joinpath('dirA', 'linkC').symlink_to(pathmod.join('..', 'dirB')) | 
					
						
							|  |  |  |             p.joinpath('dirB', 'linkD').symlink_to(pathmod.join('..', 'dirB')) | 
					
						
							|  |  |  |             p.joinpath('brokenLinkLoop').symlink_to('brokenLinkLoop') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def tearDown(self): | 
					
						
							|  |  |  |         cls = self.cls | 
					
						
							|  |  |  |         cls._files.clear() | 
					
						
							|  |  |  |         cls._directories.clear() | 
					
						
							|  |  |  |         cls._symlinks.clear() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def tempdir(self): | 
					
						
							| 
									
										
										
										
											2023-12-17 00:07:32 +00:00
										 |  |  |         path = self.cls(self.base).with_name('tmp-dirD') | 
					
						
							| 
									
										
										
										
											2023-12-16 19:04:33 +00:00
										 |  |  |         path.mkdir() | 
					
						
							|  |  |  |         return path | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def assertFileNotFound(self, func, *args, **kwargs): | 
					
						
							|  |  |  |         with self.assertRaises(FileNotFoundError) as cm: | 
					
						
							|  |  |  |             func(*args, **kwargs) | 
					
						
							|  |  |  |         self.assertEqual(cm.exception.errno, errno.ENOENT) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def assertEqualNormCase(self, path_a, path_b): | 
					
						
							| 
									
										
										
										
											2023-12-22 18:09:50 +00:00
										 |  |  |         normcase = self.pathmod.normcase | 
					
						
							|  |  |  |         self.assertEqual(normcase(path_a), normcase(path_b)) | 
					
						
							| 
									
										
										
										
											2023-12-16 19:04:33 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_samefile(self): | 
					
						
							| 
									
										
										
										
											2023-12-22 18:09:50 +00:00
										 |  |  |         pathmod = self.pathmod | 
					
						
							|  |  |  |         fileA_path = pathmod.join(self.base, 'fileA') | 
					
						
							|  |  |  |         fileB_path = pathmod.join(self.base, 'dirB', 'fileB') | 
					
						
							| 
									
										
										
										
											2023-12-16 19:04:33 +00:00
										 |  |  |         p = self.cls(fileA_path) | 
					
						
							|  |  |  |         pp = self.cls(fileA_path) | 
					
						
							|  |  |  |         q = self.cls(fileB_path) | 
					
						
							|  |  |  |         self.assertTrue(p.samefile(fileA_path)) | 
					
						
							|  |  |  |         self.assertTrue(p.samefile(pp)) | 
					
						
							|  |  |  |         self.assertFalse(p.samefile(fileB_path)) | 
					
						
							|  |  |  |         self.assertFalse(p.samefile(q)) | 
					
						
							|  |  |  |         # Test the non-existent file case | 
					
						
							| 
									
										
										
										
											2023-12-22 18:09:50 +00:00
										 |  |  |         non_existent = pathmod.join(self.base, 'foo') | 
					
						
							| 
									
										
										
										
											2023-12-16 19:04:33 +00:00
										 |  |  |         r = self.cls(non_existent) | 
					
						
							|  |  |  |         self.assertRaises(FileNotFoundError, p.samefile, r) | 
					
						
							|  |  |  |         self.assertRaises(FileNotFoundError, p.samefile, non_existent) | 
					
						
							|  |  |  |         self.assertRaises(FileNotFoundError, r.samefile, p) | 
					
						
							|  |  |  |         self.assertRaises(FileNotFoundError, r.samefile, non_existent) | 
					
						
							|  |  |  |         self.assertRaises(FileNotFoundError, r.samefile, r) | 
					
						
							|  |  |  |         self.assertRaises(FileNotFoundError, r.samefile, non_existent) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_exists(self): | 
					
						
							|  |  |  |         P = self.cls | 
					
						
							| 
									
										
										
										
											2023-12-17 00:07:32 +00:00
										 |  |  |         p = P(self.base) | 
					
						
							| 
									
										
										
										
											2023-12-16 19:04:33 +00:00
										 |  |  |         self.assertIs(True, p.exists()) | 
					
						
							|  |  |  |         self.assertIs(True, (p / 'dirA').exists()) | 
					
						
							|  |  |  |         self.assertIs(True, (p / 'fileA').exists()) | 
					
						
							|  |  |  |         self.assertIs(False, (p / 'fileA' / 'bah').exists()) | 
					
						
							|  |  |  |         if self.can_symlink: | 
					
						
							|  |  |  |             self.assertIs(True, (p / 'linkA').exists()) | 
					
						
							|  |  |  |             self.assertIs(True, (p / 'linkB').exists()) | 
					
						
							|  |  |  |             self.assertIs(True, (p / 'linkB' / 'fileB').exists()) | 
					
						
							|  |  |  |             self.assertIs(False, (p / 'linkA' / 'bah').exists()) | 
					
						
							|  |  |  |             self.assertIs(False, (p / 'brokenLink').exists()) | 
					
						
							|  |  |  |             self.assertIs(True, (p / 'brokenLink').exists(follow_symlinks=False)) | 
					
						
							|  |  |  |         self.assertIs(False, (p / 'foo').exists()) | 
					
						
							|  |  |  |         self.assertIs(False, P('/xyzzy').exists()) | 
					
						
							| 
									
										
										
										
											2023-12-17 00:07:32 +00:00
										 |  |  |         self.assertIs(False, P(self.base + '\udfff').exists()) | 
					
						
							|  |  |  |         self.assertIs(False, P(self.base + '\x00').exists()) | 
					
						
							| 
									
										
										
										
											2023-12-16 19:04:33 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_open_common(self): | 
					
						
							| 
									
										
										
										
											2023-12-17 00:07:32 +00:00
										 |  |  |         p = self.cls(self.base) | 
					
						
							| 
									
										
										
										
											2023-12-16 19:04:33 +00:00
										 |  |  |         with (p / 'fileA').open('r') as f: | 
					
						
							|  |  |  |             self.assertIsInstance(f, io.TextIOBase) | 
					
						
							|  |  |  |             self.assertEqual(f.read(), "this is file A\n") | 
					
						
							|  |  |  |         with (p / 'fileA').open('rb') as f: | 
					
						
							|  |  |  |             self.assertIsInstance(f, io.BufferedIOBase) | 
					
						
							|  |  |  |             self.assertEqual(f.read().strip(), b"this is file A") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_read_write_bytes(self): | 
					
						
							| 
									
										
										
										
											2023-12-17 00:07:32 +00:00
										 |  |  |         p = self.cls(self.base) | 
					
						
							| 
									
										
										
										
											2023-12-16 19:04:33 +00:00
										 |  |  |         (p / 'fileA').write_bytes(b'abcdefg') | 
					
						
							|  |  |  |         self.assertEqual((p / 'fileA').read_bytes(), b'abcdefg') | 
					
						
							|  |  |  |         # Check that trying to write str does not truncate the file. | 
					
						
							|  |  |  |         self.assertRaises(TypeError, (p / 'fileA').write_bytes, 'somestr') | 
					
						
							|  |  |  |         self.assertEqual((p / 'fileA').read_bytes(), b'abcdefg') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_read_write_text(self): | 
					
						
							| 
									
										
										
										
											2023-12-17 00:07:32 +00:00
										 |  |  |         p = self.cls(self.base) | 
					
						
							| 
									
										
										
										
											2023-12-16 19:04:33 +00:00
										 |  |  |         (p / 'fileA').write_text('äbcdefg', encoding='latin-1') | 
					
						
							|  |  |  |         self.assertEqual((p / 'fileA').read_text( | 
					
						
							|  |  |  |             encoding='utf-8', errors='ignore'), 'bcdefg') | 
					
						
							|  |  |  |         # Check that trying to write bytes does not truncate the file. | 
					
						
							|  |  |  |         self.assertRaises(TypeError, (p / 'fileA').write_text, b'somebytes') | 
					
						
							|  |  |  |         self.assertEqual((p / 'fileA').read_text(encoding='latin-1'), 'äbcdefg') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_read_text_with_newlines(self): | 
					
						
							| 
									
										
										
										
											2023-12-17 00:07:32 +00:00
										 |  |  |         p = self.cls(self.base) | 
					
						
							| 
									
										
										
										
											2023-12-16 19:04:33 +00:00
										 |  |  |         # Check that `\n` character change nothing | 
					
						
							|  |  |  |         (p / 'fileA').write_bytes(b'abcde\r\nfghlk\n\rmnopq') | 
					
						
							|  |  |  |         self.assertEqual((p / 'fileA').read_text(newline='\n'), | 
					
						
							|  |  |  |                          'abcde\r\nfghlk\n\rmnopq') | 
					
						
							|  |  |  |         # Check that `\r` character replaces `\n` | 
					
						
							|  |  |  |         (p / 'fileA').write_bytes(b'abcde\r\nfghlk\n\rmnopq') | 
					
						
							|  |  |  |         self.assertEqual((p / 'fileA').read_text(newline='\r'), | 
					
						
							|  |  |  |                          'abcde\r\nfghlk\n\rmnopq') | 
					
						
							|  |  |  |         # Check that `\r\n` character replaces `\n` | 
					
						
							|  |  |  |         (p / 'fileA').write_bytes(b'abcde\r\nfghlk\n\rmnopq') | 
					
						
							|  |  |  |         self.assertEqual((p / 'fileA').read_text(newline='\r\n'), | 
					
						
							|  |  |  |                              'abcde\r\nfghlk\n\rmnopq') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_write_text_with_newlines(self): | 
					
						
							| 
									
										
										
										
											2023-12-17 00:07:32 +00:00
										 |  |  |         p = self.cls(self.base) | 
					
						
							| 
									
										
										
										
											2023-12-16 19:04:33 +00:00
										 |  |  |         # Check that `\n` character change nothing | 
					
						
							|  |  |  |         (p / 'fileA').write_text('abcde\r\nfghlk\n\rmnopq', newline='\n') | 
					
						
							|  |  |  |         self.assertEqual((p / 'fileA').read_bytes(), | 
					
						
							|  |  |  |                          b'abcde\r\nfghlk\n\rmnopq') | 
					
						
							|  |  |  |         # Check that `\r` character replaces `\n` | 
					
						
							|  |  |  |         (p / 'fileA').write_text('abcde\r\nfghlk\n\rmnopq', newline='\r') | 
					
						
							|  |  |  |         self.assertEqual((p / 'fileA').read_bytes(), | 
					
						
							|  |  |  |                          b'abcde\r\rfghlk\r\rmnopq') | 
					
						
							|  |  |  |         # Check that `\r\n` character replaces `\n` | 
					
						
							|  |  |  |         (p / 'fileA').write_text('abcde\r\nfghlk\n\rmnopq', newline='\r\n') | 
					
						
							|  |  |  |         self.assertEqual((p / 'fileA').read_bytes(), | 
					
						
							|  |  |  |                          b'abcde\r\r\nfghlk\r\n\rmnopq') | 
					
						
							|  |  |  |         # Check that no argument passed will change `\n` to `os.linesep` | 
					
						
							|  |  |  |         os_linesep_byte = bytes(os.linesep, encoding='ascii') | 
					
						
							|  |  |  |         (p / 'fileA').write_text('abcde\nfghlk\n\rmnopq') | 
					
						
							|  |  |  |         self.assertEqual((p / 'fileA').read_bytes(), | 
					
						
							|  |  |  |                           b'abcde' + os_linesep_byte + b'fghlk' + os_linesep_byte + b'\rmnopq') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_iterdir(self): | 
					
						
							|  |  |  |         P = self.cls | 
					
						
							| 
									
										
										
										
											2023-12-17 00:07:32 +00:00
										 |  |  |         p = P(self.base) | 
					
						
							| 
									
										
										
										
											2023-12-16 19:04:33 +00:00
										 |  |  |         it = p.iterdir() | 
					
						
							|  |  |  |         paths = set(it) | 
					
						
							|  |  |  |         expected = ['dirA', 'dirB', 'dirC', 'dirE', 'fileA'] | 
					
						
							|  |  |  |         if self.can_symlink: | 
					
						
							|  |  |  |             expected += ['linkA', 'linkB', 'brokenLink', 'brokenLinkLoop'] | 
					
						
							| 
									
										
										
										
											2023-12-17 00:07:32 +00:00
										 |  |  |         self.assertEqual(paths, { P(self.base, q) for q in expected }) | 
					
						
							| 
									
										
										
										
											2023-12-16 19:04:33 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-01-26 22:29:28 +00:00
										 |  |  |     @needs_symlinks | 
					
						
							| 
									
										
										
										
											2023-12-16 19:04:33 +00:00
										 |  |  |     def test_iterdir_symlink(self): | 
					
						
							|  |  |  |         # __iter__ on a symlink to a directory. | 
					
						
							|  |  |  |         P = self.cls | 
					
						
							| 
									
										
										
										
											2023-12-17 00:07:32 +00:00
										 |  |  |         p = P(self.base, 'linkB') | 
					
						
							| 
									
										
										
										
											2023-12-16 19:04:33 +00:00
										 |  |  |         paths = set(p.iterdir()) | 
					
						
							| 
									
										
										
										
											2023-12-17 00:07:32 +00:00
										 |  |  |         expected = { P(self.base, 'linkB', q) for q in ['fileB', 'linkD'] } | 
					
						
							| 
									
										
										
										
											2023-12-16 19:04:33 +00:00
										 |  |  |         self.assertEqual(paths, expected) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_iterdir_nodir(self): | 
					
						
							|  |  |  |         # __iter__ on something that is not a directory. | 
					
						
							| 
									
										
										
										
											2023-12-17 00:07:32 +00:00
										 |  |  |         p = self.cls(self.base, 'fileA') | 
					
						
							| 
									
										
										
										
											2023-12-16 19:04:33 +00:00
										 |  |  |         with self.assertRaises(OSError) as cm: | 
					
						
							|  |  |  |             p.iterdir() | 
					
						
							|  |  |  |         # ENOENT or EINVAL under Windows, ENOTDIR otherwise | 
					
						
							|  |  |  |         # (see issue #12802). | 
					
						
							|  |  |  |         self.assertIn(cm.exception.errno, (errno.ENOTDIR, | 
					
						
							|  |  |  |                                            errno.ENOENT, errno.EINVAL)) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_glob_common(self): | 
					
						
							|  |  |  |         def _check(glob, expected): | 
					
						
							| 
									
										
										
										
											2023-12-17 00:07:32 +00:00
										 |  |  |             self.assertEqual(set(glob), { P(self.base, q) for q in expected }) | 
					
						
							| 
									
										
										
										
											2023-12-16 19:04:33 +00:00
										 |  |  |         P = self.cls | 
					
						
							| 
									
										
										
										
											2023-12-17 00:07:32 +00:00
										 |  |  |         p = P(self.base) | 
					
						
							| 
									
										
										
										
											2023-12-16 19:04:33 +00:00
										 |  |  |         it = p.glob("fileA") | 
					
						
							|  |  |  |         self.assertIsInstance(it, collections.abc.Iterator) | 
					
						
							|  |  |  |         _check(it, ["fileA"]) | 
					
						
							|  |  |  |         _check(p.glob("fileB"), []) | 
					
						
							|  |  |  |         _check(p.glob("dir*/file*"), ["dirB/fileB", "dirC/fileC"]) | 
					
						
							|  |  |  |         if not self.can_symlink: | 
					
						
							|  |  |  |             _check(p.glob("*A"), ['dirA', 'fileA']) | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             _check(p.glob("*A"), ['dirA', 'fileA', 'linkA']) | 
					
						
							|  |  |  |         if not self.can_symlink: | 
					
						
							|  |  |  |             _check(p.glob("*B/*"), ['dirB/fileB']) | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             _check(p.glob("*B/*"), ['dirB/fileB', 'dirB/linkD', | 
					
						
							|  |  |  |                                     'linkB/fileB', 'linkB/linkD']) | 
					
						
							|  |  |  |         if not self.can_symlink: | 
					
						
							|  |  |  |             _check(p.glob("*/fileB"), ['dirB/fileB']) | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             _check(p.glob("*/fileB"), ['dirB/fileB', 'linkB/fileB']) | 
					
						
							|  |  |  |         if self.can_symlink: | 
					
						
							|  |  |  |             _check(p.glob("brokenLink"), ['brokenLink']) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if not self.can_symlink: | 
					
						
							|  |  |  |             _check(p.glob("*/"), ["dirA/", "dirB/", "dirC/", "dirE/"]) | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             _check(p.glob("*/"), ["dirA/", "dirB/", "dirC/", "dirE/", "linkB/"]) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-01-27 02:16:17 +00:00
										 |  |  |     @needs_posix | 
					
						
							|  |  |  |     def test_glob_posix(self): | 
					
						
							|  |  |  |         P = self.cls | 
					
						
							|  |  |  |         p = P(self.base) | 
					
						
							|  |  |  |         given = set(p.glob("FILEa")) | 
					
						
							|  |  |  |         expect = set() | 
					
						
							|  |  |  |         self.assertEqual(given, expect) | 
					
						
							|  |  |  |         self.assertEqual(set(p.glob("FILEa*")), set()) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     @needs_windows | 
					
						
							|  |  |  |     def test_glob_windows(self): | 
					
						
							|  |  |  |         P = self.cls | 
					
						
							|  |  |  |         p = P(self.base) | 
					
						
							|  |  |  |         self.assertEqual(set(p.glob("FILEa")), { P(self.base, "fileA") }) | 
					
						
							|  |  |  |         self.assertEqual(set(p.glob("*a\\")), { P(self.base, "dirA/") }) | 
					
						
							|  |  |  |         self.assertEqual(set(p.glob("F*a")), { P(self.base, "fileA") }) | 
					
						
							|  |  |  |         self.assertEqual(set(map(str, p.glob("FILEa"))), {f"{p}\\fileA"}) | 
					
						
							|  |  |  |         self.assertEqual(set(map(str, p.glob("F*a"))), {f"{p}\\fileA"}) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-12-16 19:04:33 +00:00
										 |  |  |     def test_glob_empty_pattern(self): | 
					
						
							| 
									
										
										
										
											2024-01-20 02:10:25 +00:00
										 |  |  |         P = self.cls | 
					
						
							|  |  |  |         p = P(self.base) | 
					
						
							| 
									
										
										
										
											2024-01-27 19:59:51 +00:00
										 |  |  |         self.assertEqual(list(p.glob("")), [p]) | 
					
						
							|  |  |  |         self.assertEqual(list(p.glob(".")), [p / "."]) | 
					
						
							|  |  |  |         self.assertEqual(list(p.glob("./")), [p / "./"]) | 
					
						
							| 
									
										
										
										
											2023-12-16 19:04:33 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_glob_case_sensitive(self): | 
					
						
							|  |  |  |         P = self.cls | 
					
						
							|  |  |  |         def _check(path, pattern, case_sensitive, expected): | 
					
						
							|  |  |  |             actual = {str(q) for q in path.glob(pattern, case_sensitive=case_sensitive)} | 
					
						
							| 
									
										
										
										
											2023-12-17 00:07:32 +00:00
										 |  |  |             expected = {str(P(self.base, q)) for q in expected} | 
					
						
							| 
									
										
										
										
											2023-12-16 19:04:33 +00:00
										 |  |  |             self.assertEqual(actual, expected) | 
					
						
							| 
									
										
										
										
											2023-12-17 00:07:32 +00:00
										 |  |  |         path = P(self.base) | 
					
						
							| 
									
										
										
										
											2023-12-16 19:04:33 +00:00
										 |  |  |         _check(path, "DIRB/FILE*", True, []) | 
					
						
							|  |  |  |         _check(path, "DIRB/FILE*", False, ["dirB/fileB"]) | 
					
						
							|  |  |  |         _check(path, "dirb/file*", True, []) | 
					
						
							|  |  |  |         _check(path, "dirb/file*", False, ["dirB/fileB"]) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-01-26 22:29:28 +00:00
										 |  |  |     @needs_symlinks | 
					
						
							| 
									
										
										
										
											2023-12-16 19:04:33 +00:00
										 |  |  |     def test_glob_follow_symlinks_common(self): | 
					
						
							|  |  |  |         def _check(path, glob, expected): | 
					
						
							|  |  |  |             actual = {path for path in path.glob(glob, follow_symlinks=True) | 
					
						
							| 
									
										
										
										
											2024-01-06 17:03:39 +00:00
										 |  |  |                       if path.parts.count("linkD") <= 1}  # exclude symlink loop. | 
					
						
							| 
									
										
										
										
											2023-12-17 00:07:32 +00:00
										 |  |  |             self.assertEqual(actual, { P(self.base, q) for q in expected }) | 
					
						
							| 
									
										
										
										
											2023-12-16 19:04:33 +00:00
										 |  |  |         P = self.cls | 
					
						
							| 
									
										
										
										
											2023-12-17 00:07:32 +00:00
										 |  |  |         p = P(self.base) | 
					
						
							| 
									
										
										
										
											2023-12-16 19:04:33 +00:00
										 |  |  |         _check(p, "fileB", []) | 
					
						
							|  |  |  |         _check(p, "dir*/file*", ["dirB/fileB", "dirC/fileC"]) | 
					
						
							|  |  |  |         _check(p, "*A", ["dirA", "fileA", "linkA"]) | 
					
						
							|  |  |  |         _check(p, "*B/*", ["dirB/fileB", "dirB/linkD", "linkB/fileB", "linkB/linkD"]) | 
					
						
							|  |  |  |         _check(p, "*/fileB", ["dirB/fileB", "linkB/fileB"]) | 
					
						
							|  |  |  |         _check(p, "*/", ["dirA/", "dirB/", "dirC/", "dirE/", "linkB/"]) | 
					
						
							| 
									
										
										
										
											2024-01-06 17:03:39 +00:00
										 |  |  |         _check(p, "dir*/*/..", ["dirC/dirD/..", "dirA/linkC/..", "dirB/linkD/.."]) | 
					
						
							| 
									
										
										
										
											2024-01-30 19:52:53 +00:00
										 |  |  |         _check(p, "dir*/**", [ | 
					
						
							| 
									
										
										
										
											2024-02-06 02:48:18 +00:00
										 |  |  |             "dirA/", "dirA/linkC", "dirA/linkC/fileB", "dirA/linkC/linkD", "dirA/linkC/linkD/fileB", | 
					
						
							|  |  |  |             "dirB/", "dirB/fileB", "dirB/linkD", "dirB/linkD/fileB", | 
					
						
							|  |  |  |             "dirC/", "dirC/fileC", "dirC/dirD",  "dirC/dirD/fileD", "dirC/novel.txt", | 
					
						
							|  |  |  |             "dirE/"]) | 
					
						
							| 
									
										
										
										
											2023-12-16 19:04:33 +00:00
										 |  |  |         _check(p, "dir*/**/", ["dirA/", "dirA/linkC/", "dirA/linkC/linkD/", "dirB/", "dirB/linkD/", | 
					
						
							|  |  |  |                                "dirC/", "dirC/dirD/", "dirE/"]) | 
					
						
							|  |  |  |         _check(p, "dir*/**/..", ["dirA/..", "dirA/linkC/..", "dirB/..", | 
					
						
							| 
									
										
										
										
											2024-01-06 17:03:39 +00:00
										 |  |  |                                  "dirB/linkD/..", "dirA/linkC/linkD/..", | 
					
						
							| 
									
										
										
										
											2023-12-16 19:04:33 +00:00
										 |  |  |                                  "dirC/..", "dirC/dirD/..", "dirE/.."]) | 
					
						
							| 
									
										
										
										
											2024-01-30 19:52:53 +00:00
										 |  |  |         _check(p, "dir*/*/**", [ | 
					
						
							| 
									
										
										
										
											2024-02-06 02:48:18 +00:00
										 |  |  |             "dirA/linkC/", "dirA/linkC/linkD", "dirA/linkC/fileB", "dirA/linkC/linkD/fileB", | 
					
						
							|  |  |  |             "dirB/linkD/", "dirB/linkD/fileB", | 
					
						
							|  |  |  |             "dirC/dirD/", "dirC/dirD/fileD"]) | 
					
						
							| 
									
										
										
										
											2023-12-16 19:04:33 +00:00
										 |  |  |         _check(p, "dir*/*/**/", ["dirA/linkC/", "dirA/linkC/linkD/", "dirB/linkD/", "dirC/dirD/"]) | 
					
						
							| 
									
										
										
										
											2024-01-06 17:03:39 +00:00
										 |  |  |         _check(p, "dir*/*/**/..", ["dirA/linkC/..", "dirA/linkC/linkD/..", | 
					
						
							|  |  |  |                                    "dirB/linkD/..", "dirC/dirD/.."]) | 
					
						
							| 
									
										
										
										
											2023-12-16 19:04:33 +00:00
										 |  |  |         _check(p, "dir*/**/fileC", ["dirC/fileC"]) | 
					
						
							|  |  |  |         _check(p, "dir*/*/../dirD/**/", ["dirC/dirD/../dirD/"]) | 
					
						
							| 
									
										
										
										
											2024-02-06 02:48:18 +00:00
										 |  |  |         _check(p, "*/dirD/**", ["dirC/dirD/", "dirC/dirD/fileD"]) | 
					
						
							| 
									
										
										
										
											2023-12-16 19:04:33 +00:00
										 |  |  |         _check(p, "*/dirD/**/", ["dirC/dirD/"]) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-01-26 22:29:28 +00:00
										 |  |  |     @needs_symlinks | 
					
						
							| 
									
										
										
										
											2023-12-16 19:04:33 +00:00
										 |  |  |     def test_glob_no_follow_symlinks_common(self): | 
					
						
							|  |  |  |         def _check(path, glob, expected): | 
					
						
							|  |  |  |             actual = {path for path in path.glob(glob, follow_symlinks=False)} | 
					
						
							| 
									
										
										
										
											2023-12-17 00:07:32 +00:00
										 |  |  |             self.assertEqual(actual, { P(self.base, q) for q in expected }) | 
					
						
							| 
									
										
										
										
											2023-12-16 19:04:33 +00:00
										 |  |  |         P = self.cls | 
					
						
							| 
									
										
										
										
											2023-12-17 00:07:32 +00:00
										 |  |  |         p = P(self.base) | 
					
						
							| 
									
										
										
										
											2023-12-16 19:04:33 +00:00
										 |  |  |         _check(p, "fileB", []) | 
					
						
							|  |  |  |         _check(p, "dir*/file*", ["dirB/fileB", "dirC/fileC"]) | 
					
						
							|  |  |  |         _check(p, "*A", ["dirA", "fileA", "linkA"]) | 
					
						
							|  |  |  |         _check(p, "*B/*", ["dirB/fileB", "dirB/linkD"]) | 
					
						
							|  |  |  |         _check(p, "*/fileB", ["dirB/fileB"]) | 
					
						
							|  |  |  |         _check(p, "*/", ["dirA/", "dirB/", "dirC/", "dirE/"]) | 
					
						
							|  |  |  |         _check(p, "dir*/*/..", ["dirC/dirD/.."]) | 
					
						
							| 
									
										
										
										
											2024-01-30 19:52:53 +00:00
										 |  |  |         _check(p, "dir*/**", [ | 
					
						
							| 
									
										
										
										
											2024-02-06 02:48:18 +00:00
										 |  |  |             "dirA/", "dirA/linkC", | 
					
						
							|  |  |  |             "dirB/", "dirB/fileB", "dirB/linkD", | 
					
						
							|  |  |  |             "dirC/", "dirC/fileC", "dirC/dirD", "dirC/dirD/fileD", "dirC/novel.txt", | 
					
						
							|  |  |  |             "dirE/"]) | 
					
						
							| 
									
										
										
										
											2023-12-16 19:04:33 +00:00
										 |  |  |         _check(p, "dir*/**/", ["dirA/", "dirB/", "dirC/", "dirC/dirD/", "dirE/"]) | 
					
						
							|  |  |  |         _check(p, "dir*/**/..", ["dirA/..", "dirB/..", "dirC/..", "dirC/dirD/..", "dirE/.."]) | 
					
						
							| 
									
										
										
										
											2024-02-06 02:48:18 +00:00
										 |  |  |         _check(p, "dir*/*/**", ["dirC/dirD/", "dirC/dirD/fileD"]) | 
					
						
							| 
									
										
										
										
											2023-12-16 19:04:33 +00:00
										 |  |  |         _check(p, "dir*/*/**/", ["dirC/dirD/"]) | 
					
						
							|  |  |  |         _check(p, "dir*/*/**/..", ["dirC/dirD/.."]) | 
					
						
							|  |  |  |         _check(p, "dir*/**/fileC", ["dirC/fileC"]) | 
					
						
							| 
									
										
										
										
											2024-02-06 02:48:18 +00:00
										 |  |  |         _check(p, "dir*/*/../dirD/**", ["dirC/dirD/../dirD/", "dirC/dirD/../dirD/fileD"]) | 
					
						
							| 
									
										
										
										
											2023-12-16 19:04:33 +00:00
										 |  |  |         _check(p, "dir*/*/../dirD/**/", ["dirC/dirD/../dirD/"]) | 
					
						
							| 
									
										
										
										
											2024-02-06 02:48:18 +00:00
										 |  |  |         _check(p, "*/dirD/**", ["dirC/dirD/", "dirC/dirD/fileD"]) | 
					
						
							| 
									
										
										
										
											2023-12-16 19:04:33 +00:00
										 |  |  |         _check(p, "*/dirD/**/", ["dirC/dirD/"]) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_rglob_common(self): | 
					
						
							|  |  |  |         def _check(glob, expected): | 
					
						
							| 
									
										
										
										
											2023-12-17 00:07:32 +00:00
										 |  |  |             self.assertEqual(set(glob), {P(self.base, q) for q in expected}) | 
					
						
							| 
									
										
										
										
											2023-12-16 19:04:33 +00:00
										 |  |  |         P = self.cls | 
					
						
							| 
									
										
										
										
											2023-12-17 00:07:32 +00:00
										 |  |  |         p = P(self.base) | 
					
						
							| 
									
										
										
										
											2023-12-16 19:04:33 +00:00
										 |  |  |         it = p.rglob("fileA") | 
					
						
							|  |  |  |         self.assertIsInstance(it, collections.abc.Iterator) | 
					
						
							|  |  |  |         _check(it, ["fileA"]) | 
					
						
							|  |  |  |         _check(p.rglob("fileB"), ["dirB/fileB"]) | 
					
						
							|  |  |  |         _check(p.rglob("**/fileB"), ["dirB/fileB"]) | 
					
						
							|  |  |  |         _check(p.rglob("*/fileA"), []) | 
					
						
							|  |  |  |         if not self.can_symlink: | 
					
						
							|  |  |  |             _check(p.rglob("*/fileB"), ["dirB/fileB"]) | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             _check(p.rglob("*/fileB"), ["dirB/fileB", "dirB/linkD/fileB", | 
					
						
							|  |  |  |                                         "linkB/fileB", "dirA/linkC/fileB"]) | 
					
						
							|  |  |  |         _check(p.rglob("file*"), ["fileA", "dirB/fileB", | 
					
						
							|  |  |  |                                   "dirC/fileC", "dirC/dirD/fileD"]) | 
					
						
							|  |  |  |         if not self.can_symlink: | 
					
						
							|  |  |  |             _check(p.rglob("*/"), [ | 
					
						
							|  |  |  |                 "dirA/", "dirB/", "dirC/", "dirC/dirD/", "dirE/", | 
					
						
							|  |  |  |             ]) | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             _check(p.rglob("*/"), [ | 
					
						
							|  |  |  |                 "dirA/", "dirA/linkC/", "dirB/", "dirB/linkD/", "dirC/", | 
					
						
							|  |  |  |                 "dirC/dirD/", "dirE/", "linkB/", | 
					
						
							|  |  |  |             ]) | 
					
						
							| 
									
										
										
										
											2024-01-06 17:03:39 +00:00
										 |  |  |         _check(p.rglob(""), ["", "dirA/", "dirB/", "dirC/", "dirE/", "dirC/dirD/"]) | 
					
						
							| 
									
										
										
										
											2023-12-16 19:04:33 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-12-17 00:07:32 +00:00
										 |  |  |         p = P(self.base, "dirC") | 
					
						
							| 
									
										
										
										
											2023-12-16 19:04:33 +00:00
										 |  |  |         _check(p.rglob("*"), ["dirC/fileC", "dirC/novel.txt", | 
					
						
							|  |  |  |                               "dirC/dirD", "dirC/dirD/fileD"]) | 
					
						
							|  |  |  |         _check(p.rglob("file*"), ["dirC/fileC", "dirC/dirD/fileD"]) | 
					
						
							|  |  |  |         _check(p.rglob("**/file*"), ["dirC/fileC", "dirC/dirD/fileD"]) | 
					
						
							| 
									
										
										
										
											2024-02-06 02:48:18 +00:00
										 |  |  |         _check(p.rglob("dir*/**"), ["dirC/dirD/", "dirC/dirD/fileD"]) | 
					
						
							| 
									
										
										
										
											2023-12-16 19:04:33 +00:00
										 |  |  |         _check(p.rglob("dir*/**/"), ["dirC/dirD/"]) | 
					
						
							|  |  |  |         _check(p.rglob("*/*"), ["dirC/dirD/fileD"]) | 
					
						
							|  |  |  |         _check(p.rglob("*/"), ["dirC/dirD/"]) | 
					
						
							|  |  |  |         _check(p.rglob(""), ["dirC/", "dirC/dirD/"]) | 
					
						
							| 
									
										
										
										
											2024-01-30 19:52:53 +00:00
										 |  |  |         _check(p.rglob("**"), [ | 
					
						
							| 
									
										
										
										
											2024-02-06 02:48:18 +00:00
										 |  |  |             "dirC/", "dirC/fileC", "dirC/dirD", "dirC/dirD/fileD", "dirC/novel.txt"]) | 
					
						
							| 
									
										
										
										
											2023-12-16 19:04:33 +00:00
										 |  |  |         _check(p.rglob("**/"), ["dirC/", "dirC/dirD/"]) | 
					
						
							|  |  |  |         # gh-91616, a re module regression | 
					
						
							|  |  |  |         _check(p.rglob("*.txt"), ["dirC/novel.txt"]) | 
					
						
							|  |  |  |         _check(p.rglob("*.*"), ["dirC/novel.txt"]) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-01-27 02:16:17 +00:00
										 |  |  |     @needs_posix | 
					
						
							|  |  |  |     def test_rglob_posix(self): | 
					
						
							|  |  |  |         P = self.cls | 
					
						
							|  |  |  |         p = P(self.base, "dirC") | 
					
						
							|  |  |  |         given = set(p.rglob("FILEd")) | 
					
						
							|  |  |  |         expect = set() | 
					
						
							|  |  |  |         self.assertEqual(given, expect) | 
					
						
							|  |  |  |         self.assertEqual(set(p.rglob("FILEd*")), set()) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     @needs_windows | 
					
						
							|  |  |  |     def test_rglob_windows(self): | 
					
						
							|  |  |  |         P = self.cls | 
					
						
							|  |  |  |         p = P(self.base, "dirC") | 
					
						
							|  |  |  |         self.assertEqual(set(p.rglob("FILEd")), { P(self.base, "dirC/dirD/fileD") }) | 
					
						
							|  |  |  |         self.assertEqual(set(p.rglob("*\\")), { P(self.base, "dirC/dirD/") }) | 
					
						
							|  |  |  |         self.assertEqual(set(map(str, p.rglob("FILEd"))), {f"{p}\\dirD\\fileD"}) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-01-26 22:29:28 +00:00
										 |  |  |     @needs_symlinks | 
					
						
							| 
									
										
										
										
											2023-12-16 19:04:33 +00:00
										 |  |  |     def test_rglob_follow_symlinks_common(self): | 
					
						
							|  |  |  |         def _check(path, glob, expected): | 
					
						
							|  |  |  |             actual = {path for path in path.rglob(glob, follow_symlinks=True) | 
					
						
							| 
									
										
										
										
											2024-01-06 17:03:39 +00:00
										 |  |  |                       if path.parts.count("linkD") <= 1}  # exclude symlink loop. | 
					
						
							| 
									
										
										
										
											2023-12-17 00:07:32 +00:00
										 |  |  |             self.assertEqual(actual, { P(self.base, q) for q in expected }) | 
					
						
							| 
									
										
										
										
											2023-12-16 19:04:33 +00:00
										 |  |  |         P = self.cls | 
					
						
							| 
									
										
										
										
											2023-12-17 00:07:32 +00:00
										 |  |  |         p = P(self.base) | 
					
						
							| 
									
										
										
										
											2024-01-06 17:03:39 +00:00
										 |  |  |         _check(p, "fileB", ["dirB/fileB", "dirA/linkC/fileB", "linkB/fileB", | 
					
						
							|  |  |  |                             "dirA/linkC/linkD/fileB", "dirB/linkD/fileB", "linkB/linkD/fileB"]) | 
					
						
							| 
									
										
										
										
											2023-12-16 19:04:33 +00:00
										 |  |  |         _check(p, "*/fileA", []) | 
					
						
							| 
									
										
										
										
											2024-01-06 17:03:39 +00:00
										 |  |  |         _check(p, "*/fileB", ["dirB/fileB", "dirA/linkC/fileB", "linkB/fileB", | 
					
						
							|  |  |  |                               "dirA/linkC/linkD/fileB", "dirB/linkD/fileB", "linkB/linkD/fileB"]) | 
					
						
							| 
									
										
										
										
											2023-12-16 19:04:33 +00:00
										 |  |  |         _check(p, "file*", ["fileA", "dirA/linkC/fileB", "dirB/fileB", | 
					
						
							| 
									
										
										
										
											2024-01-06 17:03:39 +00:00
										 |  |  |                             "dirA/linkC/linkD/fileB", "dirB/linkD/fileB", "linkB/linkD/fileB", | 
					
						
							| 
									
										
										
										
											2023-12-16 19:04:33 +00:00
										 |  |  |                             "dirC/fileC", "dirC/dirD/fileD", "linkB/fileB"]) | 
					
						
							|  |  |  |         _check(p, "*/", ["dirA/", "dirA/linkC/", "dirA/linkC/linkD/", "dirB/", "dirB/linkD/", | 
					
						
							|  |  |  |                          "dirC/", "dirC/dirD/", "dirE/", "linkB/", "linkB/linkD/"]) | 
					
						
							| 
									
										
										
										
											2024-01-06 17:03:39 +00:00
										 |  |  |         _check(p, "", ["", "dirA/", "dirA/linkC/", "dirA/linkC/linkD/", "dirB/", "dirB/linkD/", | 
					
						
							| 
									
										
										
										
											2023-12-16 19:04:33 +00:00
										 |  |  |                        "dirC/", "dirE/", "dirC/dirD/", "linkB/", "linkB/linkD/"]) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-12-17 00:07:32 +00:00
										 |  |  |         p = P(self.base, "dirC") | 
					
						
							| 
									
										
										
										
											2023-12-16 19:04:33 +00:00
										 |  |  |         _check(p, "*", ["dirC/fileC", "dirC/novel.txt", | 
					
						
							|  |  |  |                         "dirC/dirD", "dirC/dirD/fileD"]) | 
					
						
							|  |  |  |         _check(p, "file*", ["dirC/fileC", "dirC/dirD/fileD"]) | 
					
						
							|  |  |  |         _check(p, "*/*", ["dirC/dirD/fileD"]) | 
					
						
							|  |  |  |         _check(p, "*/", ["dirC/dirD/"]) | 
					
						
							|  |  |  |         _check(p, "", ["dirC/", "dirC/dirD/"]) | 
					
						
							|  |  |  |         # gh-91616, a re module regression | 
					
						
							|  |  |  |         _check(p, "*.txt", ["dirC/novel.txt"]) | 
					
						
							|  |  |  |         _check(p, "*.*", ["dirC/novel.txt"]) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-01-26 22:29:28 +00:00
										 |  |  |     @needs_symlinks | 
					
						
							| 
									
										
										
										
											2023-12-16 19:04:33 +00:00
										 |  |  |     def test_rglob_no_follow_symlinks_common(self): | 
					
						
							|  |  |  |         def _check(path, glob, expected): | 
					
						
							|  |  |  |             actual = {path for path in path.rglob(glob, follow_symlinks=False)} | 
					
						
							| 
									
										
										
										
											2023-12-17 00:07:32 +00:00
										 |  |  |             self.assertEqual(actual, { P(self.base, q) for q in expected }) | 
					
						
							| 
									
										
										
										
											2023-12-16 19:04:33 +00:00
										 |  |  |         P = self.cls | 
					
						
							| 
									
										
										
										
											2023-12-17 00:07:32 +00:00
										 |  |  |         p = P(self.base) | 
					
						
							| 
									
										
										
										
											2023-12-16 19:04:33 +00:00
										 |  |  |         _check(p, "fileB", ["dirB/fileB"]) | 
					
						
							|  |  |  |         _check(p, "*/fileA", []) | 
					
						
							|  |  |  |         _check(p, "*/fileB", ["dirB/fileB"]) | 
					
						
							|  |  |  |         _check(p, "file*", ["fileA", "dirB/fileB", "dirC/fileC", "dirC/dirD/fileD", ]) | 
					
						
							|  |  |  |         _check(p, "*/", ["dirA/", "dirB/", "dirC/", "dirC/dirD/", "dirE/"]) | 
					
						
							| 
									
										
										
										
											2024-01-06 17:03:39 +00:00
										 |  |  |         _check(p, "", ["", "dirA/", "dirB/", "dirC/", "dirE/", "dirC/dirD/"]) | 
					
						
							| 
									
										
										
										
											2023-12-16 19:04:33 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-12-17 00:07:32 +00:00
										 |  |  |         p = P(self.base, "dirC") | 
					
						
							| 
									
										
										
										
											2023-12-16 19:04:33 +00:00
										 |  |  |         _check(p, "*", ["dirC/fileC", "dirC/novel.txt", | 
					
						
							|  |  |  |                         "dirC/dirD", "dirC/dirD/fileD"]) | 
					
						
							|  |  |  |         _check(p, "file*", ["dirC/fileC", "dirC/dirD/fileD"]) | 
					
						
							|  |  |  |         _check(p, "*/*", ["dirC/dirD/fileD"]) | 
					
						
							|  |  |  |         _check(p, "*/", ["dirC/dirD/"]) | 
					
						
							|  |  |  |         _check(p, "", ["dirC/", "dirC/dirD/"]) | 
					
						
							|  |  |  |         # gh-91616, a re module regression | 
					
						
							|  |  |  |         _check(p, "*.txt", ["dirC/novel.txt"]) | 
					
						
							|  |  |  |         _check(p, "*.*", ["dirC/novel.txt"]) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-01-26 22:29:28 +00:00
										 |  |  |     @needs_symlinks | 
					
						
							| 
									
										
										
										
											2023-12-16 19:04:33 +00:00
										 |  |  |     def test_rglob_symlink_loop(self): | 
					
						
							|  |  |  |         # Don't get fooled by symlink loops (Issue #26012). | 
					
						
							|  |  |  |         P = self.cls | 
					
						
							| 
									
										
										
										
											2023-12-17 00:07:32 +00:00
										 |  |  |         p = P(self.base) | 
					
						
							| 
									
										
										
										
											2023-12-16 19:04:33 +00:00
										 |  |  |         given = set(p.rglob('*')) | 
					
						
							|  |  |  |         expect = {'brokenLink', | 
					
						
							|  |  |  |                   'dirA', 'dirA/linkC', | 
					
						
							|  |  |  |                   'dirB', 'dirB/fileB', 'dirB/linkD', | 
					
						
							|  |  |  |                   'dirC', 'dirC/dirD', 'dirC/dirD/fileD', | 
					
						
							|  |  |  |                   'dirC/fileC', 'dirC/novel.txt', | 
					
						
							|  |  |  |                   'dirE', | 
					
						
							|  |  |  |                   'fileA', | 
					
						
							|  |  |  |                   'linkA', | 
					
						
							|  |  |  |                   'linkB', | 
					
						
							|  |  |  |                   'brokenLinkLoop', | 
					
						
							|  |  |  |                   } | 
					
						
							|  |  |  |         self.assertEqual(given, {p / x for x in expect}) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_glob_dotdot(self): | 
					
						
							|  |  |  |         # ".." is not special in globs. | 
					
						
							|  |  |  |         P = self.cls | 
					
						
							| 
									
										
										
										
											2023-12-17 00:07:32 +00:00
										 |  |  |         p = P(self.base) | 
					
						
							|  |  |  |         self.assertEqual(set(p.glob("..")), { P(self.base, "..") }) | 
					
						
							|  |  |  |         self.assertEqual(set(p.glob("../..")), { P(self.base, "..", "..") }) | 
					
						
							|  |  |  |         self.assertEqual(set(p.glob("dirA/..")), { P(self.base, "dirA", "..") }) | 
					
						
							|  |  |  |         self.assertEqual(set(p.glob("dirA/../file*")), { P(self.base, "dirA/../fileA") }) | 
					
						
							| 
									
										
										
										
											2023-12-16 19:04:33 +00:00
										 |  |  |         self.assertEqual(set(p.glob("dirA/../file*/..")), set()) | 
					
						
							|  |  |  |         self.assertEqual(set(p.glob("../xyzzy")), set()) | 
					
						
							|  |  |  |         self.assertEqual(set(p.glob("xyzzy/..")), set()) | 
					
						
							| 
									
										
										
										
											2023-12-17 00:07:32 +00:00
										 |  |  |         self.assertEqual(set(p.glob("/".join([".."] * 50))), { P(self.base, *[".."] * 50)}) | 
					
						
							| 
									
										
										
										
											2023-12-16 19:04:33 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-01-26 22:29:28 +00:00
										 |  |  |     @needs_symlinks | 
					
						
							| 
									
										
										
										
											2023-12-16 19:04:33 +00:00
										 |  |  |     def test_glob_permissions(self): | 
					
						
							|  |  |  |         # See bpo-38894 | 
					
						
							|  |  |  |         P = self.cls | 
					
						
							| 
									
										
										
										
											2023-12-17 00:07:32 +00:00
										 |  |  |         base = P(self.base) / 'permissions' | 
					
						
							| 
									
										
										
										
											2023-12-16 19:04:33 +00:00
										 |  |  |         base.mkdir() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         for i in range(100): | 
					
						
							|  |  |  |             link = base / f"link{i}" | 
					
						
							|  |  |  |             if i % 2: | 
					
						
							| 
									
										
										
										
											2023-12-17 00:07:32 +00:00
										 |  |  |                 link.symlink_to(P(self.base, "dirE", "nonexistent")) | 
					
						
							| 
									
										
										
										
											2023-12-16 19:04:33 +00:00
										 |  |  |             else: | 
					
						
							| 
									
										
										
										
											2023-12-17 00:07:32 +00:00
										 |  |  |                 link.symlink_to(P(self.base, "dirC")) | 
					
						
							| 
									
										
										
										
											2023-12-16 19:04:33 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |         self.assertEqual(len(set(base.glob("*"))), 100) | 
					
						
							|  |  |  |         self.assertEqual(len(set(base.glob("*/"))), 50) | 
					
						
							|  |  |  |         self.assertEqual(len(set(base.glob("*/fileC"))), 50) | 
					
						
							|  |  |  |         self.assertEqual(len(set(base.glob("*/file*"))), 50) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-01-26 22:29:28 +00:00
										 |  |  |     @needs_symlinks | 
					
						
							| 
									
										
										
										
											2023-12-16 19:04:33 +00:00
										 |  |  |     def test_glob_long_symlink(self): | 
					
						
							|  |  |  |         # See gh-87695 | 
					
						
							| 
									
										
										
										
											2023-12-17 00:07:32 +00:00
										 |  |  |         base = self.cls(self.base) / 'long_symlink' | 
					
						
							| 
									
										
										
										
											2023-12-16 19:04:33 +00:00
										 |  |  |         base.mkdir() | 
					
						
							|  |  |  |         bad_link = base / 'bad_link' | 
					
						
							|  |  |  |         bad_link.symlink_to("bad" * 200) | 
					
						
							|  |  |  |         self.assertEqual(sorted(base.glob('**/*')), [bad_link]) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-01-26 22:29:28 +00:00
										 |  |  |     @needs_symlinks | 
					
						
							| 
									
										
										
										
											2023-12-16 19:04:33 +00:00
										 |  |  |     def test_readlink(self): | 
					
						
							| 
									
										
										
										
											2023-12-17 00:07:32 +00:00
										 |  |  |         P = self.cls(self.base) | 
					
						
							| 
									
										
										
										
											2023-12-16 19:04:33 +00:00
										 |  |  |         self.assertEqual((P / 'linkA').readlink(), self.cls('fileA')) | 
					
						
							|  |  |  |         self.assertEqual((P / 'brokenLink').readlink(), | 
					
						
							|  |  |  |                          self.cls('non-existing')) | 
					
						
							|  |  |  |         self.assertEqual((P / 'linkB').readlink(), self.cls('dirB')) | 
					
						
							|  |  |  |         self.assertEqual((P / 'linkB' / 'linkD').readlink(), self.cls('../dirB')) | 
					
						
							|  |  |  |         with self.assertRaises(OSError): | 
					
						
							|  |  |  |             (P / 'fileA').readlink() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     @unittest.skipIf(hasattr(os, "readlink"), "os.readlink() is present") | 
					
						
							|  |  |  |     def test_readlink_unsupported(self): | 
					
						
							| 
									
										
										
										
											2023-12-17 00:07:32 +00:00
										 |  |  |         P = self.cls(self.base) | 
					
						
							| 
									
										
										
										
											2023-12-16 19:04:33 +00:00
										 |  |  |         p = P / 'fileA' | 
					
						
							| 
									
										
										
										
											2023-12-22 20:59:17 +00:00
										 |  |  |         with self.assertRaises(UnsupportedOperation): | 
					
						
							| 
									
										
										
										
											2023-12-16 19:04:33 +00:00
										 |  |  |             q.readlink(p) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def _check_resolve(self, p, expected, strict=True): | 
					
						
							|  |  |  |         q = p.resolve(strict) | 
					
						
							|  |  |  |         self.assertEqual(q, expected) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # This can be used to check both relative and absolute resolutions. | 
					
						
							|  |  |  |     _check_resolve_relative = _check_resolve_absolute = _check_resolve | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-01-26 22:29:28 +00:00
										 |  |  |     @needs_symlinks | 
					
						
							| 
									
										
										
										
											2023-12-16 19:04:33 +00:00
										 |  |  |     def test_resolve_common(self): | 
					
						
							|  |  |  |         P = self.cls | 
					
						
							| 
									
										
										
										
											2023-12-17 00:07:32 +00:00
										 |  |  |         p = P(self.base, 'foo') | 
					
						
							| 
									
										
										
										
											2023-12-16 19:04:33 +00:00
										 |  |  |         with self.assertRaises(OSError) as cm: | 
					
						
							|  |  |  |             p.resolve(strict=True) | 
					
						
							|  |  |  |         self.assertEqual(cm.exception.errno, errno.ENOENT) | 
					
						
							|  |  |  |         # Non-strict | 
					
						
							| 
									
										
										
										
											2023-12-22 18:09:50 +00:00
										 |  |  |         pathmod = self.pathmod | 
					
						
							| 
									
										
										
										
											2023-12-16 19:04:33 +00:00
										 |  |  |         self.assertEqualNormCase(str(p.resolve(strict=False)), | 
					
						
							| 
									
										
										
										
											2023-12-22 18:09:50 +00:00
										 |  |  |                                  pathmod.join(self.base, 'foo')) | 
					
						
							| 
									
										
										
										
											2023-12-17 00:07:32 +00:00
										 |  |  |         p = P(self.base, 'foo', 'in', 'spam') | 
					
						
							| 
									
										
										
										
											2023-12-16 19:04:33 +00:00
										 |  |  |         self.assertEqualNormCase(str(p.resolve(strict=False)), | 
					
						
							| 
									
										
										
										
											2023-12-22 18:09:50 +00:00
										 |  |  |                                  pathmod.join(self.base, 'foo', 'in', 'spam')) | 
					
						
							| 
									
										
										
										
											2023-12-17 00:07:32 +00:00
										 |  |  |         p = P(self.base, '..', 'foo', 'in', 'spam') | 
					
						
							| 
									
										
										
										
											2023-12-16 19:04:33 +00:00
										 |  |  |         self.assertEqualNormCase(str(p.resolve(strict=False)), | 
					
						
							| 
									
										
										
										
											2023-12-22 18:09:50 +00:00
										 |  |  |                                  pathmod.join(pathmod.dirname(self.base), 'foo', 'in', 'spam')) | 
					
						
							| 
									
										
										
										
											2023-12-16 19:04:33 +00:00
										 |  |  |         # These are all relative symlinks. | 
					
						
							| 
									
										
										
										
											2023-12-17 00:07:32 +00:00
										 |  |  |         p = P(self.base, 'dirB', 'fileB') | 
					
						
							| 
									
										
										
										
											2023-12-16 19:04:33 +00:00
										 |  |  |         self._check_resolve_relative(p, p) | 
					
						
							| 
									
										
										
										
											2023-12-17 00:07:32 +00:00
										 |  |  |         p = P(self.base, 'linkA') | 
					
						
							|  |  |  |         self._check_resolve_relative(p, P(self.base, 'fileA')) | 
					
						
							|  |  |  |         p = P(self.base, 'dirA', 'linkC', 'fileB') | 
					
						
							|  |  |  |         self._check_resolve_relative(p, P(self.base, 'dirB', 'fileB')) | 
					
						
							|  |  |  |         p = P(self.base, 'dirB', 'linkD', 'fileB') | 
					
						
							|  |  |  |         self._check_resolve_relative(p, P(self.base, 'dirB', 'fileB')) | 
					
						
							| 
									
										
										
										
											2023-12-16 19:04:33 +00:00
										 |  |  |         # Non-strict | 
					
						
							| 
									
										
										
										
											2023-12-17 00:07:32 +00:00
										 |  |  |         p = P(self.base, 'dirA', 'linkC', 'fileB', 'foo', 'in', 'spam') | 
					
						
							|  |  |  |         self._check_resolve_relative(p, P(self.base, 'dirB', 'fileB', 'foo', 'in', | 
					
						
							| 
									
										
										
										
											2023-12-16 19:04:33 +00:00
										 |  |  |                                           'spam'), False) | 
					
						
							| 
									
										
										
										
											2023-12-17 00:07:32 +00:00
										 |  |  |         p = P(self.base, 'dirA', 'linkC', '..', 'foo', 'in', 'spam') | 
					
						
							| 
									
										
										
										
											2023-12-22 18:09:50 +00:00
										 |  |  |         if self.cls.pathmod is not posixpath: | 
					
						
							| 
									
										
										
										
											2023-12-16 19:04:33 +00:00
										 |  |  |             # In Windows, if linkY points to dirB, 'dirA\linkY\..' | 
					
						
							|  |  |  |             # resolves to 'dirA' without resolving linkY first. | 
					
						
							| 
									
										
										
										
											2023-12-17 00:07:32 +00:00
										 |  |  |             self._check_resolve_relative(p, P(self.base, 'dirA', 'foo', 'in', | 
					
						
							| 
									
										
										
										
											2023-12-16 19:04:33 +00:00
										 |  |  |                                               'spam'), False) | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             # In Posix, if linkY points to dirB, 'dirA/linkY/..' | 
					
						
							|  |  |  |             # resolves to 'dirB/..' first before resolving to parent of dirB. | 
					
						
							| 
									
										
										
										
											2023-12-17 00:07:32 +00:00
										 |  |  |             self._check_resolve_relative(p, P(self.base, 'foo', 'in', 'spam'), False) | 
					
						
							| 
									
										
										
										
											2023-12-16 19:04:33 +00:00
										 |  |  |         # Now create absolute symlinks. | 
					
						
							|  |  |  |         d = self.tempdir() | 
					
						
							| 
									
										
										
										
											2023-12-17 00:07:32 +00:00
										 |  |  |         P(self.base, 'dirA', 'linkX').symlink_to(d) | 
					
						
							|  |  |  |         P(self.base, str(d), 'linkY').symlink_to(self.pathmod.join(self.base, 'dirB')) | 
					
						
							|  |  |  |         p = P(self.base, 'dirA', 'linkX', 'linkY', 'fileB') | 
					
						
							|  |  |  |         self._check_resolve_absolute(p, P(self.base, 'dirB', 'fileB')) | 
					
						
							| 
									
										
										
										
											2023-12-16 19:04:33 +00:00
										 |  |  |         # Non-strict | 
					
						
							| 
									
										
										
										
											2023-12-17 00:07:32 +00:00
										 |  |  |         p = P(self.base, 'dirA', 'linkX', 'linkY', 'foo', 'in', 'spam') | 
					
						
							|  |  |  |         self._check_resolve_relative(p, P(self.base, 'dirB', 'foo', 'in', 'spam'), | 
					
						
							| 
									
										
										
										
											2023-12-16 19:04:33 +00:00
										 |  |  |                                      False) | 
					
						
							| 
									
										
										
										
											2023-12-17 00:07:32 +00:00
										 |  |  |         p = P(self.base, 'dirA', 'linkX', 'linkY', '..', 'foo', 'in', 'spam') | 
					
						
							| 
									
										
										
										
											2023-12-22 18:09:50 +00:00
										 |  |  |         if self.cls.pathmod is not posixpath: | 
					
						
							| 
									
										
										
										
											2023-12-16 19:04:33 +00:00
										 |  |  |             # In Windows, if linkY points to dirB, 'dirA\linkY\..' | 
					
						
							|  |  |  |             # resolves to 'dirA' without resolving linkY first. | 
					
						
							|  |  |  |             self._check_resolve_relative(p, P(d, 'foo', 'in', 'spam'), False) | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             # In Posix, if linkY points to dirB, 'dirA/linkY/..' | 
					
						
							|  |  |  |             # resolves to 'dirB/..' first before resolving to parent of dirB. | 
					
						
							| 
									
										
										
										
											2023-12-17 00:07:32 +00:00
										 |  |  |             self._check_resolve_relative(p, P(self.base, 'foo', 'in', 'spam'), False) | 
					
						
							| 
									
										
										
										
											2023-12-16 19:04:33 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-01-26 22:29:28 +00:00
										 |  |  |     @needs_symlinks | 
					
						
							| 
									
										
										
										
											2023-12-16 19:04:33 +00:00
										 |  |  |     def test_resolve_dot(self): | 
					
						
							|  |  |  |         # See http://web.archive.org/web/20200623062557/https://bitbucket.org/pitrou/pathlib/issues/9/ | 
					
						
							| 
									
										
										
										
											2023-12-22 18:09:50 +00:00
										 |  |  |         pathmod = self.pathmod | 
					
						
							| 
									
										
										
										
											2023-12-17 00:07:32 +00:00
										 |  |  |         p = self.cls(self.base) | 
					
						
							| 
									
										
										
										
											2023-12-16 19:04:33 +00:00
										 |  |  |         p.joinpath('0').symlink_to('.', target_is_directory=True) | 
					
						
							| 
									
										
										
										
											2023-12-22 18:09:50 +00:00
										 |  |  |         p.joinpath('1').symlink_to(pathmod.join('0', '0'), target_is_directory=True) | 
					
						
							|  |  |  |         p.joinpath('2').symlink_to(pathmod.join('1', '1'), target_is_directory=True) | 
					
						
							| 
									
										
										
										
											2023-12-16 19:04:33 +00:00
										 |  |  |         q = p / '2' | 
					
						
							|  |  |  |         self.assertEqual(q.resolve(strict=True), p) | 
					
						
							|  |  |  |         r = q / '3' / '4' | 
					
						
							|  |  |  |         self.assertRaises(FileNotFoundError, r.resolve, strict=True) | 
					
						
							|  |  |  |         # Non-strict | 
					
						
							|  |  |  |         self.assertEqual(r.resolve(strict=False), p / '3' / '4') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def _check_symlink_loop(self, *args): | 
					
						
							|  |  |  |         path = self.cls(*args) | 
					
						
							|  |  |  |         with self.assertRaises(OSError) as cm: | 
					
						
							|  |  |  |             path.resolve(strict=True) | 
					
						
							|  |  |  |         self.assertEqual(cm.exception.errno, errno.ELOOP) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-01-26 22:29:28 +00:00
										 |  |  |     @needs_posix | 
					
						
							|  |  |  |     @needs_symlinks | 
					
						
							| 
									
										
										
										
											2023-12-16 19:04:33 +00:00
										 |  |  |     def test_resolve_loop(self): | 
					
						
							|  |  |  |         # Loops with relative symlinks. | 
					
						
							| 
									
										
										
										
											2023-12-17 00:07:32 +00:00
										 |  |  |         self.cls(self.base, 'linkX').symlink_to('linkX/inside') | 
					
						
							|  |  |  |         self._check_symlink_loop(self.base, 'linkX') | 
					
						
							|  |  |  |         self.cls(self.base, 'linkY').symlink_to('linkY') | 
					
						
							|  |  |  |         self._check_symlink_loop(self.base, 'linkY') | 
					
						
							|  |  |  |         self.cls(self.base, 'linkZ').symlink_to('linkZ/../linkZ') | 
					
						
							|  |  |  |         self._check_symlink_loop(self.base, 'linkZ') | 
					
						
							| 
									
										
										
										
											2023-12-16 19:04:33 +00:00
										 |  |  |         # Non-strict | 
					
						
							| 
									
										
										
										
											2023-12-17 00:07:32 +00:00
										 |  |  |         p = self.cls(self.base, 'linkZ', 'foo') | 
					
						
							| 
									
										
										
										
											2023-12-16 19:04:33 +00:00
										 |  |  |         self.assertEqual(p.resolve(strict=False), p) | 
					
						
							|  |  |  |         # Loops with absolute symlinks. | 
					
						
							| 
									
										
										
										
											2023-12-17 00:07:32 +00:00
										 |  |  |         self.cls(self.base, 'linkU').symlink_to(self.pathmod.join(self.base, 'linkU/inside')) | 
					
						
							|  |  |  |         self._check_symlink_loop(self.base, 'linkU') | 
					
						
							|  |  |  |         self.cls(self.base, 'linkV').symlink_to(self.pathmod.join(self.base, 'linkV')) | 
					
						
							|  |  |  |         self._check_symlink_loop(self.base, 'linkV') | 
					
						
							|  |  |  |         self.cls(self.base, 'linkW').symlink_to(self.pathmod.join(self.base, 'linkW/../linkW')) | 
					
						
							|  |  |  |         self._check_symlink_loop(self.base, 'linkW') | 
					
						
							| 
									
										
										
										
											2023-12-16 19:04:33 +00:00
										 |  |  |         # Non-strict | 
					
						
							| 
									
										
										
										
											2023-12-17 00:07:32 +00:00
										 |  |  |         q = self.cls(self.base, 'linkW', 'foo') | 
					
						
							| 
									
										
										
										
											2023-12-16 19:04:33 +00:00
										 |  |  |         self.assertEqual(q.resolve(strict=False), q) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_stat(self): | 
					
						
							| 
									
										
										
										
											2023-12-17 00:07:32 +00:00
										 |  |  |         statA = self.cls(self.base).joinpath('fileA').stat() | 
					
						
							|  |  |  |         statB = self.cls(self.base).joinpath('dirB', 'fileB').stat() | 
					
						
							|  |  |  |         statC = self.cls(self.base).joinpath('dirC').stat() | 
					
						
							| 
									
										
										
										
											2023-12-16 19:04:33 +00:00
										 |  |  |         # st_mode: files are the same, directory differs. | 
					
						
							|  |  |  |         self.assertIsInstance(statA.st_mode, int) | 
					
						
							|  |  |  |         self.assertEqual(statA.st_mode, statB.st_mode) | 
					
						
							|  |  |  |         self.assertNotEqual(statA.st_mode, statC.st_mode) | 
					
						
							|  |  |  |         self.assertNotEqual(statB.st_mode, statC.st_mode) | 
					
						
							|  |  |  |         # st_ino: all different, | 
					
						
							|  |  |  |         self.assertIsInstance(statA.st_ino, int) | 
					
						
							|  |  |  |         self.assertNotEqual(statA.st_ino, statB.st_ino) | 
					
						
							|  |  |  |         self.assertNotEqual(statA.st_ino, statC.st_ino) | 
					
						
							|  |  |  |         self.assertNotEqual(statB.st_ino, statC.st_ino) | 
					
						
							|  |  |  |         # st_dev: all the same. | 
					
						
							|  |  |  |         self.assertIsInstance(statA.st_dev, int) | 
					
						
							|  |  |  |         self.assertEqual(statA.st_dev, statB.st_dev) | 
					
						
							|  |  |  |         self.assertEqual(statA.st_dev, statC.st_dev) | 
					
						
							|  |  |  |         # other attributes not used by pathlib. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-01-26 22:29:28 +00:00
										 |  |  |     @needs_symlinks | 
					
						
							| 
									
										
										
										
											2023-12-16 19:04:33 +00:00
										 |  |  |     def test_stat_no_follow_symlinks(self): | 
					
						
							| 
									
										
										
										
											2023-12-17 00:07:32 +00:00
										 |  |  |         p = self.cls(self.base) / 'linkA' | 
					
						
							| 
									
										
										
										
											2023-12-16 19:04:33 +00:00
										 |  |  |         st = p.stat() | 
					
						
							|  |  |  |         self.assertNotEqual(st, p.stat(follow_symlinks=False)) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_stat_no_follow_symlinks_nosymlink(self): | 
					
						
							| 
									
										
										
										
											2023-12-17 00:07:32 +00:00
										 |  |  |         p = self.cls(self.base) / 'fileA' | 
					
						
							| 
									
										
										
										
											2023-12-16 19:04:33 +00:00
										 |  |  |         st = p.stat() | 
					
						
							|  |  |  |         self.assertEqual(st, p.stat(follow_symlinks=False)) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-01-26 22:29:28 +00:00
										 |  |  |     @needs_symlinks | 
					
						
							| 
									
										
										
										
											2023-12-16 19:04:33 +00:00
										 |  |  |     def test_lstat(self): | 
					
						
							| 
									
										
										
										
											2023-12-17 00:07:32 +00:00
										 |  |  |         p = self.cls(self.base)/ 'linkA' | 
					
						
							| 
									
										
										
										
											2023-12-16 19:04:33 +00:00
										 |  |  |         st = p.stat() | 
					
						
							|  |  |  |         self.assertNotEqual(st, p.lstat()) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_lstat_nosymlink(self): | 
					
						
							| 
									
										
										
										
											2023-12-17 00:07:32 +00:00
										 |  |  |         p = self.cls(self.base) / 'fileA' | 
					
						
							| 
									
										
										
										
											2023-12-16 19:04:33 +00:00
										 |  |  |         st = p.stat() | 
					
						
							|  |  |  |         self.assertEqual(st, p.lstat()) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_is_dir(self): | 
					
						
							| 
									
										
										
										
											2023-12-17 00:07:32 +00:00
										 |  |  |         P = self.cls(self.base) | 
					
						
							| 
									
										
										
										
											2023-12-16 19:04:33 +00:00
										 |  |  |         self.assertTrue((P / 'dirA').is_dir()) | 
					
						
							|  |  |  |         self.assertFalse((P / 'fileA').is_dir()) | 
					
						
							|  |  |  |         self.assertFalse((P / 'non-existing').is_dir()) | 
					
						
							|  |  |  |         self.assertFalse((P / 'fileA' / 'bah').is_dir()) | 
					
						
							|  |  |  |         if self.can_symlink: | 
					
						
							|  |  |  |             self.assertFalse((P / 'linkA').is_dir()) | 
					
						
							|  |  |  |             self.assertTrue((P / 'linkB').is_dir()) | 
					
						
							|  |  |  |             self.assertFalse((P/ 'brokenLink').is_dir()) | 
					
						
							|  |  |  |         self.assertFalse((P / 'dirA\udfff').is_dir()) | 
					
						
							|  |  |  |         self.assertFalse((P / 'dirA\x00').is_dir()) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_is_dir_no_follow_symlinks(self): | 
					
						
							| 
									
										
										
										
											2023-12-17 00:07:32 +00:00
										 |  |  |         P = self.cls(self.base) | 
					
						
							| 
									
										
										
										
											2023-12-16 19:04:33 +00:00
										 |  |  |         self.assertTrue((P / 'dirA').is_dir(follow_symlinks=False)) | 
					
						
							|  |  |  |         self.assertFalse((P / 'fileA').is_dir(follow_symlinks=False)) | 
					
						
							|  |  |  |         self.assertFalse((P / 'non-existing').is_dir(follow_symlinks=False)) | 
					
						
							|  |  |  |         self.assertFalse((P / 'fileA' / 'bah').is_dir(follow_symlinks=False)) | 
					
						
							|  |  |  |         if self.can_symlink: | 
					
						
							|  |  |  |             self.assertFalse((P / 'linkA').is_dir(follow_symlinks=False)) | 
					
						
							|  |  |  |             self.assertFalse((P / 'linkB').is_dir(follow_symlinks=False)) | 
					
						
							|  |  |  |             self.assertFalse((P/ 'brokenLink').is_dir(follow_symlinks=False)) | 
					
						
							|  |  |  |         self.assertFalse((P / 'dirA\udfff').is_dir(follow_symlinks=False)) | 
					
						
							|  |  |  |         self.assertFalse((P / 'dirA\x00').is_dir(follow_symlinks=False)) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_is_file(self): | 
					
						
							| 
									
										
										
										
											2023-12-17 00:07:32 +00:00
										 |  |  |         P = self.cls(self.base) | 
					
						
							| 
									
										
										
										
											2023-12-16 19:04:33 +00:00
										 |  |  |         self.assertTrue((P / 'fileA').is_file()) | 
					
						
							|  |  |  |         self.assertFalse((P / 'dirA').is_file()) | 
					
						
							|  |  |  |         self.assertFalse((P / 'non-existing').is_file()) | 
					
						
							|  |  |  |         self.assertFalse((P / 'fileA' / 'bah').is_file()) | 
					
						
							|  |  |  |         if self.can_symlink: | 
					
						
							|  |  |  |             self.assertTrue((P / 'linkA').is_file()) | 
					
						
							|  |  |  |             self.assertFalse((P / 'linkB').is_file()) | 
					
						
							|  |  |  |             self.assertFalse((P/ 'brokenLink').is_file()) | 
					
						
							|  |  |  |         self.assertFalse((P / 'fileA\udfff').is_file()) | 
					
						
							|  |  |  |         self.assertFalse((P / 'fileA\x00').is_file()) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_is_file_no_follow_symlinks(self): | 
					
						
							| 
									
										
										
										
											2023-12-17 00:07:32 +00:00
										 |  |  |         P = self.cls(self.base) | 
					
						
							| 
									
										
										
										
											2023-12-16 19:04:33 +00:00
										 |  |  |         self.assertTrue((P / 'fileA').is_file(follow_symlinks=False)) | 
					
						
							|  |  |  |         self.assertFalse((P / 'dirA').is_file(follow_symlinks=False)) | 
					
						
							|  |  |  |         self.assertFalse((P / 'non-existing').is_file(follow_symlinks=False)) | 
					
						
							|  |  |  |         self.assertFalse((P / 'fileA' / 'bah').is_file(follow_symlinks=False)) | 
					
						
							|  |  |  |         if self.can_symlink: | 
					
						
							|  |  |  |             self.assertFalse((P / 'linkA').is_file(follow_symlinks=False)) | 
					
						
							|  |  |  |             self.assertFalse((P / 'linkB').is_file(follow_symlinks=False)) | 
					
						
							|  |  |  |             self.assertFalse((P/ 'brokenLink').is_file(follow_symlinks=False)) | 
					
						
							|  |  |  |         self.assertFalse((P / 'fileA\udfff').is_file(follow_symlinks=False)) | 
					
						
							|  |  |  |         self.assertFalse((P / 'fileA\x00').is_file(follow_symlinks=False)) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_is_mount(self): | 
					
						
							| 
									
										
										
										
											2023-12-17 00:07:32 +00:00
										 |  |  |         P = self.cls(self.base) | 
					
						
							| 
									
										
										
										
											2023-12-16 19:04:33 +00:00
										 |  |  |         self.assertFalse((P / 'fileA').is_mount()) | 
					
						
							|  |  |  |         self.assertFalse((P / 'dirA').is_mount()) | 
					
						
							|  |  |  |         self.assertFalse((P / 'non-existing').is_mount()) | 
					
						
							|  |  |  |         self.assertFalse((P / 'fileA' / 'bah').is_mount()) | 
					
						
							|  |  |  |         if self.can_symlink: | 
					
						
							|  |  |  |             self.assertFalse((P / 'linkA').is_mount()) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_is_symlink(self): | 
					
						
							| 
									
										
										
										
											2023-12-17 00:07:32 +00:00
										 |  |  |         P = self.cls(self.base) | 
					
						
							| 
									
										
										
										
											2023-12-16 19:04:33 +00:00
										 |  |  |         self.assertFalse((P / 'fileA').is_symlink()) | 
					
						
							|  |  |  |         self.assertFalse((P / 'dirA').is_symlink()) | 
					
						
							|  |  |  |         self.assertFalse((P / 'non-existing').is_symlink()) | 
					
						
							|  |  |  |         self.assertFalse((P / 'fileA' / 'bah').is_symlink()) | 
					
						
							|  |  |  |         if self.can_symlink: | 
					
						
							|  |  |  |             self.assertTrue((P / 'linkA').is_symlink()) | 
					
						
							|  |  |  |             self.assertTrue((P / 'linkB').is_symlink()) | 
					
						
							|  |  |  |             self.assertTrue((P/ 'brokenLink').is_symlink()) | 
					
						
							|  |  |  |         self.assertIs((P / 'fileA\udfff').is_file(), False) | 
					
						
							|  |  |  |         self.assertIs((P / 'fileA\x00').is_file(), False) | 
					
						
							|  |  |  |         if self.can_symlink: | 
					
						
							|  |  |  |             self.assertIs((P / 'linkA\udfff').is_file(), False) | 
					
						
							|  |  |  |             self.assertIs((P / 'linkA\x00').is_file(), False) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_is_junction_false(self): | 
					
						
							| 
									
										
										
										
											2023-12-17 00:07:32 +00:00
										 |  |  |         P = self.cls(self.base) | 
					
						
							| 
									
										
										
										
											2023-12-16 19:04:33 +00:00
										 |  |  |         self.assertFalse((P / 'fileA').is_junction()) | 
					
						
							|  |  |  |         self.assertFalse((P / 'dirA').is_junction()) | 
					
						
							|  |  |  |         self.assertFalse((P / 'non-existing').is_junction()) | 
					
						
							|  |  |  |         self.assertFalse((P / 'fileA' / 'bah').is_junction()) | 
					
						
							|  |  |  |         self.assertFalse((P / 'fileA\udfff').is_junction()) | 
					
						
							|  |  |  |         self.assertFalse((P / 'fileA\x00').is_junction()) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_is_fifo_false(self): | 
					
						
							| 
									
										
										
										
											2023-12-17 00:07:32 +00:00
										 |  |  |         P = self.cls(self.base) | 
					
						
							| 
									
										
										
										
											2023-12-16 19:04:33 +00:00
										 |  |  |         self.assertFalse((P / 'fileA').is_fifo()) | 
					
						
							|  |  |  |         self.assertFalse((P / 'dirA').is_fifo()) | 
					
						
							|  |  |  |         self.assertFalse((P / 'non-existing').is_fifo()) | 
					
						
							|  |  |  |         self.assertFalse((P / 'fileA' / 'bah').is_fifo()) | 
					
						
							|  |  |  |         self.assertIs((P / 'fileA\udfff').is_fifo(), False) | 
					
						
							|  |  |  |         self.assertIs((P / 'fileA\x00').is_fifo(), False) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_is_socket_false(self): | 
					
						
							| 
									
										
										
										
											2023-12-17 00:07:32 +00:00
										 |  |  |         P = self.cls(self.base) | 
					
						
							| 
									
										
										
										
											2023-12-16 19:04:33 +00:00
										 |  |  |         self.assertFalse((P / 'fileA').is_socket()) | 
					
						
							|  |  |  |         self.assertFalse((P / 'dirA').is_socket()) | 
					
						
							|  |  |  |         self.assertFalse((P / 'non-existing').is_socket()) | 
					
						
							|  |  |  |         self.assertFalse((P / 'fileA' / 'bah').is_socket()) | 
					
						
							|  |  |  |         self.assertIs((P / 'fileA\udfff').is_socket(), False) | 
					
						
							|  |  |  |         self.assertIs((P / 'fileA\x00').is_socket(), False) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_is_block_device_false(self): | 
					
						
							| 
									
										
										
										
											2023-12-17 00:07:32 +00:00
										 |  |  |         P = self.cls(self.base) | 
					
						
							| 
									
										
										
										
											2023-12-16 19:04:33 +00:00
										 |  |  |         self.assertFalse((P / 'fileA').is_block_device()) | 
					
						
							|  |  |  |         self.assertFalse((P / 'dirA').is_block_device()) | 
					
						
							|  |  |  |         self.assertFalse((P / 'non-existing').is_block_device()) | 
					
						
							|  |  |  |         self.assertFalse((P / 'fileA' / 'bah').is_block_device()) | 
					
						
							|  |  |  |         self.assertIs((P / 'fileA\udfff').is_block_device(), False) | 
					
						
							|  |  |  |         self.assertIs((P / 'fileA\x00').is_block_device(), False) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_is_char_device_false(self): | 
					
						
							| 
									
										
										
										
											2023-12-17 00:07:32 +00:00
										 |  |  |         P = self.cls(self.base) | 
					
						
							| 
									
										
										
										
											2023-12-16 19:04:33 +00:00
										 |  |  |         self.assertFalse((P / 'fileA').is_char_device()) | 
					
						
							|  |  |  |         self.assertFalse((P / 'dirA').is_char_device()) | 
					
						
							|  |  |  |         self.assertFalse((P / 'non-existing').is_char_device()) | 
					
						
							|  |  |  |         self.assertFalse((P / 'fileA' / 'bah').is_char_device()) | 
					
						
							|  |  |  |         self.assertIs((P / 'fileA\udfff').is_char_device(), False) | 
					
						
							|  |  |  |         self.assertIs((P / 'fileA\x00').is_char_device(), False) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def _check_complex_symlinks(self, link0_target): | 
					
						
							|  |  |  |         # Test solving a non-looping chain of symlinks (issue #19887). | 
					
						
							| 
									
										
										
										
											2023-12-22 18:09:50 +00:00
										 |  |  |         pathmod = self.pathmod | 
					
						
							| 
									
										
										
										
											2023-12-17 00:07:32 +00:00
										 |  |  |         P = self.cls(self.base) | 
					
						
							| 
									
										
										
										
											2023-12-22 18:09:50 +00:00
										 |  |  |         P.joinpath('link1').symlink_to(pathmod.join('link0', 'link0'), target_is_directory=True) | 
					
						
							|  |  |  |         P.joinpath('link2').symlink_to(pathmod.join('link1', 'link1'), target_is_directory=True) | 
					
						
							|  |  |  |         P.joinpath('link3').symlink_to(pathmod.join('link2', 'link2'), target_is_directory=True) | 
					
						
							| 
									
										
										
										
											2023-12-16 19:04:33 +00:00
										 |  |  |         P.joinpath('link0').symlink_to(link0_target, target_is_directory=True) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # Resolve absolute paths. | 
					
						
							|  |  |  |         p = (P / 'link0').resolve() | 
					
						
							|  |  |  |         self.assertEqual(p, P) | 
					
						
							| 
									
										
										
										
											2023-12-17 00:07:32 +00:00
										 |  |  |         self.assertEqualNormCase(str(p), self.base) | 
					
						
							| 
									
										
										
										
											2023-12-16 19:04:33 +00:00
										 |  |  |         p = (P / 'link1').resolve() | 
					
						
							|  |  |  |         self.assertEqual(p, P) | 
					
						
							| 
									
										
										
										
											2023-12-17 00:07:32 +00:00
										 |  |  |         self.assertEqualNormCase(str(p), self.base) | 
					
						
							| 
									
										
										
										
											2023-12-16 19:04:33 +00:00
										 |  |  |         p = (P / 'link2').resolve() | 
					
						
							|  |  |  |         self.assertEqual(p, P) | 
					
						
							| 
									
										
										
										
											2023-12-17 00:07:32 +00:00
										 |  |  |         self.assertEqualNormCase(str(p), self.base) | 
					
						
							| 
									
										
										
										
											2023-12-16 19:04:33 +00:00
										 |  |  |         p = (P / 'link3').resolve() | 
					
						
							|  |  |  |         self.assertEqual(p, P) | 
					
						
							| 
									
										
										
										
											2023-12-17 00:07:32 +00:00
										 |  |  |         self.assertEqualNormCase(str(p), self.base) | 
					
						
							| 
									
										
										
										
											2023-12-16 19:04:33 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # Resolve relative paths. | 
					
						
							|  |  |  |         try: | 
					
						
							| 
									
										
										
										
											2024-01-10 01:12:58 +00:00
										 |  |  |             self.cls('').absolute() | 
					
						
							| 
									
										
										
										
											2023-12-22 20:59:17 +00:00
										 |  |  |         except UnsupportedOperation: | 
					
						
							| 
									
										
										
										
											2023-12-16 19:04:33 +00:00
										 |  |  |             return | 
					
						
							|  |  |  |         old_path = os.getcwd() | 
					
						
							| 
									
										
										
										
											2023-12-17 00:07:32 +00:00
										 |  |  |         os.chdir(self.base) | 
					
						
							| 
									
										
										
										
											2023-12-16 19:04:33 +00:00
										 |  |  |         try: | 
					
						
							|  |  |  |             p = self.cls('link0').resolve() | 
					
						
							|  |  |  |             self.assertEqual(p, P) | 
					
						
							| 
									
										
										
										
											2023-12-17 00:07:32 +00:00
										 |  |  |             self.assertEqualNormCase(str(p), self.base) | 
					
						
							| 
									
										
										
										
											2023-12-16 19:04:33 +00:00
										 |  |  |             p = self.cls('link1').resolve() | 
					
						
							|  |  |  |             self.assertEqual(p, P) | 
					
						
							| 
									
										
										
										
											2023-12-17 00:07:32 +00:00
										 |  |  |             self.assertEqualNormCase(str(p), self.base) | 
					
						
							| 
									
										
										
										
											2023-12-16 19:04:33 +00:00
										 |  |  |             p = self.cls('link2').resolve() | 
					
						
							|  |  |  |             self.assertEqual(p, P) | 
					
						
							| 
									
										
										
										
											2023-12-17 00:07:32 +00:00
										 |  |  |             self.assertEqualNormCase(str(p), self.base) | 
					
						
							| 
									
										
										
										
											2023-12-16 19:04:33 +00:00
										 |  |  |             p = self.cls('link3').resolve() | 
					
						
							|  |  |  |             self.assertEqual(p, P) | 
					
						
							| 
									
										
										
										
											2023-12-17 00:07:32 +00:00
										 |  |  |             self.assertEqualNormCase(str(p), self.base) | 
					
						
							| 
									
										
										
										
											2023-12-16 19:04:33 +00:00
										 |  |  |         finally: | 
					
						
							|  |  |  |             os.chdir(old_path) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-01-26 22:29:28 +00:00
										 |  |  |     @needs_symlinks | 
					
						
							| 
									
										
										
										
											2023-12-16 19:04:33 +00:00
										 |  |  |     def test_complex_symlinks_absolute(self): | 
					
						
							| 
									
										
										
										
											2023-12-17 00:07:32 +00:00
										 |  |  |         self._check_complex_symlinks(self.base) | 
					
						
							| 
									
										
										
										
											2023-12-16 19:04:33 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-01-26 22:29:28 +00:00
										 |  |  |     @needs_symlinks | 
					
						
							| 
									
										
										
										
											2023-12-16 19:04:33 +00:00
										 |  |  |     def test_complex_symlinks_relative(self): | 
					
						
							|  |  |  |         self._check_complex_symlinks('.') | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-01-26 22:29:28 +00:00
										 |  |  |     @needs_symlinks | 
					
						
							| 
									
										
										
										
											2023-12-16 19:04:33 +00:00
										 |  |  |     def test_complex_symlinks_relative_dot_dot(self): | 
					
						
							| 
									
										
										
										
											2023-12-22 18:09:50 +00:00
										 |  |  |         self._check_complex_symlinks(self.pathmod.join('dirA', '..')) | 
					
						
							| 
									
										
										
										
											2023-12-16 19:04:33 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def setUpWalk(self): | 
					
						
							|  |  |  |         # Build: | 
					
						
							|  |  |  |         #     TESTFN/ | 
					
						
							|  |  |  |         #       TEST1/              a file kid and two directory kids | 
					
						
							|  |  |  |         #         tmp1 | 
					
						
							|  |  |  |         #         SUB1/             a file kid and a directory kid | 
					
						
							|  |  |  |         #           tmp2 | 
					
						
							|  |  |  |         #           SUB11/          no kids | 
					
						
							|  |  |  |         #         SUB2/             a file kid and a dirsymlink kid | 
					
						
							|  |  |  |         #           tmp3 | 
					
						
							|  |  |  |         #           link/           a symlink to TEST2 | 
					
						
							|  |  |  |         #           broken_link | 
					
						
							|  |  |  |         #           broken_link2 | 
					
						
							|  |  |  |         #       TEST2/ | 
					
						
							|  |  |  |         #         tmp4              a lone file | 
					
						
							| 
									
										
										
										
											2023-12-17 00:07:32 +00:00
										 |  |  |         self.walk_path = self.cls(self.base, "TEST1") | 
					
						
							| 
									
										
										
										
											2023-12-16 19:04:33 +00:00
										 |  |  |         self.sub1_path = self.walk_path / "SUB1" | 
					
						
							|  |  |  |         self.sub11_path = self.sub1_path / "SUB11" | 
					
						
							|  |  |  |         self.sub2_path = self.walk_path / "SUB2" | 
					
						
							|  |  |  |         tmp1_path = self.walk_path / "tmp1" | 
					
						
							|  |  |  |         tmp2_path = self.sub1_path / "tmp2" | 
					
						
							|  |  |  |         tmp3_path = self.sub2_path / "tmp3" | 
					
						
							|  |  |  |         self.link_path = self.sub2_path / "link" | 
					
						
							| 
									
										
										
										
											2023-12-17 00:07:32 +00:00
										 |  |  |         t2_path = self.cls(self.base, "TEST2") | 
					
						
							|  |  |  |         tmp4_path = self.cls(self.base, "TEST2", "tmp4") | 
					
						
							| 
									
										
										
										
											2023-12-16 19:04:33 +00:00
										 |  |  |         broken_link_path = self.sub2_path / "broken_link" | 
					
						
							|  |  |  |         broken_link2_path = self.sub2_path / "broken_link2" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         self.sub11_path.mkdir(parents=True) | 
					
						
							|  |  |  |         self.sub2_path.mkdir(parents=True) | 
					
						
							|  |  |  |         t2_path.mkdir(parents=True) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         for path in tmp1_path, tmp2_path, tmp3_path, tmp4_path: | 
					
						
							|  |  |  |             with path.open("w", encoding='utf-8') as f: | 
					
						
							|  |  |  |                 f.write(f"I'm {path} and proud of it.  Blame test_pathlib.\n") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if self.can_symlink: | 
					
						
							|  |  |  |             self.link_path.symlink_to(t2_path) | 
					
						
							|  |  |  |             broken_link_path.symlink_to('broken') | 
					
						
							|  |  |  |             broken_link2_path.symlink_to(self.cls('tmp3', 'broken')) | 
					
						
							|  |  |  |             self.sub2_tree = (self.sub2_path, [], ["broken_link", "broken_link2", "link", "tmp3"]) | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             self.sub2_tree = (self.sub2_path, [], ["tmp3"]) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_walk_topdown(self): | 
					
						
							|  |  |  |         self.setUpWalk() | 
					
						
							|  |  |  |         walker = self.walk_path.walk() | 
					
						
							|  |  |  |         entry = next(walker) | 
					
						
							|  |  |  |         entry[1].sort()  # Ensure we visit SUB1 before SUB2 | 
					
						
							|  |  |  |         self.assertEqual(entry, (self.walk_path, ["SUB1", "SUB2"], ["tmp1"])) | 
					
						
							|  |  |  |         entry = next(walker) | 
					
						
							|  |  |  |         self.assertEqual(entry, (self.sub1_path, ["SUB11"], ["tmp2"])) | 
					
						
							|  |  |  |         entry = next(walker) | 
					
						
							|  |  |  |         self.assertEqual(entry, (self.sub11_path, [], [])) | 
					
						
							|  |  |  |         entry = next(walker) | 
					
						
							|  |  |  |         entry[1].sort() | 
					
						
							|  |  |  |         entry[2].sort() | 
					
						
							|  |  |  |         self.assertEqual(entry, self.sub2_tree) | 
					
						
							|  |  |  |         with self.assertRaises(StopIteration): | 
					
						
							|  |  |  |             next(walker) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_walk_prune(self): | 
					
						
							|  |  |  |         self.setUpWalk() | 
					
						
							|  |  |  |         # Prune the search. | 
					
						
							|  |  |  |         all = [] | 
					
						
							|  |  |  |         for root, dirs, files in self.walk_path.walk(): | 
					
						
							|  |  |  |             all.append((root, dirs, files)) | 
					
						
							|  |  |  |             if 'SUB1' in dirs: | 
					
						
							|  |  |  |                 # Note that this also mutates the dirs we appended to all! | 
					
						
							|  |  |  |                 dirs.remove('SUB1') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         self.assertEqual(len(all), 2) | 
					
						
							|  |  |  |         self.assertEqual(all[0], (self.walk_path, ["SUB2"], ["tmp1"])) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         all[1][-1].sort() | 
					
						
							|  |  |  |         all[1][1].sort() | 
					
						
							|  |  |  |         self.assertEqual(all[1], self.sub2_tree) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_walk_bottom_up(self): | 
					
						
							|  |  |  |         self.setUpWalk() | 
					
						
							|  |  |  |         seen_testfn = seen_sub1 = seen_sub11 = seen_sub2 = False | 
					
						
							|  |  |  |         for path, dirnames, filenames in self.walk_path.walk(top_down=False): | 
					
						
							|  |  |  |             if path == self.walk_path: | 
					
						
							|  |  |  |                 self.assertFalse(seen_testfn) | 
					
						
							|  |  |  |                 self.assertTrue(seen_sub1) | 
					
						
							|  |  |  |                 self.assertTrue(seen_sub2) | 
					
						
							|  |  |  |                 self.assertEqual(sorted(dirnames), ["SUB1", "SUB2"]) | 
					
						
							|  |  |  |                 self.assertEqual(filenames, ["tmp1"]) | 
					
						
							|  |  |  |                 seen_testfn = True | 
					
						
							|  |  |  |             elif path == self.sub1_path: | 
					
						
							|  |  |  |                 self.assertFalse(seen_testfn) | 
					
						
							|  |  |  |                 self.assertFalse(seen_sub1) | 
					
						
							|  |  |  |                 self.assertTrue(seen_sub11) | 
					
						
							|  |  |  |                 self.assertEqual(dirnames, ["SUB11"]) | 
					
						
							|  |  |  |                 self.assertEqual(filenames, ["tmp2"]) | 
					
						
							|  |  |  |                 seen_sub1 = True | 
					
						
							|  |  |  |             elif path == self.sub11_path: | 
					
						
							|  |  |  |                 self.assertFalse(seen_sub1) | 
					
						
							|  |  |  |                 self.assertFalse(seen_sub11) | 
					
						
							|  |  |  |                 self.assertEqual(dirnames, []) | 
					
						
							|  |  |  |                 self.assertEqual(filenames, []) | 
					
						
							|  |  |  |                 seen_sub11 = True | 
					
						
							|  |  |  |             elif path == self.sub2_path: | 
					
						
							|  |  |  |                 self.assertFalse(seen_testfn) | 
					
						
							|  |  |  |                 self.assertFalse(seen_sub2) | 
					
						
							|  |  |  |                 self.assertEqual(sorted(dirnames), sorted(self.sub2_tree[1])) | 
					
						
							|  |  |  |                 self.assertEqual(sorted(filenames), sorted(self.sub2_tree[2])) | 
					
						
							|  |  |  |                 seen_sub2 = True | 
					
						
							|  |  |  |             else: | 
					
						
							|  |  |  |                 raise AssertionError(f"Unexpected path: {path}") | 
					
						
							|  |  |  |         self.assertTrue(seen_testfn) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-01-26 22:29:28 +00:00
										 |  |  |     @needs_symlinks | 
					
						
							| 
									
										
										
										
											2023-12-16 19:04:33 +00:00
										 |  |  |     def test_walk_follow_symlinks(self): | 
					
						
							|  |  |  |         self.setUpWalk() | 
					
						
							|  |  |  |         walk_it = self.walk_path.walk(follow_symlinks=True) | 
					
						
							|  |  |  |         for root, dirs, files in walk_it: | 
					
						
							|  |  |  |             if root == self.link_path: | 
					
						
							|  |  |  |                 self.assertEqual(dirs, []) | 
					
						
							|  |  |  |                 self.assertEqual(files, ["tmp4"]) | 
					
						
							|  |  |  |                 break | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             self.fail("Didn't follow symlink with follow_symlinks=True") | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-01-26 22:29:28 +00:00
										 |  |  |     @needs_symlinks | 
					
						
							| 
									
										
										
										
											2023-12-16 19:04:33 +00:00
										 |  |  |     def test_walk_symlink_location(self): | 
					
						
							|  |  |  |         self.setUpWalk() | 
					
						
							|  |  |  |         # Tests whether symlinks end up in filenames or dirnames depending | 
					
						
							|  |  |  |         # on the `follow_symlinks` argument. | 
					
						
							|  |  |  |         walk_it = self.walk_path.walk(follow_symlinks=False) | 
					
						
							|  |  |  |         for root, dirs, files in walk_it: | 
					
						
							|  |  |  |             if root == self.sub2_path: | 
					
						
							|  |  |  |                 self.assertIn("link", files) | 
					
						
							|  |  |  |                 break | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             self.fail("symlink not found") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         walk_it = self.walk_path.walk(follow_symlinks=True) | 
					
						
							|  |  |  |         for root, dirs, files in walk_it: | 
					
						
							|  |  |  |             if root == self.sub2_path: | 
					
						
							|  |  |  |                 self.assertIn("link", dirs) | 
					
						
							|  |  |  |                 break | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             self.fail("symlink not found") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class DummyPathWithSymlinks(DummyPath): | 
					
						
							| 
									
										
										
										
											2024-01-08 19:31:52 +00:00
										 |  |  |     __slots__ = () | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # Reduce symlink traversal limit to make tests run faster. | 
					
						
							|  |  |  |     _max_symlinks = 20 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-12-16 19:04:33 +00:00
										 |  |  |     def readlink(self): | 
					
						
							|  |  |  |         path = str(self.parent.resolve() / self.name) | 
					
						
							|  |  |  |         if path in self._symlinks: | 
					
						
							|  |  |  |             return self.with_segments(self._symlinks[path]) | 
					
						
							|  |  |  |         elif path in self._files or path in self._directories: | 
					
						
							|  |  |  |             raise OSError(errno.EINVAL, "Not a symlink", path) | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             raise FileNotFoundError(errno.ENOENT, "File not found", path) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def symlink_to(self, target, target_is_directory=False): | 
					
						
							|  |  |  |         self._directories[str(self.parent)].add(self.name) | 
					
						
							|  |  |  |         self._symlinks[str(self)] = str(target) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class DummyPathWithSymlinksTest(DummyPathTest): | 
					
						
							|  |  |  |     cls = DummyPathWithSymlinks | 
					
						
							|  |  |  |     can_symlink = True | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | if __name__ == "__main__": | 
					
						
							|  |  |  |     unittest.main() |