Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 2dbb2e0

Browse filesBrowse files
authored
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.
1 parent 7c50800 commit 2dbb2e0
Copy full SHA for 2dbb2e0

File tree

2 files changed

+204
-204
lines changed
Filter options

2 files changed

+204
-204
lines changed

‎Lib/pathlib.py

Copy file name to clipboardExpand all lines: Lib/pathlib.py
+120-120Lines changed: 120 additions & 120 deletions
Original file line numberDiff line numberDiff line change
@@ -246,44 +246,6 @@ class PurePath:
246246
)
247247
pathmod = os.path
248248

249-
def __new__(cls, *args, **kwargs):
250-
"""Construct a PurePath from one or several strings and or existing
251-
PurePath objects. The strings and path objects are combined so as
252-
to yield a canonicalized path, which is incorporated into the
253-
new PurePath object.
254-
"""
255-
if cls is PurePath:
256-
cls = PureWindowsPath if os.name == 'nt' else PurePosixPath
257-
return object.__new__(cls)
258-
259-
def __reduce__(self):
260-
# Using the parts tuple helps share interned path parts
261-
# when pickling related paths.
262-
return (self.__class__, self.parts)
263-
264-
def __init__(self, *args):
265-
paths = []
266-
for arg in args:
267-
if isinstance(arg, PurePath):
268-
if arg.pathmod is ntpath and self.pathmod is posixpath:
269-
# GH-103631: Convert separators for backwards compatibility.
270-
paths.extend(path.replace('\\', '/') for path in arg._raw_paths)
271-
else:
272-
paths.extend(arg._raw_paths)
273-
else:
274-
try:
275-
path = os.fspath(arg)
276-
except TypeError:
277-
path = arg
278-
if not isinstance(path, str):
279-
raise TypeError(
280-
"argument should be a str or an os.PathLike "
281-
"object where __fspath__ returns a str, "
282-
f"not {type(path).__name__!r}")
283-
paths.append(path)
284-
self._raw_paths = paths
285-
self._resolving = False
286-
287249
def with_segments(self, *pathsegments):
288250
"""Construct a new path object from any number of path-like objects.
289251
Subclasses may override this method to customize how new path objects
@@ -351,96 +313,14 @@ def __str__(self):
351313
self._tail) or '.'
352314
return self._str
353315

354-
def __fspath__(self):
355-
return str(self)
356-
357316
def as_posix(self):
358317
"""Return the string representation of the path with forward (/)
359318
slashes."""
360319
return str(self).replace(self.pathmod.sep, '/')
361320

362-
def __bytes__(self):
363-
"""Return the bytes representation of the path. This is only
364-
recommended to use under Unix."""
365-
return os.fsencode(self)
366-
367321
def __repr__(self):
368322
return "{}({!r})".format(self.__class__.__name__, self.as_posix())
369323

370-
def as_uri(self):
371-
"""Return the path as a URI."""
372-
if not self.is_absolute():
373-
raise ValueError("relative path can't be expressed as a file URI")
374-
375-
drive = self.drive
376-
if len(drive) == 2 and drive[1] == ':':
377-
# It's a path on a local drive => 'file:///c:/a/b'
378-
prefix = 'file:///' + drive
379-
path = self.as_posix()[2:]
380-
elif drive:
381-
# It's a path on a network drive => 'file://host/share/a/b'
382-
prefix = 'file:'
383-
path = self.as_posix()
384-
else:
385-
# It's a posix path => 'file:///etc/hosts'
386-
prefix = 'file://'
387-
path = str(self)
388-
from urllib.parse import quote_from_bytes
389-
return prefix + quote_from_bytes(os.fsencode(path))
390-
391-
@property
392-
def _str_normcase(self):
393-
# String with normalized case, for hashing and equality checks
394-
try:
395-
return self._str_normcase_cached
396-
except AttributeError:
397-
if _is_case_sensitive(self.pathmod):
398-
self._str_normcase_cached = str(self)
399-
else:
400-
self._str_normcase_cached = str(self).lower()
401-
return self._str_normcase_cached
402-
403-
@property
404-
def _parts_normcase(self):
405-
# Cached parts with normalized case, for comparisons.
406-
try:
407-
return self._parts_normcase_cached
408-
except AttributeError:
409-
self._parts_normcase_cached = self._str_normcase.split(self.pathmod.sep)
410-
return self._parts_normcase_cached
411-
412-
def __eq__(self, other):
413-
if not isinstance(other, PurePath):
414-
return NotImplemented
415-
return self._str_normcase == other._str_normcase and self.pathmod is other.pathmod
416-
417-
def __hash__(self):
418-
try:
419-
return self._hash
420-
except AttributeError:
421-
self._hash = hash(self._str_normcase)
422-
return self._hash
423-
424-
def __lt__(self, other):
425-
if not isinstance(other, PurePath) or self.pathmod is not other.pathmod:
426-
return NotImplemented
427-
return self._parts_normcase < other._parts_normcase
428-
429-
def __le__(self, other):
430-
if not isinstance(other, PurePath) or self.pathmod is not other.pathmod:
431-
return NotImplemented
432-
return self._parts_normcase <= other._parts_normcase
433-
434-
def __gt__(self, other):
435-
if not isinstance(other, PurePath) or self.pathmod is not other.pathmod:
436-
return NotImplemented
437-
return self._parts_normcase > other._parts_normcase
438-
439-
def __ge__(self, other):
440-
if not isinstance(other, PurePath) or self.pathmod is not other.pathmod:
441-
return NotImplemented
442-
return self._parts_normcase >= other._parts_normcase
443-
444324
@property
445325
def drive(self):
446326
"""The drive prefix (letter or UNC path), if any."""
@@ -694,6 +574,126 @@ def match(self, path_pattern, *, case_sensitive=None):
694574
match = _compile_pattern(pattern_str, sep, case_sensitive)
695575
return match(str(self)) is not None
696576

577+
def __new__(cls, *args, **kwargs):
578+
"""Construct a PurePath from one or several strings and or existing
579+
PurePath objects. The strings and path objects are combined so as
580+
to yield a canonicalized path, which is incorporated into the
581+
new PurePath object.
582+
"""
583+
if cls is PurePath:
584+
cls = PureWindowsPath if os.name == 'nt' else PurePosixPath
585+
return object.__new__(cls)
586+
587+
def __init__(self, *args):
588+
paths = []
589+
for arg in args:
590+
if isinstance(arg, PurePath):
591+
if arg.pathmod is ntpath and self.pathmod is posixpath:
592+
# GH-103631: Convert separators for backwards compatibility.
593+
paths.extend(path.replace('\\', '/') for path in arg._raw_paths)
594+
else:
595+
paths.extend(arg._raw_paths)
596+
else:
597+
try:
598+
path = os.fspath(arg)
599+
except TypeError:
600+
path = arg
601+
if not isinstance(path, str):
602+
raise TypeError(
603+
"argument should be a str or an os.PathLike "
604+
"object where __fspath__ returns a str, "
605+
f"not {type(path).__name__!r}")
606+
paths.append(path)
607+
self._raw_paths = paths
608+
self._resolving = False
609+
610+
def __reduce__(self):
611+
# Using the parts tuple helps share interned path parts
612+
# when pickling related paths.
613+
return (self.__class__, self.parts)
614+
615+
def __fspath__(self):
616+
return str(self)
617+
618+
def __bytes__(self):
619+
"""Return the bytes representation of the path. This is only
620+
recommended to use under Unix."""
621+
return os.fsencode(self)
622+
623+
@property
624+
def _str_normcase(self):
625+
# String with normalized case, for hashing and equality checks
626+
try:
627+
return self._str_normcase_cached
628+
except AttributeError:
629+
if _is_case_sensitive(self.pathmod):
630+
self._str_normcase_cached = str(self)
631+
else:
632+
self._str_normcase_cached = str(self).lower()
633+
return self._str_normcase_cached
634+
635+
def __hash__(self):
636+
try:
637+
return self._hash
638+
except AttributeError:
639+
self._hash = hash(self._str_normcase)
640+
return self._hash
641+
642+
def __eq__(self, other):
643+
if not isinstance(other, PurePath):
644+
return NotImplemented
645+
return self._str_normcase == other._str_normcase and self.pathmod is other.pathmod
646+
647+
@property
648+
def _parts_normcase(self):
649+
# Cached parts with normalized case, for comparisons.
650+
try:
651+
return self._parts_normcase_cached
652+
except AttributeError:
653+
self._parts_normcase_cached = self._str_normcase.split(self.pathmod.sep)
654+
return self._parts_normcase_cached
655+
656+
def __lt__(self, other):
657+
if not isinstance(other, PurePath) or self.pathmod is not other.pathmod:
658+
return NotImplemented
659+
return self._parts_normcase < other._parts_normcase
660+
661+
def __le__(self, other):
662+
if not isinstance(other, PurePath) or self.pathmod is not other.pathmod:
663+
return NotImplemented
664+
return self._parts_normcase <= other._parts_normcase
665+
666+
def __gt__(self, other):
667+
if not isinstance(other, PurePath) or self.pathmod is not other.pathmod:
668+
return NotImplemented
669+
return self._parts_normcase > other._parts_normcase
670+
671+
def __ge__(self, other):
672+
if not isinstance(other, PurePath) or self.pathmod is not other.pathmod:
673+
return NotImplemented
674+
return self._parts_normcase >= other._parts_normcase
675+
676+
def as_uri(self):
677+
"""Return the path as a URI."""
678+
if not self.is_absolute():
679+
raise ValueError("relative path can't be expressed as a file URI")
680+
681+
drive = self.drive
682+
if len(drive) == 2 and drive[1] == ':':
683+
# It's a path on a local drive => 'file:///c:/a/b'
684+
prefix = 'file:///' + drive
685+
path = self.as_posix()[2:]
686+
elif drive:
687+
# It's a path on a network drive => 'file://host/share/a/b'
688+
prefix = 'file:'
689+
path = self.as_posix()
690+
else:
691+
# It's a posix path => 'file:///etc/hosts'
692+
prefix = 'file://'
693+
path = str(self)
694+
from urllib.parse import quote_from_bytes
695+
return prefix + quote_from_bytes(os.fsencode(path))
696+
697697

698698
# Subclassing os.PathLike makes isinstance() checks slower,
699699
# which in turn makes Path construction slower. Register instead!

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.