Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

equivalent of Ruby's Pathname?

5 views
Skip to first unread message

Phlip

unread,
Feb 3, 2010, 5:47:52 PM2/3/10
to
Pythonistas:

Yes, calling os.path.walk() and os.path.join() all the time on raw
strings is fun, but I seem to recall from my Ruby days a class called
Pathname, which presented an object that behaved like a string at
need, and like a filesystem path at need. path + 'folder' would
call .join() and insert the / correctly, for example.

What's the best equivalent in Python-land?

--
Phlip

alex23

unread,
Feb 3, 2010, 9:08:52 PM2/3/10
to

It's no longer supported, but the 3rd party 'path' module used to be
the go-to module for this:

>>> from path import path
C:\Python26\lib\site-packages\path.py:32: DeprecationWarning: the md5
module is deprecated; use hashlib instead
import sys, warnings, os, fnmatch, glob, shutil, codecs, md5
>>> c = path('C:\\')
>>> c.listdir()
[path(u'C:\\AUTOEXEC.BAT'), path(u'C:\\boot.ini'), ...]
>>> (c + 'python26').listdir()
[path(u'C:\\python26\\circuits.pth_disabled_for_egg'), path(u'C:\
\python26\\DLLs'), ...]
>>> (c / 'python26').listdir()
[path(u'C:\\python26\\circuits.pth_disabled_for_egg'), path(u'C:\
\python26\\DLLs'), ...]

I've hand edited the results for brevity...

The module could do with some TLC to bring it up to date, but warning
aside it still seems to work fine under 2.6.

(From memory, I think the original author gave up when it became clear
it would never be integrated into the standard lib[1], which is a
shame, I think there's scope for a pathtools addition to the lib that
provides this level of convenience...)

There was also a PEP with another possible implementation:
http://www.python.org/dev/peps/pep-0355/

Hope this helps.

Sean DiZazzo

unread,
Feb 4, 2010, 10:10:31 PM2/4/10
to

It's too bad that something like this can't be agreed to. I used a
homegrown module like this for a couple of years in my early days with
python. It was great, but I didn't know enough at the time to make it
really useful.

Why did Path() get rejected? Is it the idea itself, or just the
approach that was used? What are the complaints?

~Sean

Aahz

unread,
Feb 8, 2010, 5:36:47 PM2/8/10
to
In article <dcace5fc-5ae9-4756...@s36g2000prh.googlegroups.com>,
Sean DiZazzo <half.i...@gmail.com> wrote:

>On Feb 3, 6:08=A0pm, alex23 <wuwe...@gmail.com> wrote:
>>
>> There was also a PEP with another possible implementation:
>> http://www.python.org/dev/peps/pep-0355/
>
>Why did Path() get rejected? Is it the idea itself, or just the
>approach that was used? What are the complaints?

You should search for the discussiona around it.
--
Aahz (aa...@pythoncraft.com) <*> http://www.pythoncraft.com/

import antigravity

Phlip

unread,
Feb 8, 2010, 5:46:36 PM2/8/10
to
On Feb 8, 2:36 pm, a...@pythoncraft.com (Aahz) wrote:

> >> There was also a PEP with another possible implementation:
> >>http://www.python.org/dev/peps/pep-0355/
>
> >Why did Path() get rejected?  Is it the idea itself, or just the
> >approach that was used?  What are the complaints?
>
> You should search for the discussiona around it.

I, OTOH, am burning rubber with Python 2.6.1, so leading edge concerns
are not mine - yet!

I went with this version, generously ripped out & plopped into our
project:

# URL: http://www.jorendorff.com/articles/python/path
# Author: Jason Orendorff <ja...@jorendorff.com> (and others - see
the url!)
# Date: 7 Mar 2004

class path(_base):
""" Represents a filesystem path.
"""

Gods bless http://www.google.com/codesearch, huh?!

--
Phlip
http://c2.com/cgi/wiki?ZeekLand

Carl Banks

unread,
Feb 8, 2010, 7:26:18 PM2/8/10
to

I don't know if it was the reason it was rejected, but a seriously
divisive question is whether the path should be a subset of string.

Under ordinary circumstances it would be a poor choice for inheritance
(only a few string methods would be useful fot a pathname), but some
people were fiercely adamant that paths should be passable to open()
as-in (without having to explicity convert to string). IIRC, the guy
who maintained path wavered between subclassing and not subclassing
str. I don't remember if the idea of modifying open to accept path
objects came up.


Carl Banks

Phlip

unread,
Feb 9, 2010, 12:21:55 AM2/9/10
to
Carl Banks wrote:

> I don't know if it was the reason it was rejected, but a seriously
> divisive question is whether the path should be a subset of string.

OMG that's nothing but the OO "circle vs ellipse" non-question. Glad
to see the Committee derailed a perfectly good library over such
sophistry.

> Under ordinary circumstances it would be a poor choice for inheritance
> (only a few string methods would be useful fot a pathname), but some
> people were fiercely adamant that paths should be passable to open()
> as-in (without having to explicity convert to string).

That's just silly. To be object-based, you should say path.open('r').
fopen() and its ilk are too 1960s...

My 5th Grade science teacher, one Eunice Feight, once expressed
chagrin for submitting a proposal to Readers' Digest, and getting it
accepted. She sold them the following sloka:

Don't be clever don't be witty
Or you'll wind up BEING the Committee!

--
Phlip
http://penbird.tumblr.com/

Gregory Ewing

unread,
Feb 9, 2010, 1:55:16 AM2/9/10
to
Carl Banks wrote:
> I don't remember if the idea of modifying open to accept path
> objects came up.

It wouldn't just be open() that people would want modified --
it would be every other function that takes a pathname as
well.

I seem to recall another point of contention was whether
path objects should have methods for accessing the file
system (opening files, renaming them, etc.) or whether it
should confine itself to representing and manipulating
pathnames.

In any case, introducing any kind of path object at this
late stage of the language's development would result in
More Than One Way to represent pathnames, with neither of
them being the obvious choice.

--
Greg

Steve Holden

unread,
Feb 9, 2010, 7:38:42 AM2/9/10
to pytho...@python.org
Phlip wrote:
> Carl Banks wrote:
>
>> I don't know if it was the reason it was rejected, but a seriously
>> divisive question is whether the path should be a subset of string.
>
> OMG that's nothing but the OO "circle vs ellipse" non-question. Glad
> to see the Committee derailed a perfectly good library over such
> sophistry.
>
That's nothing but the most arrant nonsense, as you would discover if
you took the trouble to read the discussion on python-dev instead of
jumping to conclusions.

>> Under ordinary circumstances it would be a poor choice for inheritance
>> (only a few string methods would be useful fot a pathname), but some
>> people were fiercely adamant that paths should be passable to open()
>> as-in (without having to explicity convert to string).
>
> That's just silly. To be object-based, you should say path.open('r').
> fopen() and its ilk are too 1960s...
>

What? Are you arguing for "myfile.txt".open('r') to be a valid Python
construct? If not then surely you can see that paths would require
different treatment from strings, which was the main thrust of the
discussion on the dev list.

I find it really irritating when the clueless come along and criticize
decisions made by the developers after thorough discussion. Not only do
decisions have to be made about how code is going to work (and work for
the next twenty years or so), but someone has to commit to maintaining
the code before it goes in (otherwise Python will be full of bit-rot).

To call your criticism ill-informed would be flattering it.

> My 5th Grade science teacher, one Eunice Feight, once expressed
> chagrin for submitting a proposal to Readers' Digest, and getting it
> accepted. She sold them the following sloka:
>
> Don't be clever don't be witty
> Or you'll wind up BEING the Committee!
>

Criticism isn't pretty
Specially when your logic's shitty.

regards
Steve
--
Steve Holden +1 571 484 6266 +1 800 494 3119
PyCon is coming! Atlanta, Feb 2010 http://us.pycon.org/
Holden Web LLC http://www.holdenweb.com/
UPCOMING EVENTS: http://holdenweb.eventbrite.com/

Chris Rebert

unread,
Feb 9, 2010, 7:52:02 AM2/9/10
to Steve Holden, pytho...@python.org
On Tue, Feb 9, 2010 at 4:38 AM, Steve Holden <st...@holdenweb.com> wrote:
> Phlip wrote:
>> Carl Banks wrote:
>>
>>> I don't know if it was the reason it was rejected, but a seriously
>>> divisive question is whether the path should be a subset of string.
>>
>> OMG that's nothing but the OO "circle vs ellipse" non-question. Glad
>> to see the Committee derailed a perfectly good library over such
>> sophistry.
>>
> That's nothing but the most arrant nonsense, as you would discover if
> you took the trouble to read the discussion on python-dev instead of
> jumping to conclusions.
>
>>> Under ordinary circumstances it would be a poor choice for inheritance
>>> (only a few string methods would be useful fot a pathname), but some
>>> people were fiercely adamant that paths should be passable to open()
>>> as-in (without having to explicity convert to string).
>>
>> That's just silly. To be object-based, you should say path.open('r').
>> fopen() and its ilk are too 1960s...
>>
> What? Are you arguing for "myfile.txt".open('r') to be a valid Python
> construct? If not then surely you can see that paths would require
> different treatment from strings, which was the main thrust of the
> discussion on the dev list.

Based on the context, I'm /pretty/ sure he was (implicitly) talking
about e.g. Path("myfile.txt").open('r').

Cheers,
Chris
--
http://blog.rebertia.com

Phlip

unread,
Feb 9, 2010, 9:00:23 AM2/9/10
to
Gregory Ewing wrote:

> It wouldn't just be open() that people would want modified --
> it would be every other function that takes a pathname as
> well.

Then refer to the same argument against implicit type conversions in C+
+.

A ::std::string must call .c_str() to turn into a lowly char*, before
passing into a C function. Advocating for 8 characters of convenience
opens the risk of silent bugs at refactor time.

> I seem to recall another point of contention was whether
> path objects should have methods for accessing the file
> system (opening files, renaming them, etc.) or whether it
> should confine itself to representing and manipulating
> pathnames.

In that case, the package I picked seems to have "erred" on the side
of programmer convenience.

Because the basic file operations (exist, stat, move/rename, copy,
open, chmod, unlink) come as a complete and whole kit, a class should
simply present that kit, insulating against filesystem differences.

> In any case, introducing any kind of path object at this
> late stage of the language's development would result in
> More Than One Way to represent pathnames, with neither of
> them being the obvious choice.

Ah, now we get down to the root of the problem. Because Python is so
stuck on the "one best way to do it" mentality, language bigotry
prevented the Committee from picking from among several equally valid
but non-best options. And after 20 years of growth, Python still has
no Pathname class. What a mature community! C-:

--
Phlip
http://c2.com/cgi/wiki?MoreliaViridis

Bruno Desthuilliers

unread,
Feb 9, 2010, 10:23:59 AM2/9/10
to
Phlip a �crit :

> Gregory Ewing wrote:
>
>> In any case, introducing any kind of path object at this
>> late stage of the language's development would result in
>> More Than One Way to represent pathnames, with neither of
>> them being the obvious choice.
>
> Ah, now we get down to the root of the problem. Because Python is so
> stuck on the "one best way to do it"
> mentality, language bigotry
> prevented the Committee from picking from among several equally valid
> but non-best options.

You failed to actually _read_ what you're answering to. Try again. Using
your brain, this time.

Chris Rebert

unread,
Feb 9, 2010, 5:28:12 PM2/9/10
to Phlip, pytho...@python.org
On Tue, Feb 9, 2010 at 6:00 AM, Phlip <phli...@gmail.com> wrote:
<snip>

> Ah, now we get down to the root of the problem. Because Python is so
> stuck on the "one best way to do it" mentality, language bigotry
> prevented the Committee from picking from among several equally valid
> but non-best options. And after 20 years of growth, Python still has
> no Pathname class. What a mature community! C-:

Committee? I think you have us confused with C++...

*wink*,
Chris

Sean DiZazzo

unread,
Feb 9, 2010, 7:27:41 PM2/9/10
to
On Feb 8, 2:36 pm, a...@pythoncraft.com (Aahz) wrote:
> In article <dcace5fc-5ae9-4756-942d-6da7da2f6...@s36g2000prh.googlegroups.com>,

> Sean DiZazzo  <half.ital...@gmail.com> wrote:
>
> >On Feb 3, 6:08=A0pm, alex23 <wuwe...@gmail.com> wrote:
>
> >> There was also a PEP with another possible implementation:
> >>http://www.python.org/dev/peps/pep-0355/
>
> >Why did Path() get rejected?  Is it the idea itself, or just the
> >approach that was used?  What are the complaints?
>
> You should search for the discussiona around it.
> --
> Aahz (a...@pythoncraft.com)           <*>        http://www.pythoncraft.com/
>
> import antigravity

I read the discussion, and there was definitely some going back and
forth on whether it should be sub-classed from string, but the
conversation just seemed to stop abruptly with no decision one way of
the other. Maybe I missed a thread.

I guess being dropped without a final go-ahead is just as good as a
formal no anyway.

Aahz

unread,
Feb 14, 2010, 3:39:40 PM2/14/10
to
In article <8fc356e0-f3ed-4a67...@p13g2000pre.googlegroups.com>,
Sean DiZazzo <half.i...@gmail.com> wrote:
>On Feb 8, 2:36=A0pm, a...@pythoncraft.com (Aahz) wrote:
>> In article <dcace5fc-5ae9-4756-942d-6da7da2f6...@s36g2000prh.googlegroups=
>.com>,

>> Sean DiZazzo =A0<half.ital...@gmail.com> wrote:
>>>
>>>Why did Path() get rejected? Is it the idea itself, or just the
>>>approach that was used? What are the complaints?
>>
>> You should search for the discussiona around it.
>
>I read the discussion, and there was definitely some going back and
>forth on whether it should be sub-classed from string, but the
>conversation just seemed to stop abruptly with no decision one way of
>the other. Maybe I missed a thread.
>
>I guess being dropped without a final go-ahead is just as good as a
>formal no anyway.

Not quite: because it was not rejected, someone who wants to shepherd the
process forward would likely be welcomed (even if it ends up with formal
rejection). I suggest starting by writing your own summary of the
previous discussion and see if the people involved agree that your
summary is reasonably accurate. Also check to see if the original PEP
writer wants to be involved or whether zie is willing to have you take
over.

Another good (and related) starting point would be to create a reasoning
favoring one side or the other that was not brought up in previous
discussion.

"At Resolver we've found it useful to short-circuit any doubt and just
refer to comments in code as 'lies'. :-)"

Mike Orr

unread,
Mar 9, 2010, 6:18:11 PM3/9/10
to
I just saw this thread on the Python-URL.

On Feb 14, 12:39 pm, a...@pythoncraft.com (Aahz) wrote:
> >> Sean DiZazzo =A0<half.ital...@gmail.com> wrote:
>
> >>>Why did Path() get rejected? Is it the idea itself, or just the
> >>>approach that was used? What are the complaints?
>
> >> You should search for the discussiona around it.
>
> >I read the discussion, and there was definitely some going back and
> >forth on whether it should be sub-classed from string, but the
> >conversation just seemed to stop abruptly with no decision one way of
> >the other.  Maybe I missed a thread.

It has a habit of being discussed and dropped repeatedly. The main
issue is that Guido doesn't see an OO approach as necessarily better
than the existing functions, so it has a high bar for acceptance. One
issue is that some people see a need to separate filesystem-
independent functionality (joining paths and extracting components)
from filesystem-dependent functionality (listing directories, removing
files, etc). ``path.py`` and PEP 355 were rejected mainly because of
this. There was support for a small filesystem-independent class that
could be put into the stdlib, and some modest moving/renaming of the
filesystem functions (which are scattered across os, os.path, shutil,
glob, etc). We were hoping to get this done for Python 3 but didn't
make it. I wrote a ``Unipath`` package that tried to be a compromise
between what everybody wanted, with a FS-independent class and a FS-
dependent subclass, but could not get any feedback on it. Somebody
else was going to write a PEP for the renamings, but I never saw it.

Since then, path.py has been included in a couple packages and seems
to have the most widespread use. I gave up on the stdlib and
reconfigured Unipath as a pure 3rd-party library. (The FS-independent
AbstractPath class is still there if anybody wants to use it for a
PEP.) The other people who made their own implementations seemed to be
happy with theirs, and that was that.

The string vs non-string argument has pretty much been decided in
favor of strings (i.e., a string subclass). Not ``"a.txt".open()`` but
``open(Path("a.txt"))``. Too many standard and 3rd-party modules
expect string paths: you'd have to convert your path to a string every
time you pass it as an argument. The main problem with string paths
is that .join() means something else, but that's usually solved by
using a different method name: "joinpath", "child", "/", etc.

Other proposals have been a tuple subclass, so that ``Path("a/b/c.txt")
[-1] == Path("c.txt")``, and a library that can do non-native paths
(Windows style on Unix systems and vice-versa). These don't seem to be
in vogue anymore.

What has become more common is virtual paths; i.e., the same interface
for filesystems, FTP, zip files, etc. That was discussed during the
last go-around but there were no implementations. Now there are a few
projects active on this, such as http://groups.google.com/group/stdpyfs
. This is probably the future of any path object, so it would make
sense to define a path now that can work with all these backends.

--Mike

Martin P. Hellwig

unread,
Mar 9, 2010, 6:58:01 PM3/9/10
to
On 02/09/10 14:00, Phlip wrote:
<cut>

> Ah, now we get down to the root of the problem. Because Python is so
> stuck on the "one best way to do it" mentality, language bigotry
> prevented the Committee from picking from among several equally valid
> but non-best options. And after 20 years of growth, Python still has
> no Pathname class. What a mature community! C-:
>
<cut>
Well even if this statement would be true, I personally think that not
proclaiming something a 'standard' if you are sure that you are not sure
about it, is a virtue.

--
mph

Phlip

unread,
Mar 10, 2010, 11:54:51 AM3/10/10
to
Martin P. Hellwig wrote:

> Well even if this statement would be true, I personally think that not
> proclaiming something a 'standard' if you are sure that you are not sure
> about it, is a virtue.

In terms of trying too hard to achieve perfection, am I missing a
Python repository similar to the C++ Boost project? All the nice-to-
have classes that extend the core of C++ get to live in Boost before
the C++ Committee pulls the best ideas off the top and add them to the
Standard Library...

--
Phlip
http://penbird.tumblr.com/

Chris Rebert

unread,
Mar 10, 2010, 12:15:07 PM3/10/10
to Phlip, pytho...@python.org

The next closest thing would probably be the Python Cookbook:
http://code.activestate.com/recipes/langs/python/

However, such stuff can also be found as third-party modules.

Phlip

unread,
Mar 16, 2010, 12:12:08 PM3/16/10
to
Chris Rebert wrote:

> The next closest thing would probably be the Python Cookbook:http://code.activestate.com/recipes/langs/python/

One thing I really like about ... my hacked version of path.py ... is
path.cd( lambda: ... ). It works great inside fabfile.py to
temporarily switch to a different folder:

sample_project = path('sample_project').abspath()

def run():
sample_project.cd( lambda:
_sh('python manage.py runserver 0.0.0.0:8000 --
settings=test_settings') )

After the lambda runs, we exception-safely return to the home folder.

(BTW I'm aware that a fabfile.py command with only one statement will
return to its shell and remain in the correct folder. It's just ...
the thought!)

This be .cd():

class path:

def cd(self, block=None):
previous = path(os.path.curdir).abspath()
self.chdir()

if block:
try: block()
finally: previous.chdir()

That's based on Jason Orendoff's work at http://www.jorendorff.com/articles/python/path

--
Phlip
http://c2.com/cgi/wiki?ZeekLand

Steve Holden

unread,
Mar 16, 2010, 1:00:36 PM3/16/10
to pytho...@python.org
Wouldn't this be better written as a context manager?

Be aware also that this won't work well in a multi-threaded environment
(assuming os.path.chdir is ultimately used to change directories)
because it effects the process's (globaL current directory.

regards
Steve
--
Steve Holden +1 571 484 6266 +1 800 494 3119

See PyCon Talks from Atlanta 2010 http://pycon.blip.tv/

0 new messages