[Python-ideas] PEP 428 - object-oriented filesystem paths

Antoine Pitrou solipsis at pitrou.net
Fri Oct 5 21:55:20 CEST 2012

On Fri, 5 Oct 2012 20:19:12 +0100
Paul Moore <p.f.moore at gmail.com> wrote:
> On 5 October 2012 19:25, Antoine Pitrou <solipsis at pitrou.net> wrote:
> > A path can be joined with another using the ``__getitem__`` operator::
> >
> >     >>> p = PurePosixPath('foo')
> >     >>> p['bar']
> >     PurePosixPath('foo/bar')
> >     >>> p[PurePosixPath('bar')]
> >     PurePosixPath('foo/bar')
> There is a risk that this is too "cute". However, it's probably better
> than overloading the '/' operator, and you do need something short.

I think overloading '/' is ugly (dividing paths??).

Someone else proposed overloading '+', which would be confusing since we
need to be able to combine paths and regular strings, for ease of use.
The point of using __getitem__ is that you get an error if you replace
the Path object with a regular string by mistake:

>>> PurePath('foo')['bar']
>>> 'foo'['bar']
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: string indices must be integers

If you were to use the '+' operator instead, 'foo' + 'bar' would work
but give you the wrong result.

> > As with constructing, multiple path components can be specified at once::
> >
> >     >>> p['bar/xyzzy']
> >     PurePosixPath('foo/bar/xyzzy')
> That's risky. Are you proposing always using '/' regardless of OS? I'd
> have expected os.sep (so \ on Windows).

Both '/' and '\\' are accepted as path separators under Windows. Under
Unix, '\\' is a regular character:

>>> PurePosixPath('foo\\bar') == PurePosixPath('foo/bar')
>>> PureNTPath('foo\\bar') == PureNTPath('foo/bar')

> It would probably be better to allow tuples as arguments:
> p['bar', 'baz']

It already works indeed:

>>> p = PurePath('foo')
>>> p['bar', 'baz']

> > Five simple properties are provided on every path (each can be empty)::
> >
> >     >>> p = PureNTPath('c:/pathlib/setup.py')
> >     >>> p.drive
> >     'c:'
> >     >>> p.root
> >     '\\'
> >     >>> p.anchor
> >     'c:\\'
> >     >>> p.name
> >     'setup.py'
> >     >>> p.ext
> >     '.py'
> I don't like the way the distinction between "root" and "anchor" works
> here. Unix users are never going to use "anchor", as "root" is the
> natural term, and it does exactly the right thing on Unix. So code
> written on Unix will tend to do the wrong thing on Windows (where
> generally you'd want to use "anchor" or you'll find yourself switching
> accidentally to the current drive).

Well, I expect .root or .anchor to be used mostly for presentation or
debugging purposes. There's nothing really useful to be done with them
otherwise, IMHO. Do you know of any use cases?

> Also, there is no good terminology in current use here. The only
> concrete thing I can suggest is that "root" would be better used as
> the term for what you're calling "anchor" as Windows users would
> expect the root of "C:\foo\bar\baz" to be "C:\".

But then the root of "C:foo" would be "C:", which sounds wrong:
"C:" isn't a root at all.

> But there's no really simple answer - Windows and Unix are just different here.

Yes, and Unix users are expecting something simpler than what's going on
under Windows ;)

> Also, I assume that paths will be comparable, using case sensitivity
> appropriate to the platform. Presumably a PurePath and a Path are
> comparable, too. What about a PosixPath and an NTPath? Would you
> expect them to be comparable or not?

Currently, different flavours imply unequal (and unorderable) paths:

>>> PurePosixPath('foo') == PureNTPath('foo')
>>> PurePosixPath('foo') > PureNTPath('foo')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unorderable types: PurePosixPath() > PureNTPath()

However, pure paths and concrete paths of the same flavour can be
equal, and ordered:

>>> PurePath('foo') == Path('foo')
>>> PurePath('foo') >= Path('foo')



Software development and contracting: http://pro.pitrou.net

More information about the Python-ideas mailing list