[Nick] >>> Similarly, I would separate out the extension to a distinct >>> attribute, as it too uses a different separator from the normal path >>> elements ('.' most places, but '/' on RISC OS, for example)
[Greg] >> -1. What constitutes "the extension" is not well-defined in >> all cases. What about filenames with multiple suffixes, >> such as "spam.tar.gz"? What part of that would you put in >> the extension attribute? [Giovanni] > .gz of course: > > Path = "foo.tar.gz" > Path.ext = ".gz" > Path.name.ext = ".tar" > Path.name.name.ext = "" > > Which is exactly the *same* thing that os.path.splitext() does. And yes, I do > use splitext quite a lot. Remember, the idea with portable path information is to *never* store os.sep and os.extsep anywhere in the internal data - those should only be added when needed to produce strings to pass to OS-specific functions or to display to users. So I suggest splitting the internal data into 'path elements separated by os.sep', 'name elements separated by os.extsep' and 'the base path' (which can be any kind of object that supports __str__, including another path object). This leads to the following: import pathlib from pathlib import Path, PosixPath, WindowsPath, HOMEDIR pth = Path("~/foo/bar/baz.tar.gz"): assert pth.basepath == HOMEDIR assert pth.dirparts == ('foo', 'bar') assert pth.nameparts == ('baz', 'tar', 'gz') I would also provide an alternate constructor "from_parts" which looked like: pth = Path.from_parts(HOMEDIR, ('foo', 'bar'), ('baz', 'tar', 'gz')) Now consider PosixPath and WindowsPath subclasses: psx = PosixPath(pth) win = WindowsPath(pth) (platform specific Path variants would still accept posix-formatted path strings & other Path variants as inputs in addition to path strings formatted for the current platform) # Formatting of the prefix is platform dependent assert pth.prefix == str(pth.basepath) assert psx.prefix == "/home/nick/" assert win.prefix == r"C:\Documents and Settings\Nick\" # Formatting of the directory path is platform dependent assert pth.dir == os.sep.join(pth.dirparts + ('',)) assert psx.dir == "foo/bar/" assert win.dir == r"foo\bar\" # Formatting of the file name is the same on both platforms assert pth.name == os.extsep.join(pth.nameparts) assert psx.name == "baz.tar.gz" assert win.name == "baz.tar.gz" # The full path name will then also be platform dependent assert str(pth) == pth.prefix + pth.dir + pth.name assert str(psx) == "/home/nick/foo/bar/baz.tar.gz" assert str(win) == r"C:\Documents and Settings\Nick\foo\bar\baz.tar.gz" The separation of the directory parts and the name parts also allows the difference between "/foo/bar/" and "foo/bar" to be represented properly: pth1 = PosixPath("/foo/bar/") assert pth1.prefix = '/' assert pth1.dir == "foo/bar/" assert pth1.name == "" assert str(pth1) == "/foo/bar/" pth2 = PosixPath("/foo/bar") assert pth2.prefix = '/' assert pth2.dir == "foo/" assert pth2.name == "bar" assert str(pth2) == "/foo/bar" Operations such as pth.walk() would then return path objects where basepath was set to the original path object, and only the relative path was included in "dirparts". Cheers, Nick. -- Nick Coghlan | [EMAIL PROTECTED] | Brisbane, Australia --------------------------------------------------------------- http://www.boredomandlaziness.org _______________________________________________ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com