How to do relpath implementation on 2.5

  • Thread starter Brian Allen Vanderburg II
  • Start date
B

Brian Allen Vanderburg II

I've coded my own 'relpath' implementation for 2.5 (shown below) and I
want to make sure it follows as closely as it should to 2.6 and later.
I've got a question regarding that. When attempting to convert to a
relative path and it is not possible for some reason (different drive or
UNC share), should that be an error or should it return the absolute
path of the target? I'm using Debian so I don't have 2.6 available
right now for testing.

This is what I've got so far

import os
from os import path


def relpath(target, origin=os.curdir):
"""
Determine relative path of target to origin or
"""

target = path.normcase(path.abspath(path.normpath(target)))
origin = path.normcase(path.abspath(path.normpath(origin)))

# Same?
if target == origin:
return '.'

original_target = target

# Check drive (for Windows)
(tdrive, target) = path.splitdrive(target)
(odrive, origin) = path.splitdrive(origin)
if tdrive != odrive:
return original_target

# Check UNC path (for Windows)
# If they are on different shares, we want an absolute path
if not tdrive and not odrive and hasattr(path, 'splitunc'):
(tunc, target) = path.splitunc(target)
(ounc, origin) = path.splitunc(origin)
if tunc != ounc:
return original_target

# Split into lists
target_list = target.split(os.sep)
origin_list = origin.split(os.sep)

# Remove beginning empty parts
# Helps to handle when one item may be in the root
while target_list and not target_list[0]:
del target_list[0]
while origin_list and not origin_list[0]:
del origin_list[0]

# Remove common items
while origin_list and target_list:
if origin_list[0] == target_list[0]:
del origin_list[0]
del target_list[0]
else:
break

# Combine and return the result
relative_list = [os.pardir] * len(origin_list) + target_list
if not relative_list:
return os.curdir
return os.sep.join(relative_list)


Currently I just return the target if it can not be made relative.

Brian A. Vanderburg II
 
R

ryles

I've coded my own 'relpath' implementation for 2.5 (shown below) and I
want to make sure it follows as closely as it should to 2.6 and later.  
I've got a question regarding that.  When attempting to convert to a
relative path and it is not possible for some reason (different drive or
UNC share), should that be an error or should it return the absolute
path of the target?  I'm using Debian so I don't have 2.6 available
right now for testing.

Usually Python source code is easily browsed at:

http://svn.python.org/view/

Unfortunately the server is down right now.

The implementation in 2.6 raises a ValueError exception. Here is the
function from ntpath.py:

def relpath(path, start=curdir):
"""Return a relative version of a path"""

if not path:
raise ValueError("no path specified")
start_list = abspath(start).split(sep)
path_list = abspath(path).split(sep)
if start_list[0].lower() != path_list[0].lower():
unc_path, rest = splitunc(path)
unc_start, rest = splitunc(start)
if bool(unc_path) ^ bool(unc_start):
raise ValueError("Cannot mix UNC and non-UNC paths (%s and
%s)"
%
(path, start))
else:
raise ValueError("path is on drive %s, start on drive %s"
% (path_list[0],
start_list[0]))
# Work out how much of the filepath is shared by start and path.
for i in range(min(len(start_list), len(path_list))):
if start_list.lower() != path_list.lower():
break
else:
i += 1

rel_list = [pardir] * (len(start_list)-i) + path_list[i:]
if not rel_list:
return curdir
return join(*rel_list)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,201
Messages
2,571,048
Members
47,647
Latest member
NelleMacy9

Latest Threads

Top