1212"""
1313
1414import functools
15- import posixpath
15+ from abc import ABC , abstractmethod
1616from glob import _PathGlobber , _no_recurse_symlinks
17+ from pathlib import PurePath , Path
1718from pathlib ._os import magic_open , CopyReader , CopyWriter
1819
1920
@@ -39,24 +40,32 @@ def _explode_path(path):
3940 return path , names
4041
4142
42- class JoinablePath :
43- """Base class for pure path objects.
43+ class JoinablePath ( ABC ) :
44+ """Abstract base class for pure path objects.
4445
4546 This class *does not* provide several magic methods that are defined in
46- its subclass PurePath. They are: __init__, __fspath__, __bytes__,
47+ its implementation PurePath. They are: __init__, __fspath__, __bytes__,
4748 __reduce__, __hash__, __eq__, __lt__, __le__, __gt__, __ge__.
4849 """
49-
5050 __slots__ = ()
51- parser = posixpath
5251
52+ @property
53+ @abstractmethod
54+ def parser (self ):
55+ """Implementation of pathlib._types.Parser used for low-level path
56+ parsing and manipulation.
57+ """
58+ raise NotImplementedError
59+
60+ @abstractmethod
5361 def with_segments (self , * pathsegments ):
5462 """Construct a new path object from any number of path-like objects.
5563 Subclasses may override this method to customize how new path objects
5664 are created from methods like `iterdir()`.
5765 """
5866 raise NotImplementedError
5967
68+ @abstractmethod
6069 def __str__ (self ):
6170 """Return the string representation of the path, suitable for
6271 passing to system calls."""
@@ -198,23 +207,17 @@ def full_match(self, pattern, *, case_sensitive=None):
198207 return match (str (self )) is not None
199208
200209
201-
202210class ReadablePath (JoinablePath ):
203- """Base class for concrete path objects.
211+ """Abstract base class for readable path objects.
204212
205- This class provides dummy implementations for many methods that derived
206- classes can override selectively; the default implementations raise
207- NotImplementedError. The most basic methods, such as stat() and open(),
208- directly raise NotImplementedError; these basic methods are called by
209- other methods such as is_dir() and read_text().
210-
211- The Path class derives this class to implement local filesystem paths.
212- Users may derive their own classes to implement virtual filesystem paths,
213- such as paths in archive files or on remote storage systems.
213+ The Path class implements this ABC for local filesystem paths. Users may
214+ create subclasses to implement readable virtual filesystem paths, such as
215+ paths in archive files or on remote storage systems.
214216 """
215217 __slots__ = ()
216218
217219 @property
220+ @abstractmethod
218221 def info (self ):
219222 """
220223 A PathInfo object that exposes the file type and other file attributes
@@ -254,6 +257,7 @@ def is_symlink(self):
254257 info = self .joinpath ().info
255258 return info .is_symlink ()
256259
260+ @abstractmethod
257261 def __open_rb__ (self , buffering = - 1 ):
258262 """
259263 Open the file pointed to by this path for reading in binary mode and
@@ -275,6 +279,7 @@ def read_text(self, encoding=None, errors=None, newline=None):
275279 with magic_open (self , mode = 'r' , encoding = encoding , errors = errors , newline = newline ) as f :
276280 return f .read ()
277281
282+ @abstractmethod
278283 def iterdir (self ):
279284 """Yield path objects of the directory contents.
280285
@@ -348,6 +353,7 @@ def walk(self, top_down=True, on_error=None, follow_symlinks=False):
348353 yield path , dirnames , filenames
349354 paths += [path .joinpath (d ) for d in reversed (dirnames )]
350355
356+ @abstractmethod
351357 def readlink (self ):
352358 """
353359 Return the path to which the symbolic link points.
@@ -389,21 +395,30 @@ def copy_into(self, target_dir, *, follow_symlinks=True,
389395
390396
391397class WritablePath (JoinablePath ):
398+ """Abstract base class for writable path objects.
399+
400+ The Path class implements this ABC for local filesystem paths. Users may
401+ create subclasses to implement writable virtual filesystem paths, such as
402+ paths in archive files or on remote storage systems.
403+ """
392404 __slots__ = ()
393405
406+ @abstractmethod
394407 def symlink_to (self , target , target_is_directory = False ):
395408 """
396409 Make this path a symlink pointing to the target path.
397410 Note the order of arguments (link, target) is the reverse of os.symlink.
398411 """
399412 raise NotImplementedError
400413
414+ @abstractmethod
401415 def mkdir (self , mode = 0o777 , parents = False , exist_ok = False ):
402416 """
403417 Create a new directory at this given path.
404418 """
405419 raise NotImplementedError
406420
421+ @abstractmethod
407422 def __open_wb__ (self , buffering = - 1 ):
408423 """
409424 Open the file pointed to by this path for writing in binary mode and
@@ -431,3 +446,8 @@ def write_text(self, data, encoding=None, errors=None, newline=None):
431446 return f .write (data )
432447
433448 _copy_writer = property (CopyWriter )
449+
450+
451+ JoinablePath .register (PurePath )
452+ ReadablePath .register (Path )
453+ WritablePath .register (Path )
0 commit comments