Forgot to reply to list!
-------- Original Message -------- From: Markus Unterwaditzer markus@unterwaditzer.net Sent: 24 March 2015 13:25:27 CET To: Paul Moore p.f.moore@gmail.com Subject: Re: [Python-ideas] pathlib.Path.parts - tuple of path objects rather than strings?
I'd say treating each part as full-blown Path doesn't make sense from a semantical POV.
Simply mapping Path over the results is also a potential source of bugs, since each part is now a relative path to the CWD, instead of the previous segment.
I'd suggest that an additional property is added where:
Path("/usr/bin/true").newproperty == (Path("/"), Path("/usr"), Path("/usr/bin"), Path("/usr/bin/true"))
I.e. each part is a prefix of the next one.
But I'm not sure where you'd use that.
-- Markus
On 24 March 2015 13:08:25 CET, Paul Moore p.f.moore@gmail.com wrote:
One occasional problem I have with pathlib.Path.parts is that it returns a tuple of strings. For WindowsPath objects, paths are case insensitive but strings aren't. So we get the situation that
p1 = pathlib.PureWindowsPath('foo') p2 = pathlib.PureWindowsPath('FOO') p1 == p2
True
p1.parts == p2.parts
False
Making p1.parts return a tuple of objects of type p1.__class__ would address this:
[p1.__class__(p) for p in p1.parts] == [p2.__class__(p) for p in
p2.parts] True
Is this something that's worth changing (pathlib is still provisional, so the backward compatibility break would technically be allowed, even if it's not ideal)? Or would an extra property, say p.path_parts that returned a tuple of path objects be worth considering?
As it is, use of path.parts is a potential source of portability bugs, where Unix users don't consider the case sensitivity issue. (Heck, as a Windows user, I almost missed the problem in my implementation of common_prefix, so it's not just Unix users...)
Paul _______________________________________________ Python-ideas mailing list Python-ideas@python.org https://mail.python.org/mailman/listinfo/python-ideas Code of Conduct: http://python.org/psf/codeofconduct/
On Tue, Mar 24, 2015 at 2:39 PM, Markus Unterwaditzer markus@unterwaditzer.net wrote:
I'd suggest that an additional property is added where:
Path("/usr/bin/true").newproperty == (Path("/"), Path("/usr"), Path("/usr/bin"), Path("/usr/bin/true"))
I.e. each part is a prefix of the next one.
Path.parents already exists:
Python 3.4.2 (default, Feb 23 2015, 21:16:28) [GCC 4.2.1 Compatible Apple LLVM 5.1 (clang-503.0.40)] on darwin Type "help", "copyright", "credits" or "license" for more information.
import pathlib list(pathlib.Path("/usr/bin/true").parents)
[PosixPath('/usr/bin'), PosixPath('/usr'), PosixPath('/')]
- Tal Einat
On Mar 24, 2015, at 6:44 AM, Tal Einat talent@gmail.com wrote:
On Tue, Mar 24, 2015 at 2:39 PM, Markus Unterwaditzer markus@unterwaditzer.net wrote:
I'd suggest that an additional property is added where:
Path("/usr/bin/true").newproperty == (Path("/"), Path("/usr"), Path("/usr/bin"), Path("/usr/bin/true"))
I.e. each part is a prefix of the next one.
Path.parents already exists:
Python 3.4.2 (default, Feb 23 2015, 21:16:28) [GCC 4.2.1 Compatible Apple LLVM 5.1 (clang-503.0.40)] on darwin Type "help", "copyright", "credits" or "license" for more information.
import pathlib list(pathlib.Path("/usr/bin/true").parents)
[PosixPath('/usr/bin'), PosixPath('/usr'), PosixPath('/')]
Ooh, forgot about that!
That implies a conceptually simpler implementation: it's just first(last(takewhile(all_equal(reversed(map(parents)))))), but I'm too tired to finish translating that from Haskelly terms to itertoolsy terms in my head. :) I'm not sure if that would be simpler (or more efficient) in practice, however.
Also, it would give the opposite answer to is the 'true' bit a potential part of the result if you common-prefix /usr/bin/true with itself (or only pass one argument), which goes nicely with my intuition but not so nicely with the rosettacode page. But maybe that's just a matter of naming--with "common_parent" or "common_ancestor" instead of "common_prefix" it seems pretty obvious and unambiguous?
On Tue, Mar 24, 2015 at 4:56 PM, Andrew Barnert abarnert@yahoo.com wrote:
On Mar 24, 2015, at 6:44 AM, Tal Einat talent@gmail.com wrote:
Path.parents already exists:
Python 3.4.2 (default, Feb 23 2015, 21:16:28) [GCC 4.2.1 Compatible Apple LLVM 5.1 (clang-503.0.40)] on darwin Type "help", "copyright", "credits" or "license" for more information.
import pathlib list(pathlib.Path("/usr/bin/true").parents)
[PosixPath('/usr/bin'), PosixPath('/usr'), PosixPath('/')]
Ooh, forgot about that!
That implies a conceptually simpler implementation: it's just first(last(takewhile(all_equal(reversed(map(parents)))))), but I'm too tired to finish translating that from Haskelly terms to itertoolsy terms in my head. :) I'm not sure if that would be simpler (or more efficient) in practice, however.
Also, it would give the opposite answer to is the 'true' bit a potential part of the result if you common-prefix /usr/bin/true with itself (or only pass one argument), which goes nicely with my intuition but not so nicely with the rosettacode page. But maybe that's just a matter of naming--with "common_parent" or "common_ancestor" instead of "common_prefix" it seems pretty obvious and unambiguous?
Well, the function I wrote was "common_parent" since that was what I needed, and what it does is indeed clearer than "common_prefix". Off the top of my head, I can't think of use cases where one would want "common_prefix" instead of "common_parent" where Path.relative_to() wouldn't be better. So maybe just provide "common_parent"?
- Tal Einat