move localpath implementation to a single file, simplify unix/posix difference and fix a bit
--HG-- branch : trunk
This commit is contained in:
		
							parent
							
								
									079a2327ec
								
							
						
					
					
						commit
						561fdca3a2
					
				|  | @ -1,6 +1,6 @@ | ||||||
| 
 | 
 | ||||||
|          |          | ||||||
| py.test --dist=each $* \ | py.test --dist=each $* \ | ||||||
|     --tx 'popen//python=python2.6' \ |  | ||||||
|     --tx 'ssh=noco//python=/usr/local/bin/python2.4//chdir=/tmp/pytest-python2.4' \ |  | ||||||
|     --tx 'socket=192.168.1.106:8888' |     --tx 'socket=192.168.1.106:8888' | ||||||
|  |     #--tx 'popen//python=python2.6' \ | ||||||
|  |     #--tx 'ssh=noco//python=/usr/local/bin/python2.4//chdir=/tmp/pytest-python2.4' \ | ||||||
|  |  | ||||||
|  | @ -1,3 +1,8 @@ | ||||||
|  | Changes between 1.0.x and 'trunk' | ||||||
|  | ===================================== | ||||||
|  | 
 | ||||||
|  | * simplified internal localpath implementation  | ||||||
|  | 
 | ||||||
| Changes between 1.0.0 and 1.0.1 | Changes between 1.0.0 and 1.0.1 | ||||||
| ===================================== | ===================================== | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -106,7 +106,7 @@ initpkg(__name__, | ||||||
|     'path.__doc__'           : ('./path/__init__.py', '__doc__'), |     'path.__doc__'           : ('./path/__init__.py', '__doc__'), | ||||||
|     'path.svnwc'             : ('./path/svn/wccommand.py', 'SvnWCCommandPath'), |     'path.svnwc'             : ('./path/svn/wccommand.py', 'SvnWCCommandPath'), | ||||||
|     'path.svnurl'            : ('./path/svn/urlcommand.py', 'SvnCommandPath'), |     'path.svnurl'            : ('./path/svn/urlcommand.py', 'SvnCommandPath'), | ||||||
|     'path.local'             : ('./path/local/local.py', 'LocalPath'), |     'path.local'             : ('./path/local.py', 'LocalPath'), | ||||||
|     'path.SvnAuth'           : ('./path/svn/svncommon.py', 'SvnAuth'), |     'path.SvnAuth'           : ('./path/svn/svncommon.py', 'SvnAuth'), | ||||||
| 
 | 
 | ||||||
|     # some nice slightly magic APIs |     # some nice slightly magic APIs | ||||||
|  |  | ||||||
|  | @ -1,9 +1,5 @@ | ||||||
| """ | """ | ||||||
| specialized local path implementation. | local path implementation. | ||||||
| 
 |  | ||||||
| This Path implementation offers some methods like chmod(), owner() |  | ||||||
| and so on that may only make sense on unix. |  | ||||||
| 
 |  | ||||||
| """ | """ | ||||||
| from __future__ import generators | from __future__ import generators | ||||||
| import sys, os, stat, re, atexit | import sys, os, stat, re, atexit | ||||||
|  | @ -12,17 +8,93 @@ from py.__.path import common | ||||||
| 
 | 
 | ||||||
| iswin32 = sys.platform == "win32" | iswin32 = sys.platform == "win32" | ||||||
| 
 | 
 | ||||||
| if iswin32:  | class Stat(object): | ||||||
|     from py.__.path.local.win import WinMixin as PlatformMixin |     pformat = "%s = property(lambda x: getattr(x._osstatresult, 'st_%s'))" | ||||||
| else: |  | ||||||
|     from py.__.path.local.posix import PosixMixin as PlatformMixin |  | ||||||
| 
 | 
 | ||||||
| class LocalPath(common.FSPathBase, PlatformMixin): |     for name in ('atime blksize blocks ctime dev gid '  | ||||||
|     """ Local path implementation offering access/modification |                  'ino mode mtime nlink rdev size uid'.split()): | ||||||
|         methods similar to os.path. |         code = pformat.replace("%s", name) | ||||||
|  |         exec code  | ||||||
|  | 
 | ||||||
|  |     def __init__(self, path, osstatresult):  | ||||||
|  |         self.path = path  | ||||||
|  |         self._osstatresult = osstatresult | ||||||
|  | 
 | ||||||
|  |     def owner(self): | ||||||
|  |         if iswin32: | ||||||
|  |             raise NotImplementedError("XXX win32") | ||||||
|  |         import pwd  | ||||||
|  |         entry = self.path._callex(pwd.getpwuid, self.uid) | ||||||
|  |         return entry[0] | ||||||
|  |     owner = property(owner, None, None, "owner of path")  | ||||||
|  | 
 | ||||||
|  |     def group(self): | ||||||
|  |         """ return group name of file. """ | ||||||
|  |         if iswin32: | ||||||
|  |             raise NotImplementedError("XXX win32") | ||||||
|  |         import grp | ||||||
|  |         entry = self.path._callex(grp.getgrgid, self.gid) | ||||||
|  |         return entry[0] | ||||||
|  |     group = property(group)  | ||||||
|  | 
 | ||||||
|  | class PosixPath(common.FSPathBase): | ||||||
|  |     def chown(self, user, group, rec=0): | ||||||
|  |         """ change ownership to the given user and group. | ||||||
|  |             user and group may be specified by a number or | ||||||
|  |             by a name.  if rec is True change ownership | ||||||
|  |             recursively. | ||||||
|         """ |         """ | ||||||
|     _path_cache = {} |         uid = getuserid(user) | ||||||
|  |         gid = getgroupid(group) | ||||||
|  |         if rec: | ||||||
|  |             for x in self.visit(rec=lambda x: x.check(link=0)):  | ||||||
|  |                 if x.check(link=0): | ||||||
|  |                     self._callex(os.chown, str(x), uid, gid) | ||||||
|  |         self._callex(os.chown, str(self), uid, gid) | ||||||
| 
 | 
 | ||||||
|  |     def readlink(self): | ||||||
|  |         """ return value of a symbolic link. """ | ||||||
|  |         return self._callex(os.readlink, self.strpath) | ||||||
|  | 
 | ||||||
|  |     def mklinkto(self, oldname): | ||||||
|  |         """ posix style hard link to another name. """ | ||||||
|  |         self._callex(os.link, str(oldname), str(self)) | ||||||
|  | 
 | ||||||
|  |     def mksymlinkto(self, value, absolute=1): | ||||||
|  |         """ create a symbolic link with the given value (pointing to another name). """ | ||||||
|  |         if absolute: | ||||||
|  |             self._callex(os.symlink, str(value), self.strpath) | ||||||
|  |         else: | ||||||
|  |             base = self.common(value) | ||||||
|  |             # with posix local paths '/' is always a common base | ||||||
|  |             relsource = self.__class__(value).relto(base) | ||||||
|  |             reldest = self.relto(base) | ||||||
|  |             n = reldest.count(self.sep) | ||||||
|  |             target = self.sep.join(('..', )*n + (relsource, )) | ||||||
|  |             self._callex(os.symlink, target, self.strpath) | ||||||
|  | 
 | ||||||
|  |     def samefile(self, other): | ||||||
|  |         """ return True if other refers to the same stat object as self. """ | ||||||
|  |         return py.std.os.path.samefile(str(self), str(other)) | ||||||
|  | 
 | ||||||
|  | def getuserid(user): | ||||||
|  |     import pwd | ||||||
|  |     if not isinstance(user, int): | ||||||
|  |         user = pwd.getpwnam(user)[2] | ||||||
|  |     return user | ||||||
|  | 
 | ||||||
|  | def getgroupid(group): | ||||||
|  |     import grp | ||||||
|  |     if not isinstance(group, int): | ||||||
|  |         group = grp.getgrnam(group)[2] | ||||||
|  |     return group | ||||||
|  | 
 | ||||||
|  | FSBase = not iswin32 and PosixPath or common.FSPathBase | ||||||
|  | 
 | ||||||
|  | class LocalPath(FSBase): | ||||||
|  |     """ object oriented interface to os.path and other local filesystem  | ||||||
|  |         related information.  | ||||||
|  |     """ | ||||||
|     sep = os.sep |     sep = os.sep | ||||||
|     class Checkers(common.FSCheckers): |     class Checkers(common.FSCheckers): | ||||||
|         def _stat(self): |         def _stat(self): | ||||||
|  | @ -76,6 +148,21 @@ class LocalPath(common.FSPathBase, PlatformMixin): | ||||||
|     def __hash__(self): |     def __hash__(self): | ||||||
|         return hash(self.strpath) |         return hash(self.strpath) | ||||||
| 
 | 
 | ||||||
|  |     def remove(self, rec=1): | ||||||
|  |         """ remove a file or directory (or a directory tree if rec=1).  """ | ||||||
|  |         if self.check(dir=1, link=0): | ||||||
|  |             if rec: | ||||||
|  |                 # force remove of readonly files on windows  | ||||||
|  |                 if iswin32:  | ||||||
|  |                     self.chmod(0700, rec=1) | ||||||
|  |                 self._callex(py.std.shutil.rmtree, self.strpath) | ||||||
|  |             else: | ||||||
|  |                 self._callex(os.rmdir, self.strpath) | ||||||
|  |         else: | ||||||
|  |             if iswin32:  | ||||||
|  |                 self.chmod(0700) | ||||||
|  |             self._callex(os.remove, self.strpath) | ||||||
|  | 
 | ||||||
|     def computehash(self, hashtype="md5", chunksize=524288): |     def computehash(self, hashtype="md5", chunksize=524288): | ||||||
|         """ return hexdigest of hashvalue for this file. """ |         """ return hexdigest of hashvalue for this file. """ | ||||||
|         hash = self._gethashinstance(hashtype) |         hash = self._gethashinstance(hashtype) | ||||||
|  | @ -311,14 +398,12 @@ class LocalPath(common.FSPathBase, PlatformMixin): | ||||||
| 
 | 
 | ||||||
|     def stat(self): |     def stat(self): | ||||||
|         """ Return an os.stat() tuple. """ |         """ Return an os.stat() tuple. """ | ||||||
|         stat = self._callex(os.stat, self.strpath) |         return Stat(self, self._callex(os.stat, self.strpath)) | ||||||
|         return self._makestat(stat) |  | ||||||
| 
 | 
 | ||||||
|     def lstat(self): |     def lstat(self): | ||||||
|         """ Return an os.lstat() tuple. """ |         """ Return an os.lstat() tuple. """ | ||||||
|         return self._makestat(self._callex(os.lstat, self.strpath)) |         return Stat(self, self._callex(os.lstat, self.strpath)) | ||||||
| 
 | 
 | ||||||
|     # xlocal implementation |  | ||||||
|     def setmtime(self, mtime=None): |     def setmtime(self, mtime=None): | ||||||
|         """ set modification time for the given path.  if 'mtime' is None |         """ set modification time for the given path.  if 'mtime' is None | ||||||
|         (the default) then the file's mtime is set to current time. |         (the default) then the file's mtime is set to current time. | ||||||
|  | @ -379,6 +464,18 @@ class LocalPath(common.FSPathBase, PlatformMixin): | ||||||
|             #print "prepending to sys.path", s |             #print "prepending to sys.path", s | ||||||
|             sys.path.insert(0, s) |             sys.path.insert(0, s) | ||||||
| 
 | 
 | ||||||
|  |     def chmod(self, mode, rec=0): | ||||||
|  |         """ change permissions to the given mode. If mode is an | ||||||
|  |             integer it directly encodes the os-specific modes. | ||||||
|  |             if rec is True perform recursively. | ||||||
|  |         """ | ||||||
|  |         if not isinstance(mode, int): | ||||||
|  |             raise TypeError("mode %r must be an integer" % (mode,)) | ||||||
|  |         if rec: | ||||||
|  |             for x in self.visit(rec=rec): | ||||||
|  |                 self._callex(os.chmod, str(x), mode) | ||||||
|  |         self._callex(os.chmod, str(self), mode) | ||||||
|  | 
 | ||||||
|     def pyimport(self, modname=None, ensuresyspath=True): |     def pyimport(self, modname=None, ensuresyspath=True): | ||||||
|         """ return path as an imported python module. |         """ return path as an imported python module. | ||||||
|             if modname is None, look for the containing package |             if modname is None, look for the containing package | ||||||
|  | @ -438,7 +535,7 @@ class LocalPath(common.FSPathBase, PlatformMixin): | ||||||
| 
 | 
 | ||||||
|     def _getpycodeobj(self): |     def _getpycodeobj(self): | ||||||
|         """ read the path and compile it to a code object. """ |         """ read the path and compile it to a code object. """ | ||||||
|         dotpy = self.check(ext='.py') |         dotpy = self.ext == ".py" | ||||||
|         if dotpy: |         if dotpy: | ||||||
|             my_magic     = py.std.imp.get_magic() |             my_magic     = py.std.imp.get_magic() | ||||||
|             my_timestamp = int(self.mtime()) |             my_timestamp = int(self.mtime()) | ||||||
|  | @ -1 +0,0 @@ | ||||||
| # |  | ||||||
|  | @ -1,25 +0,0 @@ | ||||||
| import py |  | ||||||
| 
 |  | ||||||
| class Stat(object): |  | ||||||
|     def __init__(self, path, osstatresult):  |  | ||||||
|         self.path = path  |  | ||||||
|         self._osstatresult = osstatresult |  | ||||||
| 
 |  | ||||||
|     for name in ('atime blksize blocks ctime dev gid '  |  | ||||||
|                  'ino mode mtime nlink rdev size uid'.split()): |  | ||||||
|          |  | ||||||
|         code = """if 1: |  | ||||||
|             def fget(self): |  | ||||||
|                 return getattr(self._osstatresult, "st_%(name)s", None) |  | ||||||
|             %(name)s = property(fget) |  | ||||||
|             def fget_deprecated(self): |  | ||||||
|                 py.std.warnings.warn("statresult.st_%(name)s is deprecated, use " |  | ||||||
|                                      "statresult.%(name)s instead.",  |  | ||||||
|                                      DeprecationWarning, stacklevel=2) |  | ||||||
|                 return getattr(self._osstatresult, "st_%(name)s", None) |  | ||||||
|             st_%(name)s = property(fget_deprecated) |  | ||||||
| """ % locals() |  | ||||||
|         exec code |  | ||||||
|     del fget  |  | ||||||
|     del fget_deprecated |  | ||||||
| 
 |  | ||||||
|  | @ -1,129 +0,0 @@ | ||||||
| """ |  | ||||||
| module to access local filesystem pathes |  | ||||||
| (mostly filename manipulations but also file operations) |  | ||||||
| """ |  | ||||||
| import os, sys, stat |  | ||||||
| 
 |  | ||||||
| import py |  | ||||||
| #__________________________________________________________ |  | ||||||
| # |  | ||||||
| # Local Path Posix Mixin |  | ||||||
| #__________________________________________________________ |  | ||||||
| 
 |  | ||||||
| from py.__.path.local.common import Stat  |  | ||||||
| 
 |  | ||||||
| class PosixStat(Stat): |  | ||||||
|     def owner(self): |  | ||||||
|         entry = self.path._callex(py.std.pwd.getpwuid, self.uid) |  | ||||||
|         return entry[0] |  | ||||||
|     owner = property(owner, None, None, "owner of path")  |  | ||||||
| 
 |  | ||||||
|     def group(self): |  | ||||||
|         """ return group name of file. """ |  | ||||||
|         entry = self.path._callex(py.std.grp.getgrgid, self.gid) |  | ||||||
|         return entry[0] |  | ||||||
|     group = property(group)  |  | ||||||
| 
 |  | ||||||
| class PosixMixin(object): |  | ||||||
|     def _makestat(self, statresult):  |  | ||||||
|         return PosixStat(self, statresult)  |  | ||||||
| 
 |  | ||||||
|     def _deprecated(self, name):  |  | ||||||
|         py.std.warnings.warn("'path.%s()' is deprecated, use " |  | ||||||
|                              "'path.stat().%s' instead." % (name,name), |  | ||||||
|                              DeprecationWarning, stacklevel=3) |  | ||||||
|      |  | ||||||
|     # an instance needs to be a local path instance |  | ||||||
|     def owner(self): |  | ||||||
|         """ return owner name of file. """ |  | ||||||
|         self._deprecated('owner') |  | ||||||
|         return self.stat().owner  |  | ||||||
| 
 |  | ||||||
|     def group(self): |  | ||||||
|         """ return group name of file. """ |  | ||||||
|         self._deprecated('group') |  | ||||||
|         return self.stat().group  |  | ||||||
| 
 |  | ||||||
|     def mode(self): |  | ||||||
|         """ return permission mode of the path object """ |  | ||||||
|         self._deprecated('mode') |  | ||||||
|         return self.stat().mode |  | ||||||
| 
 |  | ||||||
|     def chmod(self, mode, rec=0): |  | ||||||
|         """ change permissions to the given mode. If mode is an |  | ||||||
|             integer it directly encodes the os-specific modes. |  | ||||||
|             if rec is True perform recursively. |  | ||||||
| 
 |  | ||||||
|             (xxx if mode is a string then it specifies access rights |  | ||||||
|             in '/bin/chmod' style, e.g. a+r). |  | ||||||
|         """ |  | ||||||
|         if not isinstance(mode, int): |  | ||||||
|             raise TypeError("mode %r must be an integer" % (mode,)) |  | ||||||
|         if rec: |  | ||||||
|             for x in self.visit(rec=rec): |  | ||||||
|                 self._callex(os.chmod, str(x), mode) |  | ||||||
|         self._callex(os.chmod, str(self), mode) |  | ||||||
| 
 |  | ||||||
|     def chown(self, user, group, rec=0): |  | ||||||
|         """ change ownership to the given user and group. |  | ||||||
|             user and group may be specified by a number or |  | ||||||
|             by a name.  if rec is True change ownership |  | ||||||
|             recursively. |  | ||||||
|         """ |  | ||||||
|         uid = getuserid(user) |  | ||||||
|         gid = getgroupid(group) |  | ||||||
|         if rec: |  | ||||||
|             for x in self.visit(rec=lambda x: x.check(link=0)):  |  | ||||||
|                 if x.check(link=0): |  | ||||||
|                     self._callex(os.chown, str(x), uid, gid) |  | ||||||
|         self._callex(os.chown, str(self), uid, gid) |  | ||||||
| 
 |  | ||||||
|     def readlink(self): |  | ||||||
|         """ return value of a symbolic link. """ |  | ||||||
|         return self._callex(os.readlink, self.strpath) |  | ||||||
| 
 |  | ||||||
|     def mklinkto(self, oldname): |  | ||||||
|         """ posix style hard link to another name. """ |  | ||||||
|         self._callex(os.link, str(oldname), str(self)) |  | ||||||
| 
 |  | ||||||
|     def mksymlinkto(self, value, absolute=1): |  | ||||||
|         """ create a symbolic link with the given value (pointing to another name). """ |  | ||||||
|         if absolute: |  | ||||||
|             self._callex(os.symlink, str(value), self.strpath) |  | ||||||
|         else: |  | ||||||
|             base = self.common(value) |  | ||||||
|             # with posix local paths '/' is always a common base |  | ||||||
|             relsource = self.__class__(value).relto(base) |  | ||||||
|             reldest = self.relto(base) |  | ||||||
|             n = reldest.count(self.sep) |  | ||||||
|             target = self.sep.join(('..', )*n + (relsource, )) |  | ||||||
|             self._callex(os.symlink, target, self.strpath) |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
|     def remove(self, rec=1): |  | ||||||
|         """ remove a file or directory (or a directory tree if rec=1).  """ |  | ||||||
|         if self.check(dir=1, link=0): |  | ||||||
|             if rec: |  | ||||||
|                 self._callex(py.std.shutil.rmtree, self.strpath) |  | ||||||
|             else: |  | ||||||
|                 self._callex(os.rmdir, self.strpath) |  | ||||||
|         else: |  | ||||||
|             self._callex(os.remove, self.strpath) |  | ||||||
| 
 |  | ||||||
|     def samefile(self, other): |  | ||||||
|         """ return True if other refers to the same stat object as self. """ |  | ||||||
|         return py.std.os.path.samefile(str(self), str(other)) |  | ||||||
| 
 |  | ||||||
| def getuserid(user): |  | ||||||
|     import pwd |  | ||||||
|     if isinstance(user, int): |  | ||||||
|         return user |  | ||||||
|     entry = pwd.getpwnam(user) |  | ||||||
|     return entry[2] |  | ||||||
| 
 |  | ||||||
| def getgroupid(group): |  | ||||||
|     import grp |  | ||||||
|     if isinstance(group, int): |  | ||||||
|         return group |  | ||||||
|     entry = grp.getgrnam(group) |  | ||||||
|     return entry[2] |  | ||||||
|  | @ -1 +0,0 @@ | ||||||
| # |  | ||||||
|  | @ -1,190 +0,0 @@ | ||||||
| import py |  | ||||||
| 
 |  | ||||||
| class TestPOSIXLocalPath: |  | ||||||
|     disabled = py.std.sys.platform == 'win32' |  | ||||||
| 
 |  | ||||||
|     def setup_class(cls): |  | ||||||
|         cls.root = py.test.ensuretemp(cls.__name__)  |  | ||||||
| 
 |  | ||||||
|     def setup_method(self, method):  |  | ||||||
|         name = method.im_func.func_name |  | ||||||
|         self.tmpdir = self.root.ensure(name, dir=1)  |  | ||||||
| 
 |  | ||||||
|     def test_samefile(self): |  | ||||||
|         assert self.tmpdir.samefile(self.tmpdir) |  | ||||||
|         p = self.tmpdir.ensure("hello") |  | ||||||
|         assert p.samefile(p)  |  | ||||||
| 
 |  | ||||||
|     def test_hardlink(self): |  | ||||||
|         tmpdir = self.tmpdir  |  | ||||||
|         linkpath = tmpdir.join('test') |  | ||||||
|         filepath = tmpdir.join('file') |  | ||||||
|         filepath.write("Hello") |  | ||||||
|         nlink = filepath.stat().st_nlink  |  | ||||||
|         linkpath.mklinkto(filepath) |  | ||||||
|         assert filepath.stat().st_nlink == nlink + 1  |  | ||||||
| 
 |  | ||||||
|     def test_symlink_are_identical(self): |  | ||||||
|         tmpdir = self.tmpdir  |  | ||||||
|         filepath = tmpdir.join('file') |  | ||||||
|         filepath.write("Hello") |  | ||||||
|         linkpath = tmpdir.join('test') |  | ||||||
|         linkpath.mksymlinkto(filepath) |  | ||||||
|         assert linkpath.readlink() == str(filepath)  |  | ||||||
| 
 |  | ||||||
|     def test_symlink_isfile(self): |  | ||||||
|         tmpdir = self.tmpdir  |  | ||||||
|         linkpath = tmpdir.join('test') |  | ||||||
|         filepath = tmpdir.join('file') |  | ||||||
|         filepath.write("") |  | ||||||
|         linkpath.mksymlinkto(filepath) |  | ||||||
|         assert linkpath.check(file=1) |  | ||||||
|         assert not linkpath.check(link=0, file=1) |  | ||||||
| 
 |  | ||||||
|     def test_symlink_relative(self): |  | ||||||
|         tmpdir = self.tmpdir  |  | ||||||
|         linkpath = tmpdir.join('test') |  | ||||||
|         filepath = tmpdir.join('file') |  | ||||||
|         filepath.write("Hello") |  | ||||||
|         linkpath.mksymlinkto(filepath, absolute=False) |  | ||||||
|         assert linkpath.readlink() == "file" |  | ||||||
|         assert filepath.read() == linkpath.read() |  | ||||||
| 
 |  | ||||||
|     def test_symlink_not_existing(self): |  | ||||||
|         tmpdir = self.tmpdir  |  | ||||||
|         linkpath = tmpdir.join('testnotexisting') |  | ||||||
|         assert not linkpath.check(link=1) |  | ||||||
|         assert linkpath.check(link=0) |  | ||||||
| 
 |  | ||||||
|     def test_relto_with_root(self): |  | ||||||
|         y = self.root.join('x').relto(py.path.local('/')) |  | ||||||
|         assert y[0] == str(self.root)[1] |  | ||||||
| 
 |  | ||||||
|     def test_visit_recursive_symlink(self): |  | ||||||
|         tmpdir = self.tmpdir  |  | ||||||
|         linkpath = tmpdir.join('test') |  | ||||||
|         linkpath.mksymlinkto(tmpdir) |  | ||||||
|         visitor = tmpdir.visit(None, lambda x: x.check(link=0)) |  | ||||||
|         assert list(visitor) == [linkpath] |  | ||||||
| 
 |  | ||||||
|     def test_symlink_isdir(self): |  | ||||||
|         tmpdir = self.tmpdir  |  | ||||||
|         linkpath = tmpdir.join('test') |  | ||||||
|         linkpath.mksymlinkto(tmpdir) |  | ||||||
|         assert linkpath.check(dir=1) |  | ||||||
|         assert not linkpath.check(link=0, dir=1) |  | ||||||
| 
 |  | ||||||
|     def test_symlink_remove(self): |  | ||||||
|         tmpdir = self.tmpdir.realpath()  |  | ||||||
|         linkpath = tmpdir.join('test') |  | ||||||
|         linkpath.mksymlinkto(linkpath) # point to itself |  | ||||||
|         assert linkpath.check(link=1) |  | ||||||
|         linkpath.remove() |  | ||||||
|         assert not linkpath.check() |  | ||||||
| 
 |  | ||||||
|     def test_realpath_file(self): |  | ||||||
|         tmpdir = self.tmpdir  |  | ||||||
|         linkpath = tmpdir.join('test') |  | ||||||
|         filepath = tmpdir.join('file') |  | ||||||
|         filepath.write("") |  | ||||||
|         linkpath.mksymlinkto(filepath) |  | ||||||
|         realpath = linkpath.realpath() |  | ||||||
|         assert realpath.basename == 'file' |  | ||||||
| 
 |  | ||||||
|     def test_owner(self): |  | ||||||
|         from pwd import getpwuid |  | ||||||
|         from grp import getgrgid |  | ||||||
|         stat = self.root.stat() |  | ||||||
|         assert stat.path == self.root  |  | ||||||
| 
 |  | ||||||
|         uid = stat.st_uid  |  | ||||||
|         gid = stat.st_gid  |  | ||||||
|         owner = getpwuid(uid)[0] |  | ||||||
|         group = getgrgid(gid)[0] |  | ||||||
| 
 |  | ||||||
|         assert uid == stat.uid  |  | ||||||
|         assert owner == stat.owner  |  | ||||||
|         assert gid == stat.gid  |  | ||||||
|         assert group == stat.group  |  | ||||||
| 
 |  | ||||||
|     def test_atime(self): |  | ||||||
|         import time |  | ||||||
|         path = self.root.ensure('samplefile') |  | ||||||
|         now = time.time() |  | ||||||
|         atime1 = path.atime() |  | ||||||
|         # we could wait here but timer resolution is very |  | ||||||
|         # system dependent  |  | ||||||
|         path.read() |  | ||||||
|         atime2 = path.atime() |  | ||||||
|         duration = time.time() - now |  | ||||||
|         assert (atime2-atime1) <= duration |  | ||||||
| 
 |  | ||||||
|     def test_commondir(self): |  | ||||||
|         # XXX This is here in local until we find a way to implement this |  | ||||||
|         #     using the subversion command line api. |  | ||||||
|         p1 = self.root.join('something') |  | ||||||
|         p2 = self.root.join('otherthing') |  | ||||||
|         assert p1.common(p2) == self.root |  | ||||||
|         assert p2.common(p1) == self.root |  | ||||||
| 
 |  | ||||||
|     def test_commondir_nocommon(self): |  | ||||||
|         # XXX This is here in local until we find a way to implement this |  | ||||||
|         #     using the subversion command line api. |  | ||||||
|         p1 = self.root.join('something') |  | ||||||
|         p2 = py.path.local(self.root.sep+'blabla') |  | ||||||
|         assert p1.common(p2) == '/'  |  | ||||||
| 
 |  | ||||||
|     def test_join_to_root(self):  |  | ||||||
|         root = self.root.parts()[0] |  | ||||||
|         assert len(str(root)) == 1 |  | ||||||
|         assert str(root.join('a')) == '/a' |  | ||||||
| 
 |  | ||||||
|     def test_join_root_to_root_with_no_abs(self):  |  | ||||||
|         nroot = self.root.join('/') |  | ||||||
|         assert str(self.root) == str(nroot)  |  | ||||||
|         assert self.root == nroot  |  | ||||||
| 
 |  | ||||||
|     def test_chmod_simple_int(self): |  | ||||||
|         print "self.root is", self.root |  | ||||||
|         mode = self.root.mode() |  | ||||||
|         self.root.chmod(mode/2) |  | ||||||
|         try: |  | ||||||
|             assert self.root.mode() != mode |  | ||||||
|         finally: |  | ||||||
|             self.root.chmod(mode) |  | ||||||
|             assert self.root.mode() == mode |  | ||||||
| 
 |  | ||||||
|     def test_chmod_rec_int(self): |  | ||||||
|         # XXX fragile test |  | ||||||
|         print "self.root is", self.root |  | ||||||
|         recfilter = lambda x: x.check(dotfile=0, link=0) |  | ||||||
|         oldmodes = {} |  | ||||||
|         for x in self.root.visit(rec=recfilter): |  | ||||||
|             oldmodes[x] = x.mode() |  | ||||||
|         self.root.chmod(0772, rec=recfilter) |  | ||||||
|         try: |  | ||||||
|             for x in self.root.visit(rec=recfilter): |  | ||||||
|                 assert x.mode() & 0777 == 0772 |  | ||||||
|         finally: |  | ||||||
|             for x,y in oldmodes.items(): |  | ||||||
|                 x.chmod(y) |  | ||||||
| 
 |  | ||||||
|     def test_chown_identity(self): |  | ||||||
|         owner = self.root.owner() |  | ||||||
|         group = self.root.group() |  | ||||||
|         self.root.chown(owner, group) |  | ||||||
| 
 |  | ||||||
|     def test_chown_dangling_link(self): |  | ||||||
|         owner = self.root.owner() |  | ||||||
|         group = self.root.group() |  | ||||||
|         x = self.root.join('hello') |  | ||||||
|         x.mksymlinkto('qlwkejqwlek') |  | ||||||
|         try: |  | ||||||
|             self.root.chown(owner, group, rec=1) |  | ||||||
|         finally: |  | ||||||
|             x.remove(rec=0) |  | ||||||
| 
 |  | ||||||
|     def test_chown_identity_rec_mayfail(self): |  | ||||||
|         owner = self.root.owner() |  | ||||||
|         group = self.root.group() |  | ||||||
|         self.root.chown(owner, group) |  | ||||||
|  | @ -1,56 +0,0 @@ | ||||||
| import py |  | ||||||
| 
 |  | ||||||
| class TestWINLocalPath: |  | ||||||
|     #root = local(TestLocalPath.root) |  | ||||||
|     disabled = py.std.sys.platform != 'win32' |  | ||||||
| 
 |  | ||||||
|     def setup_class(cls): |  | ||||||
|         cls.root = py.test.ensuretemp(cls.__name__)  |  | ||||||
| 
 |  | ||||||
|     def setup_method(self, method):  |  | ||||||
|         name = method.im_func.func_name |  | ||||||
|         self.tmpdir = self.root.ensure(name, dir=1)  |  | ||||||
| 
 |  | ||||||
|     def test_chmod_simple_int(self): |  | ||||||
|         print "self.root is", self.root |  | ||||||
|         mode = self.root.stat().st_mode |  | ||||||
|         # Ensure that we actually change the mode to something different. |  | ||||||
|         self.root.chmod(mode == 0 and 1 or 0) |  | ||||||
|         try: |  | ||||||
|             print self.root.stat().st_mode  |  | ||||||
|             print mode |  | ||||||
|             assert self.root.stat().st_mode != mode |  | ||||||
|         finally: |  | ||||||
|             self.root.chmod(mode) |  | ||||||
|             assert self.root.stat().st_mode == mode |  | ||||||
| 
 |  | ||||||
|     def test_path_comparison_lowercase_mixed(self): |  | ||||||
|         t1 = self.root.join("a_path") |  | ||||||
|         t2 = self.root.join("A_path") |  | ||||||
|         assert t1 == t1 |  | ||||||
|         assert t1 == t2 |  | ||||||
|          |  | ||||||
|     def test_relto_with_mixed_case(self): |  | ||||||
|         t1 = self.root.join("a_path", "fiLe") |  | ||||||
|         t2 = self.root.join("A_path") |  | ||||||
|         assert t1.relto(t2) == "fiLe" |  | ||||||
| 
 |  | ||||||
|     def test_allow_unix_style_paths(self): |  | ||||||
|         t1 = self.root.join('a_path') |  | ||||||
|         assert t1 == str(self.root) + '\\a_path' |  | ||||||
|         t1 = self.root.join('a_path/') |  | ||||||
|         assert t1 == str(self.root) + '\\a_path' |  | ||||||
|         t1 = self.root.join('dir/a_path') |  | ||||||
|         assert t1 == str(self.root) + '\\dir\\a_path' |  | ||||||
| 
 |  | ||||||
|     def test_sysfind_in_currentdir(self):                                                                          |  | ||||||
|         cmd = py.path.local.sysfind('cmd')                                                                         |  | ||||||
|         root = cmd.new(dirname='', basename='') # c:\ in most installations                                        |  | ||||||
|                                                                                                                    |  | ||||||
|         old = root.chdir()                                                                                         |  | ||||||
|         try:                                                                                                       |  | ||||||
|             x = py.path.local.sysfind(cmd.relto(root))                                                             |  | ||||||
|             assert x.check(file=1)                                                                                 |  | ||||||
|         finally:                                                                                                   |  | ||||||
|              old.chdir()     |  | ||||||
| 
 |  | ||||||
|  | @ -1,41 +0,0 @@ | ||||||
| """ |  | ||||||
| module for win-specific local path stuff |  | ||||||
| 
 |  | ||||||
| (implementor needed :-) |  | ||||||
| """ |  | ||||||
| 
 |  | ||||||
| import os |  | ||||||
| import py |  | ||||||
| from py.__.path.local.common import Stat  |  | ||||||
| 
 |  | ||||||
| class WinMixin: |  | ||||||
|     def _makestat(self, statresult): |  | ||||||
|         return Stat(self, statresult) |  | ||||||
| 
 |  | ||||||
|     def chmod(self, mode, rec=0): |  | ||||||
|         """ change permissions to the given mode. If mode is an |  | ||||||
|             integer it directly encodes the os-specific modes. |  | ||||||
|             if rec is True perform recursively. |  | ||||||
| 
 |  | ||||||
|             (xxx if mode is a string then it specifies access rights |  | ||||||
|             in '/bin/chmod' style, e.g. a+r). |  | ||||||
|         """ |  | ||||||
|         if not isinstance(mode, int): |  | ||||||
|             raise TypeError("mode %r must be an integer" % (mode,)) |  | ||||||
|         if rec: |  | ||||||
|             for x in self.visit(rec=rec): |  | ||||||
|                 self._callex(os.chmod, str(x), mode) |  | ||||||
|         self._callex(os.chmod, str(self), mode) |  | ||||||
| 
 |  | ||||||
|     def remove(self, rec=1): |  | ||||||
|         """ remove a file or directory (or a directory tree if rec=1).  """ |  | ||||||
|         if self.check(dir=1, link=0): |  | ||||||
|             if rec: |  | ||||||
|                 # force remove of readonly files on windows  |  | ||||||
|                 self.chmod(0700, rec=1) |  | ||||||
|                 self._callex(py.std.shutil.rmtree, self.strpath) |  | ||||||
|             else: |  | ||||||
|                 self._callex(os.rmdir, self.strpath) |  | ||||||
|         else: |  | ||||||
|             self.chmod(0700) |  | ||||||
|             self._callex(os.remove, self.strpath) |  | ||||||
|  | @ -94,8 +94,6 @@ class CommonFSTests(common.CommonPathTests): | ||||||
|         assert not self.root.join("sampledir").check(file=1) |         assert not self.root.join("sampledir").check(file=1) | ||||||
|         assert self.root.join("sampledir").check(file=0) |         assert self.root.join("sampledir").check(file=0) | ||||||
| 
 | 
 | ||||||
|     #def test_fnmatch_dir(self): |  | ||||||
| 
 |  | ||||||
|     def test_non_existent(self): |     def test_non_existent(self): | ||||||
|         assert self.root.join("sampledir.nothere").check(dir=0) |         assert self.root.join("sampledir.nothere").check(dir=0) | ||||||
|         assert self.root.join("sampledir.nothere").check(file=0) |         assert self.root.join("sampledir.nothere").check(file=0) | ||||||
|  | @ -205,8 +203,12 @@ class CommonFSTests(common.CommonPathTests): | ||||||
|         p = self.root.join('samplefile') |         p = self.root.join('samplefile') | ||||||
|         newp = p.dirpath('moved_samplefile') |         newp = p.dirpath('moved_samplefile') | ||||||
|         p.move(newp) |         p.move(newp) | ||||||
|  |         try: | ||||||
|             assert newp.check(file=1) |             assert newp.check(file=1) | ||||||
|             assert not p.check() |             assert not p.check() | ||||||
|  |         finally: | ||||||
|  |             newp.move(p) | ||||||
|  |         assert p.check() | ||||||
| 
 | 
 | ||||||
|     def test_move_directory(self): |     def test_move_directory(self): | ||||||
|         source = self.root.join('sampledir')  |         source = self.root.join('sampledir')  | ||||||
|  |  | ||||||
|  | @ -12,8 +12,10 @@ class LocalSetup: | ||||||
|     def setup_method(self, method): |     def setup_method(self, method): | ||||||
|         self.tmpdir = self.root.mkdir(method.__name__) |         self.tmpdir = self.root.mkdir(method.__name__) | ||||||
| 
 | 
 | ||||||
| class TestLocalPath(LocalSetup, CommonFSTests): |     def teardown_method(self, method): | ||||||
|  |         assert self.root.join("samplefile").check() | ||||||
| 
 | 
 | ||||||
|  | class TestLocalPath(LocalSetup, CommonFSTests): | ||||||
|     def test_join_normpath(self): |     def test_join_normpath(self): | ||||||
|         assert self.tmpdir.join(".") == self.tmpdir |         assert self.tmpdir.join(".") == self.tmpdir | ||||||
|         p = self.tmpdir.join("../%s" % self.tmpdir.basename) |         p = self.tmpdir.join("../%s" % self.tmpdir.basename) | ||||||
|  | @ -347,3 +349,248 @@ def test_homedir(): | ||||||
|     homedir = py.path.local._gethomedir() |     homedir = py.path.local._gethomedir() | ||||||
|     assert homedir.check(dir=1) |     assert homedir.check(dir=1) | ||||||
| 
 | 
 | ||||||
|  | class TestWINLocalPath: | ||||||
|  |     #root = local(TestLocalPath.root) | ||||||
|  |     disabled = py.std.sys.platform != 'win32' | ||||||
|  | 
 | ||||||
|  |     def setup_class(cls): | ||||||
|  |         cls.root = py.test.ensuretemp(cls.__name__)  | ||||||
|  | 
 | ||||||
|  |     def setup_method(self, method):  | ||||||
|  |         name = method.im_func.func_name | ||||||
|  |         self.tmpdir = self.root.ensure(name, dir=1)  | ||||||
|  | 
 | ||||||
|  |     def test_owner_group_not_implemented(self): | ||||||
|  |         py.test.raises(NotImplementedError, "self.root.stat().owner") | ||||||
|  |         py.test.raises(NotImplementedError, "self.root.stat().group") | ||||||
|  | 
 | ||||||
|  |     def test_chmod_simple_int(self): | ||||||
|  |         print "self.root is", self.root | ||||||
|  |         mode = self.root.stat().mode | ||||||
|  |         # Ensure that we actually change the mode to something different. | ||||||
|  |         self.root.chmod(mode == 0 and 1 or 0) | ||||||
|  |         try: | ||||||
|  |             print self.root.stat().mode  | ||||||
|  |             print mode | ||||||
|  |             assert self.root.stat().mode != mode | ||||||
|  |         finally: | ||||||
|  |             self.root.chmod(mode) | ||||||
|  |             assert self.root.stat().mode == mode | ||||||
|  | 
 | ||||||
|  |     def test_path_comparison_lowercase_mixed(self): | ||||||
|  |         t1 = self.root.join("a_path") | ||||||
|  |         t2 = self.root.join("A_path") | ||||||
|  |         assert t1 == t1 | ||||||
|  |         assert t1 == t2 | ||||||
|  |          | ||||||
|  |     def test_relto_with_mixed_case(self): | ||||||
|  |         t1 = self.root.join("a_path", "fiLe") | ||||||
|  |         t2 = self.root.join("A_path") | ||||||
|  |         assert t1.relto(t2) == "fiLe" | ||||||
|  | 
 | ||||||
|  |     def test_allow_unix_style_paths(self): | ||||||
|  |         t1 = self.root.join('a_path') | ||||||
|  |         assert t1 == str(self.root) + '\\a_path' | ||||||
|  |         t1 = self.root.join('a_path/') | ||||||
|  |         assert t1 == str(self.root) + '\\a_path' | ||||||
|  |         t1 = self.root.join('dir/a_path') | ||||||
|  |         assert t1 == str(self.root) + '\\dir\\a_path' | ||||||
|  | 
 | ||||||
|  |     def test_sysfind_in_currentdir(self): | ||||||
|  |         cmd = py.path.local.sysfind('cmd') | ||||||
|  |         root = cmd.new(dirname='', basename='') # c:\ in most installations | ||||||
|  |         old = root.chdir() | ||||||
|  |         try: | ||||||
|  |             x = py.path.local.sysfind(cmd.relto(root)) | ||||||
|  |             assert x.check(file=1) | ||||||
|  |         finally: | ||||||
|  |             old.chdir()     | ||||||
|  | 
 | ||||||
|  | class TestPOSIXLocalPath: | ||||||
|  |     disabled = py.std.sys.platform == 'win32' | ||||||
|  | 
 | ||||||
|  |     def setup_class(cls): | ||||||
|  |         cls.root = py.test.ensuretemp(cls.__name__)  | ||||||
|  | 
 | ||||||
|  |     def setup_method(self, method):  | ||||||
|  |         name = method.im_func.func_name | ||||||
|  |         self.tmpdir = self.root.ensure(name, dir=1)  | ||||||
|  | 
 | ||||||
|  |     def test_samefile(self): | ||||||
|  |         assert self.tmpdir.samefile(self.tmpdir) | ||||||
|  |         p = self.tmpdir.ensure("hello") | ||||||
|  |         assert p.samefile(p)  | ||||||
|  | 
 | ||||||
|  |     def test_hardlink(self): | ||||||
|  |         tmpdir = self.tmpdir  | ||||||
|  |         linkpath = tmpdir.join('test') | ||||||
|  |         filepath = tmpdir.join('file') | ||||||
|  |         filepath.write("Hello") | ||||||
|  |         nlink = filepath.stat().nlink | ||||||
|  |         linkpath.mklinkto(filepath) | ||||||
|  |         assert filepath.stat().nlink == nlink + 1  | ||||||
|  | 
 | ||||||
|  |     def test_symlink_are_identical(self): | ||||||
|  |         tmpdir = self.tmpdir  | ||||||
|  |         filepath = tmpdir.join('file') | ||||||
|  |         filepath.write("Hello") | ||||||
|  |         linkpath = tmpdir.join('test') | ||||||
|  |         linkpath.mksymlinkto(filepath) | ||||||
|  |         assert linkpath.readlink() == str(filepath)  | ||||||
|  | 
 | ||||||
|  |     def test_symlink_isfile(self): | ||||||
|  |         tmpdir = self.tmpdir  | ||||||
|  |         linkpath = tmpdir.join('test') | ||||||
|  |         filepath = tmpdir.join('file') | ||||||
|  |         filepath.write("") | ||||||
|  |         linkpath.mksymlinkto(filepath) | ||||||
|  |         assert linkpath.check(file=1) | ||||||
|  |         assert not linkpath.check(link=0, file=1) | ||||||
|  | 
 | ||||||
|  |     def test_symlink_relative(self): | ||||||
|  |         tmpdir = self.tmpdir  | ||||||
|  |         linkpath = tmpdir.join('test') | ||||||
|  |         filepath = tmpdir.join('file') | ||||||
|  |         filepath.write("Hello") | ||||||
|  |         linkpath.mksymlinkto(filepath, absolute=False) | ||||||
|  |         assert linkpath.readlink() == "file" | ||||||
|  |         assert filepath.read() == linkpath.read() | ||||||
|  | 
 | ||||||
|  |     def test_symlink_not_existing(self): | ||||||
|  |         tmpdir = self.tmpdir  | ||||||
|  |         linkpath = tmpdir.join('testnotexisting') | ||||||
|  |         assert not linkpath.check(link=1) | ||||||
|  |         assert linkpath.check(link=0) | ||||||
|  | 
 | ||||||
|  |     def test_relto_with_root(self): | ||||||
|  |         y = self.root.join('x').relto(py.path.local('/')) | ||||||
|  |         assert y[0] == str(self.root)[1] | ||||||
|  | 
 | ||||||
|  |     def test_visit_recursive_symlink(self): | ||||||
|  |         tmpdir = self.tmpdir  | ||||||
|  |         linkpath = tmpdir.join('test') | ||||||
|  |         linkpath.mksymlinkto(tmpdir) | ||||||
|  |         visitor = tmpdir.visit(None, lambda x: x.check(link=0)) | ||||||
|  |         assert list(visitor) == [linkpath] | ||||||
|  | 
 | ||||||
|  |     def test_symlink_isdir(self): | ||||||
|  |         tmpdir = self.tmpdir  | ||||||
|  |         linkpath = tmpdir.join('test') | ||||||
|  |         linkpath.mksymlinkto(tmpdir) | ||||||
|  |         assert linkpath.check(dir=1) | ||||||
|  |         assert not linkpath.check(link=0, dir=1) | ||||||
|  | 
 | ||||||
|  |     def test_symlink_remove(self): | ||||||
|  |         tmpdir = self.tmpdir.realpath()  | ||||||
|  |         linkpath = tmpdir.join('test') | ||||||
|  |         linkpath.mksymlinkto(linkpath) # point to itself | ||||||
|  |         assert linkpath.check(link=1) | ||||||
|  |         linkpath.remove() | ||||||
|  |         assert not linkpath.check() | ||||||
|  | 
 | ||||||
|  |     def test_realpath_file(self): | ||||||
|  |         tmpdir = self.tmpdir  | ||||||
|  |         linkpath = tmpdir.join('test') | ||||||
|  |         filepath = tmpdir.join('file') | ||||||
|  |         filepath.write("") | ||||||
|  |         linkpath.mksymlinkto(filepath) | ||||||
|  |         realpath = linkpath.realpath() | ||||||
|  |         assert realpath.basename == 'file' | ||||||
|  | 
 | ||||||
|  |     def test_owner(self): | ||||||
|  |         from pwd import getpwuid | ||||||
|  |         from grp import getgrgid | ||||||
|  |         stat = self.root.stat() | ||||||
|  |         assert stat.path == self.root  | ||||||
|  | 
 | ||||||
|  |         uid = stat.uid | ||||||
|  |         gid = stat.gid | ||||||
|  |         owner = getpwuid(uid)[0] | ||||||
|  |         group = getgrgid(gid)[0] | ||||||
|  | 
 | ||||||
|  |         assert uid == stat.uid  | ||||||
|  |         assert owner == stat.owner  | ||||||
|  |         assert gid == stat.gid  | ||||||
|  |         assert group == stat.group  | ||||||
|  | 
 | ||||||
|  |     def test_atime(self): | ||||||
|  |         import time | ||||||
|  |         path = self.root.ensure('samplefile') | ||||||
|  |         now = time.time() | ||||||
|  |         atime1 = path.atime() | ||||||
|  |         # we could wait here but timer resolution is very | ||||||
|  |         # system dependent  | ||||||
|  |         path.read() | ||||||
|  |         atime2 = path.atime() | ||||||
|  |         duration = time.time() - now | ||||||
|  |         assert (atime2-atime1) <= duration | ||||||
|  | 
 | ||||||
|  |     def test_commondir(self): | ||||||
|  |         # XXX This is here in local until we find a way to implement this | ||||||
|  |         #     using the subversion command line api. | ||||||
|  |         p1 = self.root.join('something') | ||||||
|  |         p2 = self.root.join('otherthing') | ||||||
|  |         assert p1.common(p2) == self.root | ||||||
|  |         assert p2.common(p1) == self.root | ||||||
|  | 
 | ||||||
|  |     def test_commondir_nocommon(self): | ||||||
|  |         # XXX This is here in local until we find a way to implement this | ||||||
|  |         #     using the subversion command line api. | ||||||
|  |         p1 = self.root.join('something') | ||||||
|  |         p2 = py.path.local(self.root.sep+'blabla') | ||||||
|  |         assert p1.common(p2) == '/'  | ||||||
|  | 
 | ||||||
|  |     def test_join_to_root(self):  | ||||||
|  |         root = self.root.parts()[0] | ||||||
|  |         assert len(str(root)) == 1 | ||||||
|  |         assert str(root.join('a')) == '/a' | ||||||
|  | 
 | ||||||
|  |     def test_join_root_to_root_with_no_abs(self):  | ||||||
|  |         nroot = self.root.join('/') | ||||||
|  |         assert str(self.root) == str(nroot)  | ||||||
|  |         assert self.root == nroot  | ||||||
|  | 
 | ||||||
|  |     def test_chmod_simple_int(self): | ||||||
|  |         print "self.root is", self.root | ||||||
|  |         mode = self.root.stat().mode | ||||||
|  |         self.root.chmod(mode/2) | ||||||
|  |         try: | ||||||
|  |             assert self.root.stat().mode != mode | ||||||
|  |         finally: | ||||||
|  |             self.root.chmod(mode) | ||||||
|  |             assert self.root.stat().mode == mode | ||||||
|  | 
 | ||||||
|  |     def test_chmod_rec_int(self): | ||||||
|  |         # XXX fragile test | ||||||
|  |         print "self.root is", self.root | ||||||
|  |         recfilter = lambda x: x.check(dotfile=0, link=0) | ||||||
|  |         oldmodes = {} | ||||||
|  |         for x in self.root.visit(rec=recfilter): | ||||||
|  |             oldmodes[x] = x.stat().mode | ||||||
|  |         self.root.chmod(0772, rec=recfilter) | ||||||
|  |         try: | ||||||
|  |             for x in self.root.visit(rec=recfilter): | ||||||
|  |                 assert x.stat().mode & 0777 == 0772 | ||||||
|  |         finally: | ||||||
|  |             for x,y in oldmodes.items(): | ||||||
|  |                 x.chmod(y) | ||||||
|  | 
 | ||||||
|  |     def test_chown_identity(self): | ||||||
|  |         owner = self.root.stat().owner | ||||||
|  |         group = self.root.stat().group | ||||||
|  |         self.root.chown(owner, group) | ||||||
|  | 
 | ||||||
|  |     def test_chown_dangling_link(self): | ||||||
|  |         owner = self.root.stat().owner | ||||||
|  |         group = self.root.stat().group | ||||||
|  |         x = self.root.join('hello') | ||||||
|  |         x.mksymlinkto('qlwkejqwlek') | ||||||
|  |         try: | ||||||
|  |             self.root.chown(owner, group, rec=1) | ||||||
|  |         finally: | ||||||
|  |             x.remove(rec=0) | ||||||
|  | 
 | ||||||
|  |     def test_chown_identity_rec_mayfail(self): | ||||||
|  |         owner = self.root.stat().owner | ||||||
|  |         group = self.root.stat().group | ||||||
|  |         self.root.chown(owner, group) | ||||||
		Loading…
	
		Reference in New Issue