Closed barneygale closed 6 months ago
I've spent some time playing around with the above implementation sketch (i.e. making PurePathBase
methods abstract, and moving pathmod
into PurePath
), and it feels pretty gross. The problem comes with mixing two mostly-independent ideas (syntax and I/O impl) in the same class hierarchy.
On reflection it seems obvious we should favour composition over inheritance; the bit I was missing is that we need to provide an abstract version of PurePathBase.pathmod
, roughly:
class PathModuleBase:
@classmethod
def _unsupported(cls, attr):
raise UnsupportedOperation(f"{cls.__name__}.{attr} is unsupported")
@property
def sep(self):
return self._unsupported('sep')
@property
def altsep(self):
return self._unsupported('altsep')
def normcase(self, path):
return self._unsupported('normcase()')
def isabs(self, path):
return self._unsupported('isabs()')
def join(self, path, *paths):
return self._unsupported('join()')
def split(self, path):
return self._unsupported('split()')
def splitroot(self, path):
return self._unsupported('splitroot()')
def splitdrive(self, path):
drive, root, rel = self.splitroot(path)
return drive, root + rel
def dirname(self, path):
return self.split(path)[0]
def basename(self, path):
return self.split(path)[1]
Thus user subclasses of PurePathBase
and PathBase
would be able to set the pathmod
class attribute to posixpath
, ntpath
, os.path
, or their own subclass of PathModuleBase
if they need fine-grained control over syntax.
This should be doable once #10 and #13 are resolved.
It should be possible to make path syntax and normalization more customizable. Very rough plan:
PurePathBase.pathmod
toPurePath.pathmod
drive
androot
?PurePathbase.is_absolute()
andis_reserved()
abstract (or returnFalse
?), move existing implementations toPurePath
is_case_sensitive()
abstract method (or class attribute, likesep
below?)PurePathBase.sep
andaltsep
attributes (defaults"/"
andNone
?)