changeset 34:8fec38b0dd6e

A os.path.relpath implementation for Python 2.5
author Oleg Oshmyan <chortos@inbox.lv>
date Tue, 30 Nov 2010 00:18:17 +0000
parents f90bd2d1a12b
children 23aa8da5be5f
files 2.00/compat.py 2.00/files.py
diffstat 2 files changed, 54 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/2.00/compat.py	Mon Nov 29 22:15:01 2010 +0000
+++ b/2.00/compat.py	Tue Nov 30 00:18:17 2010 +0000
@@ -64,6 +64,60 @@
 			if not isinstance(end, basestring): raise saytypeerror(end, 'end')
 			file.write(sep.join(map(str, values)) + end)
 
+try:
+	from os.path import relpath
+except ImportError:
+	# Python 2.5
+	import os.path as _path
+	
+	# Adapted from Python 2.7.1
+	
+	if hasattr(_path, 'splitunc'):
+		def _abspath_split(path):
+			abs = _path.abspath(_path.normpath(path))
+			prefix, rest = _path.splitunc(abs)
+			is_unc = bool(prefix)
+			if not is_unc:
+				prefix, rest = _path.splitdrive(abs)
+			return is_unc, prefix, [x for x in rest.split(_path.sep) if x]
+	else:
+		def _abspath_split(path):
+			prefix, rest = _path.splitdrive(_path.abspath(_path.normpath(path)))
+			return False, prefix, [x for x in rest.split(_path.sep) if x]
+	
+	def relpath(path, start=_path.curdir):
+		"""Return a relative version of a path"""
+		
+		if not path:
+			raise ValueError("no path specified")
+		
+		start_is_unc, start_prefix, start_list = _abspath_split(start)
+		path_is_unc, path_prefix, path_list = _abspath_split(path)
+		
+		if path_is_unc ^ start_is_unc:
+			raise ValueError("Cannot mix UNC and non-UNC paths (%s and %s)"
+	                                                    		% (path, start))
+		if path_prefix.lower() != start_prefix.lower():
+			if path_is_unc:
+				raise ValueError("path is on UNC root %s, start on UNC root %s"
+		                                    		% (path_prefix, start_prefix))
+			else:
+				raise ValueError("path is on drive %s, start on drive %s"
+		                                    		% (path_prefix, start_prefix))
+		# Work out how much of the filepath is shared by start and path.
+		i = 0
+		for e1, e2 in zip(start_list, path_list):
+			if e1.lower() != e2.lower():
+				break
+			i += 1
+		
+		rel_list = [_path.pardir] * (len(start_list)-i) + path_list[i:]
+		if not rel_list:
+			return _path.curdir
+		return _path.join(*rel_list)
+	
+	_path.relpath = relpath
+
 def import_urllib():
 	try:
 		# Python 3
--- a/2.00/files.py	Mon Nov 29 22:15:01 2010 +0000
+++ b/2.00/files.py	Tue Nov 30 00:18:17 2010 +0000
@@ -121,7 +121,6 @@
 				path = None
 			
 			member = self.file.getinfo(name)
-			# FIXME: 2.5 lacks os.path.realpath
 			member.filename = os.path.relpath(target, path)
 			# FIXME: 2.5 lacks ZipFile.extract
 			self.file.extract(member, path)