Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Merge pull request #9

  • Loading branch information...
commit 04ec4502aa8b74f1726e2b5f82ba72933db8c53b 2 parents 996a3fa + d36450e
@jaraco authored
Showing with 75 additions and 47 deletions.
  1. +61 −47 path.py
  2. +14 −0 test_path.py
View
108 path.py
@@ -77,10 +77,27 @@ class path(unicode):
counterparts in os.path.
"""
+ # Use an alternate path module (e.g. posixpath)
+ module = os.path
+ _subclass_for_module = {}
+ @classmethod
+ def using_module(cls, module, value=None):
+ if module in cls._subclass_for_module:
+ subclass = cls._subclass_for_module[module]
+ else:
+ subclass_name = cls.__name__ + '_' + module.__name__
+ bases = (cls,)
+ ns = {'module': module}
+ subclass = type(subclass_name, bases, ns)
+ cls._subclass_for_module[module] = subclass
+ if value is None:
+ return subclass
+ return subclass(value)
+
# --- Special Python methods.
def __repr__(self):
- return 'path(%s)' % super(path, self).__repr__()
+ return '%s(%s)' % (type(self).__name__, super(path, self).__repr__())
# Adding a path and a string yields a path.
def __add__(self, more):
@@ -101,7 +118,7 @@ def __div__(self, rel):
Join two path components, adding a separator character if
needed.
"""
- return self.__class__(os.path.join(self, rel))
+ return self.__class__(self.module.join(self, rel))
# Make the / operator work even when true division is enabled.
__truediv__ = __div__
@@ -121,14 +138,14 @@ def getcwd(cls):
#
# --- Operations on path strings.
- def abspath(self): return self.__class__(os.path.abspath(self))
- def normcase(self): return self.__class__(os.path.normcase(self))
- def normpath(self): return self.__class__(os.path.normpath(self))
- def realpath(self): return self.__class__(os.path.realpath(self))
- def expanduser(self): return self.__class__(os.path.expanduser(self))
- def expandvars(self): return self.__class__(os.path.expandvars(self))
- def dirname(self): return self.__class__(os.path.dirname(self))
- def basename(self): return self.__class__(os.path.basename(self))
+ def abspath(self): return self.__class__(self.module.abspath(self))
+ def normcase(self): return self.__class__(self.module.normcase(self))
+ def normpath(self): return self.__class__(self.module.normpath(self))
+ def realpath(self): return self.__class__(self.module.realpath(self))
+ def expanduser(self): return self.__class__(self.module.expanduser(self))
+ def expandvars(self): return self.__class__(self.module.expandvars(self))
+ def dirname(self): return self.__class__(self.module.dirname(self))
+ def basename(self): return self.__class__(self.module.basename(self))
def expand(self):
""" Clean up a filename by calling expandvars(),
@@ -140,15 +157,15 @@ def expand(self):
return self.expandvars().expanduser().normpath()
def _get_namebase(self):
- base, ext = os.path.splitext(self.name)
+ base, ext = self.module.splitext(self.name)
return base
def _get_ext(self):
- f, ext = os.path.splitext(self)
+ f, ext = self.module.splitext(self)
return ext
def _get_drive(self):
- drive, r = os.path.splitdrive(self)
+ drive, r = self.module.splitdrive(self)
return self.__class__(drive)
parent = property(
@@ -185,7 +202,7 @@ def _get_drive(self):
def splitpath(self):
""" p.splitpath() -> Return (p.parent, p.name). """
- parent, child = os.path.split(self)
+ parent, child = self.module.split(self)
return self.__class__(parent), child
def splitdrive(self):
@@ -195,7 +212,7 @@ def splitdrive(self):
no drive specifier, p.drive is empty, so the return value
is simply (path(''), p). This is always the case on Unix.
"""
- drive, rel = os.path.splitdrive(self)
+ drive, rel = self.module.splitdrive(self)
return self.__class__(drive), rel
def splitext(self):
@@ -208,7 +225,7 @@ def splitext(self):
last path segment. This has the property that if
(a, b) == p.splitext(), then a + b == p.
"""
- filename, ext = os.path.splitext(self)
+ filename, ext = self.module.splitext(self)
return self.__class__(filename), ext
def stripext(self):
@@ -219,26 +236,25 @@ def stripext(self):
"""
return self.splitext()[0]
- if hasattr(os.path, 'splitunc'):
- def splitunc(self):
- unc, rest = os.path.splitunc(self)
- return self.__class__(unc), rest
+ def splitunc(self):
+ unc, rest = self.module.splitunc(self)
+ return self.__class__(unc), rest
- def _get_uncshare(self):
- unc, r = os.path.splitunc(self)
- return self.__class__(unc)
+ def _get_uncshare(self):
+ unc, r = self.module.splitunc(self)
+ return self.__class__(unc)
- uncshare = property(
- _get_uncshare, None, None,
- """ The UNC mount point for this path.
- This is empty for paths on local drives. """)
+ uncshare = property(
+ _get_uncshare, None, None,
+ """ The UNC mount point for this path.
+ This is empty for paths on local drives. """)
def joinpath(self, *args):
""" Join two or more path components, adding a separator
character (os.sep) if needed. Returns a new path
object.
"""
- return self.__class__(os.path.join(self, *args))
+ return self.__class__(self.module.join(self, *args))
def splitall(self):
r""" Return a list of the path components in this path.
@@ -283,14 +299,14 @@ def relpathto(self, dest):
# Don't normcase dest! We want to preserve the case.
dest_list = dest.splitall()
- if orig_list[0] != os.path.normcase(dest_list[0]):
+ if orig_list[0] != self.module.normcase(dest_list[0]):
# Can't get here from there.
return dest
# Find the location where the two paths start to differ.
i = 0
for start_seg, dest_seg in zip(orig_list, dest_list):
- if start_seg != os.path.normcase(dest_seg):
+ if start_seg != self.module.normcase(dest_seg):
break
i += 1
@@ -304,7 +320,7 @@ def relpathto(self, dest):
# If they happen to be identical, use os.curdir.
relpath = os.curdir
else:
- relpath = os.path.join(*segments)
+ relpath = self.module.join(*segments)
return self.__class__(relpath)
# --- Listing, searching, walking, and matching
@@ -796,33 +812,31 @@ def read_hexhash(self, hash_name):
# (e.g. isdir on Windows, Python 3.2.2), and compiled functions don't get
# bound. Playing it safe and wrapping them all in method calls.
- def isabs(self): return os.path.isabs(self)
- def exists(self): return os.path.exists(self)
- def isdir(self): return os.path.isdir(self)
- def isfile(self): return os.path.isfile(self)
- def islink(self): return os.path.islink(self)
- def ismount(self): return os.path.ismount(self)
+ def isabs(self): return self.module.isabs(self)
+ def exists(self): return self.module.exists(self)
+ def isdir(self): return self.module.isdir(self)
+ def isfile(self): return self.module.isfile(self)
+ def islink(self): return self.module.islink(self)
+ def ismount(self): return self.module.ismount(self)
- if hasattr(os.path, 'samefile'):
- def samefile(self): return os.path.samefile(self)
+ def samefile(self): return self.module.samefile(self)
- def getatime(self): return os.path.getatime(self)
+ def getatime(self): return self.module.getatime(self)
atime = property(
getatime, None, None,
""" Last access time of the file. """)
- def getmtime(self): return os.path.getmtime(self)
+ def getmtime(self): return self.module.getmtime(self)
mtime = property(
getmtime, None, None,
""" Last-modified time of the file. """)
- if hasattr(os.path, 'getctime'):
- def getctime(self): return os.path.getctime(self)
- ctime = property(
- getctime, None, None,
- """ Creation time of the file. """)
+ def getctime(self): return self.module.getctime(self)
+ ctime = property(
+ getctime, None, None,
+ """ Creation time of the file. """)
- def getsize(self): return os.path.getsize(self)
+ def getsize(self): return self.module.getsize(self)
size = property(
getsize, None, None,
""" Size of the file, in bytes. """)
View
14 test_path.py
@@ -27,6 +27,8 @@
import shutil
import tempfile
import time
+import ntpath
+import posixpath
from path import path, __version__ as path_version
@@ -127,6 +129,18 @@ def testUNC(self):
self.assert_(p.uncshare == r'\\python1\share1')
self.assert_(p.splitunc() == os.path.splitunc(str(p)))
+ def testExplicitModule(self):
+ nt_ok = path.using_module(ntpath, r'foo\bar\baz')
+ posix_ok = path.using_module(posixpath, r'foo/bar/baz')
+ posix_wrong = path.using_module(posixpath, r'foo\bar\baz')
+
+ self.assertEqual(nt_ok.dirname(), r'foo\bar')
+ self.assertEqual(posix_ok.dirname(), r'foo/bar')
+ self.assertEqual(posix_wrong.dirname(), '')
+
+ self.assertEqual(nt_ok / 'quux', r'foo\bar\baz\quux')
+ self.assertEqual(posix_ok / 'quux', r'foo/bar/baz/quux')
+
class ReturnSelfTestCase(unittest.TestCase):
def setUp(self):
# Create a temporary directory.
Please sign in to comment.
Something went wrong with that request. Please try again.