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

paths: splitall(), relativepath()

79 views
Skip to first unread message

Martin Bless

unread,
Mar 24, 2004, 4:49:44 PM3/24/04
to
I was looking for a function that returns the relative path to a file
when looking from a specified directory. Here's what seems to do the
job.

Somebody discovers any pitfalls?

I could imagine it would be nice to have splitall() and relativepath()
funcionality somewhere in the standard library.

Have a nice day,

mb - Martin Bless


import os
import sys

def splitall(path):
"""Split a path into all of its parts.

From: Python Cookbook, Credit: Trent Mick
"""
allparts = []
while 1:
parts = os.path.split(path)
if parts[0] == path:
allparts.insert(0, parts[0])
break
elif parts[1] == path:
allparts.insert(0, parts[1])
break
else:
path = parts[0]
allparts.insert(0, parts[1])
return allparts

def relativepath(fromdir, tofile):
"""Find relative path from 'fromdir' to 'tofile'.

An absolute path is returned if 'fromdir' and 'tofile'
are on different drives. Martin Bless, 2004-03-22.
"""
f1name = os.path.abspath(tofile)
if os.path.splitdrive(f1name)[0]:
hasdrive = True
else:
hasdrive = False
f1basename = os.path.basename(tofile)
f1dirname = os.path.dirname(f1name)
f2dirname = os.path.abspath(fromdir)
f1parts = splitall(f1dirname)
f2parts = splitall(f2dirname)
if hasdrive and (f1parts[0].lower() <> f2parts[0].lower()):
"Return absolute path since we are on different drives."
return f1name
while f1parts and f2parts:
if hasdrive:
if f1parts[0].lower() <> f2parts[0].lower():
break
else:
if f1parts[0] <> f2parts[0]:
break
del f1parts[0]
del f2parts[0]
result = ['..' for part in f2parts]
result.extend(f1parts)
result.append(f1basename)
return os.sep.join(result)

if 1 and __name__=="__main__":
"demonstrate relativepath(...)"
tofile = "C:/py/docutils/stylesheets/default.css"
fromdir = "c:/PY/some/demo/currentdir"
print "fromdir.....: ", fromdir
print "tofile......: ", tofile
print "relativepath: ", relativepath(fromdir,tofile)
r"""Should print:
fromdir.....: c:/PY/some/demo/currentdir
tofile......: C:/py/docutils/stylesheets/default.css
relativepath: ..\..\..\docutils\stylesheets\default.css
"""
print "Done."

Jeff Epler

unread,
Mar 25, 2004, 10:55:42 AM3/25/04
to m.b...@gmx.de, pytho...@python.org
relativepath won't work with mac-style paths, instead of ".." you should
probably use os.pardir instead.

that's the only thing that jumps out at me...

Jeff
PS I've often wanted splitall(), I don't recall ever wanting relativepath

Martin Bless

unread,
Mar 26, 2004, 3:56:52 AM3/26/04
to
[Jeff Epler <jep...@unpythonic.net>]

>relativepath won't work with mac-style paths, instead of ".." you should
>probably use os.pardir instead.

Good point, thanks. I wasn't aware of os.pardir.

mb - Martin Bless

0 new messages