mirror of
https://github.com/python/cpython.git
synced 2025-07-28 13:44:43 +00:00
GH-110109: Churn pathlib.PurePath
methods (#112012)
Re-arrange `pathlib.PurePath` methods in source code. No other changes.
The `PurePath` implementations of certain special methods, such as
`__eq__()` and `__hash__()`, are not usually applicable to user subclasses
of `_PathBase`. To facilitate their removal, another patch will split the
`PurePath` class into `_PurePathBase` and `PurePath`, with the latter
providing these special methods.
This patch prepares the ground for splitting `PurePath`. It's similar to
e8d77b0
, which preceded splitting `Path`. By churning the methods here,
subsequent patches will be easier to review and less likely to break
things.
This commit is contained in:
parent
7c50800241
commit
2dbb2e035b
2 changed files with 204 additions and 204 deletions
240
Lib/pathlib.py
240
Lib/pathlib.py
|
@ -246,44 +246,6 @@ class PurePath:
|
||||||
)
|
)
|
||||||
pathmod = os.path
|
pathmod = os.path
|
||||||
|
|
||||||
def __new__(cls, *args, **kwargs):
|
|
||||||
"""Construct a PurePath from one or several strings and or existing
|
|
||||||
PurePath objects. The strings and path objects are combined so as
|
|
||||||
to yield a canonicalized path, which is incorporated into the
|
|
||||||
new PurePath object.
|
|
||||||
"""
|
|
||||||
if cls is PurePath:
|
|
||||||
cls = PureWindowsPath if os.name == 'nt' else PurePosixPath
|
|
||||||
return object.__new__(cls)
|
|
||||||
|
|
||||||
def __reduce__(self):
|
|
||||||
# Using the parts tuple helps share interned path parts
|
|
||||||
# when pickling related paths.
|
|
||||||
return (self.__class__, self.parts)
|
|
||||||
|
|
||||||
def __init__(self, *args):
|
|
||||||
paths = []
|
|
||||||
for arg in args:
|
|
||||||
if isinstance(arg, PurePath):
|
|
||||||
if arg.pathmod is ntpath and self.pathmod is posixpath:
|
|
||||||
# GH-103631: Convert separators for backwards compatibility.
|
|
||||||
paths.extend(path.replace('\\', '/') for path in arg._raw_paths)
|
|
||||||
else:
|
|
||||||
paths.extend(arg._raw_paths)
|
|
||||||
else:
|
|
||||||
try:
|
|
||||||
path = os.fspath(arg)
|
|
||||||
except TypeError:
|
|
||||||
path = arg
|
|
||||||
if not isinstance(path, str):
|
|
||||||
raise TypeError(
|
|
||||||
"argument should be a str or an os.PathLike "
|
|
||||||
"object where __fspath__ returns a str, "
|
|
||||||
f"not {type(path).__name__!r}")
|
|
||||||
paths.append(path)
|
|
||||||
self._raw_paths = paths
|
|
||||||
self._resolving = False
|
|
||||||
|
|
||||||
def with_segments(self, *pathsegments):
|
def with_segments(self, *pathsegments):
|
||||||
"""Construct a new path object from any number of path-like objects.
|
"""Construct a new path object from any number of path-like objects.
|
||||||
Subclasses may override this method to customize how new path objects
|
Subclasses may override this method to customize how new path objects
|
||||||
|
@ -351,96 +313,14 @@ class PurePath:
|
||||||
self._tail) or '.'
|
self._tail) or '.'
|
||||||
return self._str
|
return self._str
|
||||||
|
|
||||||
def __fspath__(self):
|
|
||||||
return str(self)
|
|
||||||
|
|
||||||
def as_posix(self):
|
def as_posix(self):
|
||||||
"""Return the string representation of the path with forward (/)
|
"""Return the string representation of the path with forward (/)
|
||||||
slashes."""
|
slashes."""
|
||||||
return str(self).replace(self.pathmod.sep, '/')
|
return str(self).replace(self.pathmod.sep, '/')
|
||||||
|
|
||||||
def __bytes__(self):
|
|
||||||
"""Return the bytes representation of the path. This is only
|
|
||||||
recommended to use under Unix."""
|
|
||||||
return os.fsencode(self)
|
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return "{}({!r})".format(self.__class__.__name__, self.as_posix())
|
return "{}({!r})".format(self.__class__.__name__, self.as_posix())
|
||||||
|
|
||||||
def as_uri(self):
|
|
||||||
"""Return the path as a URI."""
|
|
||||||
if not self.is_absolute():
|
|
||||||
raise ValueError("relative path can't be expressed as a file URI")
|
|
||||||
|
|
||||||
drive = self.drive
|
|
||||||
if len(drive) == 2 and drive[1] == ':':
|
|
||||||
# It's a path on a local drive => 'file:///c:/a/b'
|
|
||||||
prefix = 'file:///' + drive
|
|
||||||
path = self.as_posix()[2:]
|
|
||||||
elif drive:
|
|
||||||
# It's a path on a network drive => 'file://host/share/a/b'
|
|
||||||
prefix = 'file:'
|
|
||||||
path = self.as_posix()
|
|
||||||
else:
|
|
||||||
# It's a posix path => 'file:///etc/hosts'
|
|
||||||
prefix = 'file://'
|
|
||||||
path = str(self)
|
|
||||||
from urllib.parse import quote_from_bytes
|
|
||||||
return prefix + quote_from_bytes(os.fsencode(path))
|
|
||||||
|
|
||||||
@property
|
|
||||||
def _str_normcase(self):
|
|
||||||
# String with normalized case, for hashing and equality checks
|
|
||||||
try:
|
|
||||||
return self._str_normcase_cached
|
|
||||||
except AttributeError:
|
|
||||||
if _is_case_sensitive(self.pathmod):
|
|
||||||
self._str_normcase_cached = str(self)
|
|
||||||
else:
|
|
||||||
self._str_normcase_cached = str(self).lower()
|
|
||||||
return self._str_normcase_cached
|
|
||||||
|
|
||||||
@property
|
|
||||||
def _parts_normcase(self):
|
|
||||||
# Cached parts with normalized case, for comparisons.
|
|
||||||
try:
|
|
||||||
return self._parts_normcase_cached
|
|
||||||
except AttributeError:
|
|
||||||
self._parts_normcase_cached = self._str_normcase.split(self.pathmod.sep)
|
|
||||||
return self._parts_normcase_cached
|
|
||||||
|
|
||||||
def __eq__(self, other):
|
|
||||||
if not isinstance(other, PurePath):
|
|
||||||
return NotImplemented
|
|
||||||
return self._str_normcase == other._str_normcase and self.pathmod is other.pathmod
|
|
||||||
|
|
||||||
def __hash__(self):
|
|
||||||
try:
|
|
||||||
return self._hash
|
|
||||||
except AttributeError:
|
|
||||||
self._hash = hash(self._str_normcase)
|
|
||||||
return self._hash
|
|
||||||
|
|
||||||
def __lt__(self, other):
|
|
||||||
if not isinstance(other, PurePath) or self.pathmod is not other.pathmod:
|
|
||||||
return NotImplemented
|
|
||||||
return self._parts_normcase < other._parts_normcase
|
|
||||||
|
|
||||||
def __le__(self, other):
|
|
||||||
if not isinstance(other, PurePath) or self.pathmod is not other.pathmod:
|
|
||||||
return NotImplemented
|
|
||||||
return self._parts_normcase <= other._parts_normcase
|
|
||||||
|
|
||||||
def __gt__(self, other):
|
|
||||||
if not isinstance(other, PurePath) or self.pathmod is not other.pathmod:
|
|
||||||
return NotImplemented
|
|
||||||
return self._parts_normcase > other._parts_normcase
|
|
||||||
|
|
||||||
def __ge__(self, other):
|
|
||||||
if not isinstance(other, PurePath) or self.pathmod is not other.pathmod:
|
|
||||||
return NotImplemented
|
|
||||||
return self._parts_normcase >= other._parts_normcase
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def drive(self):
|
def drive(self):
|
||||||
"""The drive prefix (letter or UNC path), if any."""
|
"""The drive prefix (letter or UNC path), if any."""
|
||||||
|
@ -694,6 +574,126 @@ class PurePath:
|
||||||
match = _compile_pattern(pattern_str, sep, case_sensitive)
|
match = _compile_pattern(pattern_str, sep, case_sensitive)
|
||||||
return match(str(self)) is not None
|
return match(str(self)) is not None
|
||||||
|
|
||||||
|
def __new__(cls, *args, **kwargs):
|
||||||
|
"""Construct a PurePath from one or several strings and or existing
|
||||||
|
PurePath objects. The strings and path objects are combined so as
|
||||||
|
to yield a canonicalized path, which is incorporated into the
|
||||||
|
new PurePath object.
|
||||||
|
"""
|
||||||
|
if cls is PurePath:
|
||||||
|
cls = PureWindowsPath if os.name == 'nt' else PurePosixPath
|
||||||
|
return object.__new__(cls)
|
||||||
|
|
||||||
|
def __init__(self, *args):
|
||||||
|
paths = []
|
||||||
|
for arg in args:
|
||||||
|
if isinstance(arg, PurePath):
|
||||||
|
if arg.pathmod is ntpath and self.pathmod is posixpath:
|
||||||
|
# GH-103631: Convert separators for backwards compatibility.
|
||||||
|
paths.extend(path.replace('\\', '/') for path in arg._raw_paths)
|
||||||
|
else:
|
||||||
|
paths.extend(arg._raw_paths)
|
||||||
|
else:
|
||||||
|
try:
|
||||||
|
path = os.fspath(arg)
|
||||||
|
except TypeError:
|
||||||
|
path = arg
|
||||||
|
if not isinstance(path, str):
|
||||||
|
raise TypeError(
|
||||||
|
"argument should be a str or an os.PathLike "
|
||||||
|
"object where __fspath__ returns a str, "
|
||||||
|
f"not {type(path).__name__!r}")
|
||||||
|
paths.append(path)
|
||||||
|
self._raw_paths = paths
|
||||||
|
self._resolving = False
|
||||||
|
|
||||||
|
def __reduce__(self):
|
||||||
|
# Using the parts tuple helps share interned path parts
|
||||||
|
# when pickling related paths.
|
||||||
|
return (self.__class__, self.parts)
|
||||||
|
|
||||||
|
def __fspath__(self):
|
||||||
|
return str(self)
|
||||||
|
|
||||||
|
def __bytes__(self):
|
||||||
|
"""Return the bytes representation of the path. This is only
|
||||||
|
recommended to use under Unix."""
|
||||||
|
return os.fsencode(self)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def _str_normcase(self):
|
||||||
|
# String with normalized case, for hashing and equality checks
|
||||||
|
try:
|
||||||
|
return self._str_normcase_cached
|
||||||
|
except AttributeError:
|
||||||
|
if _is_case_sensitive(self.pathmod):
|
||||||
|
self._str_normcase_cached = str(self)
|
||||||
|
else:
|
||||||
|
self._str_normcase_cached = str(self).lower()
|
||||||
|
return self._str_normcase_cached
|
||||||
|
|
||||||
|
def __hash__(self):
|
||||||
|
try:
|
||||||
|
return self._hash
|
||||||
|
except AttributeError:
|
||||||
|
self._hash = hash(self._str_normcase)
|
||||||
|
return self._hash
|
||||||
|
|
||||||
|
def __eq__(self, other):
|
||||||
|
if not isinstance(other, PurePath):
|
||||||
|
return NotImplemented
|
||||||
|
return self._str_normcase == other._str_normcase and self.pathmod is other.pathmod
|
||||||
|
|
||||||
|
@property
|
||||||
|
def _parts_normcase(self):
|
||||||
|
# Cached parts with normalized case, for comparisons.
|
||||||
|
try:
|
||||||
|
return self._parts_normcase_cached
|
||||||
|
except AttributeError:
|
||||||
|
self._parts_normcase_cached = self._str_normcase.split(self.pathmod.sep)
|
||||||
|
return self._parts_normcase_cached
|
||||||
|
|
||||||
|
def __lt__(self, other):
|
||||||
|
if not isinstance(other, PurePath) or self.pathmod is not other.pathmod:
|
||||||
|
return NotImplemented
|
||||||
|
return self._parts_normcase < other._parts_normcase
|
||||||
|
|
||||||
|
def __le__(self, other):
|
||||||
|
if not isinstance(other, PurePath) or self.pathmod is not other.pathmod:
|
||||||
|
return NotImplemented
|
||||||
|
return self._parts_normcase <= other._parts_normcase
|
||||||
|
|
||||||
|
def __gt__(self, other):
|
||||||
|
if not isinstance(other, PurePath) or self.pathmod is not other.pathmod:
|
||||||
|
return NotImplemented
|
||||||
|
return self._parts_normcase > other._parts_normcase
|
||||||
|
|
||||||
|
def __ge__(self, other):
|
||||||
|
if not isinstance(other, PurePath) or self.pathmod is not other.pathmod:
|
||||||
|
return NotImplemented
|
||||||
|
return self._parts_normcase >= other._parts_normcase
|
||||||
|
|
||||||
|
def as_uri(self):
|
||||||
|
"""Return the path as a URI."""
|
||||||
|
if not self.is_absolute():
|
||||||
|
raise ValueError("relative path can't be expressed as a file URI")
|
||||||
|
|
||||||
|
drive = self.drive
|
||||||
|
if len(drive) == 2 and drive[1] == ':':
|
||||||
|
# It's a path on a local drive => 'file:///c:/a/b'
|
||||||
|
prefix = 'file:///' + drive
|
||||||
|
path = self.as_posix()[2:]
|
||||||
|
elif drive:
|
||||||
|
# It's a path on a network drive => 'file://host/share/a/b'
|
||||||
|
prefix = 'file:'
|
||||||
|
path = self.as_posix()
|
||||||
|
else:
|
||||||
|
# It's a posix path => 'file:///etc/hosts'
|
||||||
|
prefix = 'file://'
|
||||||
|
path = str(self)
|
||||||
|
from urllib.parse import quote_from_bytes
|
||||||
|
return prefix + quote_from_bytes(os.fsencode(path))
|
||||||
|
|
||||||
|
|
||||||
# Subclassing os.PathLike makes isinstance() checks slower,
|
# Subclassing os.PathLike makes isinstance() checks slower,
|
||||||
# which in turn makes Path construction slower. Register instead!
|
# which in turn makes Path construction slower. Register instead!
|
||||||
|
|
|
@ -117,33 +117,6 @@ class PurePathTest(unittest.TestCase):
|
||||||
with self.assertRaises(TypeError):
|
with self.assertRaises(TypeError):
|
||||||
p >= q
|
p >= q
|
||||||
|
|
||||||
def test_bytes(self):
|
|
||||||
P = self.cls
|
|
||||||
message = (r"argument should be a str or an os\.PathLike object "
|
|
||||||
r"where __fspath__ returns a str, not 'bytes'")
|
|
||||||
with self.assertRaisesRegex(TypeError, message):
|
|
||||||
P(b'a')
|
|
||||||
with self.assertRaisesRegex(TypeError, message):
|
|
||||||
P(b'a', 'b')
|
|
||||||
with self.assertRaisesRegex(TypeError, message):
|
|
||||||
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')
|
|
||||||
|
|
||||||
def _check_str_subclass(self, *args):
|
def _check_str_subclass(self, *args):
|
||||||
# Issue #21127: it should be possible to construct a PurePath object
|
# Issue #21127: it should be possible to construct a PurePath object
|
||||||
# from a str subclass instance, and it then gets converted to
|
# from a str subclass instance, and it then gets converted to
|
||||||
|
@ -273,18 +246,6 @@ class PurePathTest(unittest.TestCase):
|
||||||
self.assertEqual(P(pathstr).as_posix(), pathstr)
|
self.assertEqual(P(pathstr).as_posix(), pathstr)
|
||||||
# Other tests for as_posix() are in test_equivalences().
|
# Other tests for as_posix() are in test_equivalences().
|
||||||
|
|
||||||
def test_as_bytes_common(self):
|
|
||||||
sep = os.fsencode(self.sep)
|
|
||||||
P = self.cls
|
|
||||||
self.assertEqual(bytes(P('a/b')), b'a' + sep + b'b')
|
|
||||||
|
|
||||||
def test_as_uri_common(self):
|
|
||||||
P = self.cls
|
|
||||||
with self.assertRaises(ValueError):
|
|
||||||
P('a').as_uri()
|
|
||||||
with self.assertRaises(ValueError):
|
|
||||||
P().as_uri()
|
|
||||||
|
|
||||||
def test_repr_common(self):
|
def test_repr_common(self):
|
||||||
for pathstr in ('a', 'a/b', 'a/b/c', '/', '/a/b', '/a/b/c'):
|
for pathstr in ('a', 'a/b', 'a/b/c', '/', '/a/b', '/a/b/c'):
|
||||||
with self.subTest(pathstr=pathstr):
|
with self.subTest(pathstr=pathstr):
|
||||||
|
@ -297,17 +258,6 @@ class PurePathTest(unittest.TestCase):
|
||||||
inner = r[len(clsname) + 1 : -1]
|
inner = r[len(clsname) + 1 : -1]
|
||||||
self.assertEqual(eval(inner), p.as_posix())
|
self.assertEqual(eval(inner), p.as_posix())
|
||||||
|
|
||||||
def test_repr_roundtrips(self):
|
|
||||||
for pathstr in ('a', 'a/b', 'a/b/c', '/', '/a/b', '/a/b/c'):
|
|
||||||
with self.subTest(pathstr=pathstr):
|
|
||||||
p = self.cls(pathstr)
|
|
||||||
r = repr(p)
|
|
||||||
# The repr() roundtrips.
|
|
||||||
q = eval(r, pathlib.__dict__)
|
|
||||||
self.assertIs(q.__class__, p.__class__)
|
|
||||||
self.assertEqual(q, p)
|
|
||||||
self.assertEqual(repr(q), r)
|
|
||||||
|
|
||||||
def test_eq_common(self):
|
def test_eq_common(self):
|
||||||
P = self.cls
|
P = self.cls
|
||||||
self.assertEqual(P('a/b'), P('a/b'))
|
self.assertEqual(P('a/b'), P('a/b'))
|
||||||
|
@ -390,34 +340,6 @@ class PurePathTest(unittest.TestCase):
|
||||||
self.assertTrue(P().match('**'))
|
self.assertTrue(P().match('**'))
|
||||||
self.assertFalse(P().match('**/*'))
|
self.assertFalse(P().match('**/*'))
|
||||||
|
|
||||||
def test_ordering_common(self):
|
|
||||||
# Ordering is tuple-alike.
|
|
||||||
def assertLess(a, b):
|
|
||||||
self.assertLess(a, b)
|
|
||||||
self.assertGreater(b, a)
|
|
||||||
P = self.cls
|
|
||||||
a = P('a')
|
|
||||||
b = P('a/b')
|
|
||||||
c = P('abc')
|
|
||||||
d = P('b')
|
|
||||||
assertLess(a, b)
|
|
||||||
assertLess(a, c)
|
|
||||||
assertLess(a, d)
|
|
||||||
assertLess(b, c)
|
|
||||||
assertLess(c, d)
|
|
||||||
P = self.cls
|
|
||||||
a = P('/a')
|
|
||||||
b = P('/a/b')
|
|
||||||
c = P('/abc')
|
|
||||||
d = P('/b')
|
|
||||||
assertLess(a, b)
|
|
||||||
assertLess(a, c)
|
|
||||||
assertLess(a, d)
|
|
||||||
assertLess(b, c)
|
|
||||||
assertLess(c, d)
|
|
||||||
with self.assertRaises(TypeError):
|
|
||||||
P() < {}
|
|
||||||
|
|
||||||
def test_parts_common(self):
|
def test_parts_common(self):
|
||||||
# `parts` returns a tuple.
|
# `parts` returns a tuple.
|
||||||
sep = self.sep
|
sep = self.sep
|
||||||
|
@ -430,12 +352,6 @@ class PurePathTest(unittest.TestCase):
|
||||||
parts = p.parts
|
parts = p.parts
|
||||||
self.assertEqual(parts, (sep, 'a', 'b'))
|
self.assertEqual(parts, (sep, 'a', 'b'))
|
||||||
|
|
||||||
def test_fspath_common(self):
|
|
||||||
P = self.cls
|
|
||||||
p = P('a/b')
|
|
||||||
self._check_str(p.__fspath__(), ('a/b',))
|
|
||||||
self._check_str(os.fspath(p), ('a/b',))
|
|
||||||
|
|
||||||
def test_equivalences(self):
|
def test_equivalences(self):
|
||||||
for k, tuples in self.equivalences.items():
|
for k, tuples in self.equivalences.items():
|
||||||
canon = k.replace('/', self.sep)
|
canon = k.replace('/', self.sep)
|
||||||
|
@ -787,6 +703,90 @@ class PurePathTest(unittest.TestCase):
|
||||||
self.assertEqual(hash(pp), hash(p))
|
self.assertEqual(hash(pp), hash(p))
|
||||||
self.assertEqual(str(pp), str(p))
|
self.assertEqual(str(pp), str(p))
|
||||||
|
|
||||||
|
def test_fspath_common(self):
|
||||||
|
P = self.cls
|
||||||
|
p = P('a/b')
|
||||||
|
self._check_str(p.__fspath__(), ('a/b',))
|
||||||
|
self._check_str(os.fspath(p), ('a/b',))
|
||||||
|
|
||||||
|
def test_bytes(self):
|
||||||
|
P = self.cls
|
||||||
|
message = (r"argument should be a str or an os\.PathLike object "
|
||||||
|
r"where __fspath__ returns a str, not 'bytes'")
|
||||||
|
with self.assertRaisesRegex(TypeError, message):
|
||||||
|
P(b'a')
|
||||||
|
with self.assertRaisesRegex(TypeError, message):
|
||||||
|
P(b'a', 'b')
|
||||||
|
with self.assertRaisesRegex(TypeError, message):
|
||||||
|
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')
|
||||||
|
|
||||||
|
def test_as_bytes_common(self):
|
||||||
|
sep = os.fsencode(self.sep)
|
||||||
|
P = self.cls
|
||||||
|
self.assertEqual(bytes(P('a/b')), b'a' + sep + b'b')
|
||||||
|
|
||||||
|
def test_ordering_common(self):
|
||||||
|
# Ordering is tuple-alike.
|
||||||
|
def assertLess(a, b):
|
||||||
|
self.assertLess(a, b)
|
||||||
|
self.assertGreater(b, a)
|
||||||
|
P = self.cls
|
||||||
|
a = P('a')
|
||||||
|
b = P('a/b')
|
||||||
|
c = P('abc')
|
||||||
|
d = P('b')
|
||||||
|
assertLess(a, b)
|
||||||
|
assertLess(a, c)
|
||||||
|
assertLess(a, d)
|
||||||
|
assertLess(b, c)
|
||||||
|
assertLess(c, d)
|
||||||
|
P = self.cls
|
||||||
|
a = P('/a')
|
||||||
|
b = P('/a/b')
|
||||||
|
c = P('/abc')
|
||||||
|
d = P('/b')
|
||||||
|
assertLess(a, b)
|
||||||
|
assertLess(a, c)
|
||||||
|
assertLess(a, d)
|
||||||
|
assertLess(b, c)
|
||||||
|
assertLess(c, d)
|
||||||
|
with self.assertRaises(TypeError):
|
||||||
|
P() < {}
|
||||||
|
|
||||||
|
def test_as_uri_common(self):
|
||||||
|
P = self.cls
|
||||||
|
with self.assertRaises(ValueError):
|
||||||
|
P('a').as_uri()
|
||||||
|
with self.assertRaises(ValueError):
|
||||||
|
P().as_uri()
|
||||||
|
|
||||||
|
def test_repr_roundtrips(self):
|
||||||
|
for pathstr in ('a', 'a/b', 'a/b/c', '/', '/a/b', '/a/b/c'):
|
||||||
|
with self.subTest(pathstr=pathstr):
|
||||||
|
p = self.cls(pathstr)
|
||||||
|
r = repr(p)
|
||||||
|
# The repr() roundtrips.
|
||||||
|
q = eval(r, pathlib.__dict__)
|
||||||
|
self.assertIs(q.__class__, p.__class__)
|
||||||
|
self.assertEqual(q, p)
|
||||||
|
self.assertEqual(repr(q), r)
|
||||||
|
|
||||||
|
|
||||||
class PurePosixPathTest(PurePathTest):
|
class PurePosixPathTest(PurePathTest):
|
||||||
cls = pathlib.PurePosixPath
|
cls = pathlib.PurePosixPath
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue