← Back to team overview

launchpad-reviewers team mailing list archive

[Merge] ~cjwatson/txpkgupload:remove-zope.server into txpkgupload:master

 

Colin Watson has proposed merging ~cjwatson/txpkgupload:remove-zope.server into txpkgupload:master.

Commit message:
Remove dependencies on zope.{component,security,server}

Requested reviews:
  Launchpad code reviewers (launchpad-reviewers)

For more details, see:
https://code.launchpad.net/~cjwatson/txpkgupload/+git/txpkgupload/+merge/437107

Once upon a time, the code in Launchpad that grew into txpkgupload relied on the FTP server in `zope.server`.  That was replaced by a dependency on Twisted in 2011 or so, but we retained a vestigial dependency on `zope.server` and a good deal of leftover support code in `UploadFileSystem` that's no longer called by anything.  Get rid of all this.
-- 
Your team Launchpad code reviewers is requested to review the proposed merge of ~cjwatson/txpkgupload:remove-zope.server into txpkgupload:master.
diff --git a/requirements.txt b/requirements.txt
index ab7562f..b2cf037 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -35,7 +35,6 @@ pycparser==2.18
 PyHamcrest==1.10.1
 PyNaCl==1.3.0
 python-dateutil==2.8.1
-python-gettext==4.0
 python-mimeparse==0.1.4
 pytz==2017.2
 PyYAML==3.10
@@ -47,21 +46,10 @@ Twisted[conch]==20.3.0+lp8
 unittest2==1.1.0+lp1
 wadllib==1.3.2
 zipp==1.2.0
-zope.browser==2.3
 zope.component==4.6.1
-zope.configuration==4.4.0
-zope.contenttype==4.5.0
 zope.deferredimport==4.3.1
 zope.deprecation==4.4.0
 zope.event==4.4
-zope.exceptions==4.3
 zope.hookable==5.0.1
-zope.i18n==4.7.0
-zope.i18nmessageid==5.0.1
 zope.interface==5.0.2
-zope.location==4.2
 zope.proxy==4.3.5
-zope.publisher==5.2.0
-zope.schema==6.0.0
-zope.security==5.1.1
-zope.server==4.0.2
diff --git a/setup.py b/setup.py
index 246ba61..fc284de 100755
--- a/setup.py
+++ b/setup.py
@@ -61,10 +61,7 @@ setup(
         'setuptools',
         'six>=1.12.0',
         'Twisted[conch_nacl]',
-        'zope.component',
         'zope.interface>=3.6.0',
-        'zope.security',
-        'zope.server',
         ],
     url='https://launchpad.net/txpkgupload',
     download_url='https://launchpad.net/txpkgupload/+download',
diff --git a/src/txpkgupload/NEWS.txt b/src/txpkgupload/NEWS.txt
index c1fa967..59d1713 100644
--- a/src/txpkgupload/NEWS.txt
+++ b/src/txpkgupload/NEWS.txt
@@ -9,6 +9,8 @@ NEWS for txpkgupload
 - Adjust directory creation to work around a change in ``os.makedirs`` in
   Python 3.7.
 - Add Python 3.8 support.
+- Remove dependencies on ``zope.component``, ``zope.security``, and
+  ``zope.server``.
 
 0.4 (2021-01-04)
 ================
diff --git a/src/txpkgupload/filesystem.py b/src/txpkgupload/filesystem.py
index a598184..9a913e0 100644
--- a/src/txpkgupload/filesystem.py
+++ b/src/txpkgupload/filesystem.py
@@ -6,16 +6,9 @@ __all__ = [
     'UploadFileSystem',
     ]
 
-import datetime
 import os
-import stat
 
-from zope.interface import implementer
-from zope.security.interfaces import Unauthorized
-from zope.server.interfaces.ftp import IFileSystem
 
-
-@implementer(IFileSystem)
 class UploadFileSystem:
 
     def __init__(self, rootpath):
@@ -30,10 +23,8 @@ class UploadFileSystem:
 
     def _sanitize(self, path):
         if isinstance(path, bytes):
-            # zope.server's FTP implementation seems to decode all commands
-            # (including the paths they contain) to text using UTF-8,
-            # effectively assuming the recommendation in RFC 2640 except
-            # without the feature negotiation part.  However, Twisted's SFTP
+            # RFC 2640 recommends that paths are exchanged using UTF-8,
+            # albeit with some feature negotiation.  However, Twisted's SFTP
             # implementation leaves paths as bytes.  Since in practice
             # legitimate uses of txpkgupload will only involve ASCII paths,
             # and since UTF-8 has low risk of undetected decoding errors,
@@ -47,98 +38,6 @@ class UploadFileSystem:
         path = os.path.normpath(path)
         return path
 
-    def type(self, path):
-        """Return the file type at path
-
-        The 'type' command returns 'f' for a file, 'd' for a directory and
-        None if there is no file.
-        """
-        path = self._sanitize(path)
-        full_path = self._full(path)
-        if os.path.exists(full_path):
-            if os.path.isdir(full_path):
-                return 'd'
-            elif os.path.isfile(full_path):
-                return 'f'
-
-    def names(self, path, filter=None):
-        """Return a sequence of the names in a directory
-
-        If the filter is not None, include only those names for which
-        the filter returns a true value.
-        """
-        path = self._sanitize(path)
-        full_path = self._full(path)
-        if not os.path.exists(full_path):
-            raise OSError("Not exists:", path)
-        filenames = os.listdir(os.path.join(self.rootpath, path))
-        files = []
-        for filename in filenames:
-            if not filter or filter(filename):
-                files.append(filename)
-        return files
-
-    def ls(self, path, filter=None):
-        """Return a sequence of information objects.
-
-        It considers the names in the given path (returned self.name())
-        and builds file information using self.lsinfo().
-        """
-        return [self.lsinfo(name) for name in self.names(path, filter)]
-
-    def readfile(self, path, outstream, start=0, end=None):
-        """Outputs the file at path to a stream.
-
-        Not allowed - see filesystem.txt.
-        """
-        raise Unauthorized
-
-    def lsinfo(self, path):
-        """Return information for a unix-style ls listing for the path
-
-        See zope3's interfaces/ftp.py:IFileSystem for details of the
-        dictionary's content.
-        """
-        path = self._sanitize(path)
-        full_path = self._full(path)
-        if not os.path.exists(full_path):
-            raise OSError("Not exists:", path)
-
-        info = {"owner_name": "upload",
-                "group_name": "upload",
-                "name": path.split("/")[-1]}
-
-        s = os.stat(full_path)
-
-        info["owner_readable"] = bool(s.st_mode & stat.S_IRUSR)
-        info["owner_writable"] = bool(s.st_mode & stat.S_IWUSR)
-        info["owner_executable"] = bool(s.st_mode & stat.S_IXUSR)
-        info["group_readable"] = bool(s.st_mode & stat.S_IRGRP)
-        info["group_writable"] = bool(s.st_mode & stat.S_IWGRP)
-        info["group_executable"] = bool(s.st_mode & stat.S_IXGRP)
-        info["other_readable"] = bool(s.st_mode & stat.S_IROTH)
-        info["other_writable"] = bool(s.st_mode & stat.S_IWOTH)
-        info["other_executable"] = bool(s.st_mode & stat.S_IXOTH)
-        info["mtime"] = datetime.datetime.fromtimestamp(self.mtime(path))
-        info["size"] = self.size(path)
-        info["type"] = self.type(path)
-        info["nlinks"] = s.st_nlink
-        return info
-
-    def mtime(self, path):
-        """Return the modification time for the file"""
-        path = self._sanitize(path)
-        full_path = self._full(path)
-        if os.path.exists(full_path):
-            return os.path.getmtime(full_path)
-
-    def size(self, path):
-        """Return the size of the file at path"""
-        path = self._sanitize(path)
-        full_path = self._full(path)
-        if os.path.exists(full_path):
-            return os.path.getsize(full_path)
-
     def mkdir(self, path):
         """Create a directory."""
         path = self._sanitize(path)
@@ -156,18 +55,6 @@ class UploadFileSystem:
             finally:
                 os.umask(old_mask)
 
-    def remove(self, path):
-        """Remove a file."""
-        path = self._sanitize(path)
-        full_path = self._full(path)
-        if os.path.exists(full_path):
-            if os.path.isfile(full_path):
-                os.unlink(full_path)
-            elif os.path.isdir(full_path):
-                raise OSError("Is a directory:", path)
-        else:
-            raise OSError("Not exists:", path)
-
     def rmdir(self, path):
         """Remove a directory.
 
@@ -179,81 +66,3 @@ class UploadFileSystem:
             os.rmdir(full_path)
         else:
             raise OSError("Not exists:", path)
-
-    def rename(self, old, new):
-        """Rename a file."""
-        old = self._sanitize(old)
-        new = self._sanitize(new)
-        full_old = self._full(old)
-        full_new = self._full(new)
-
-        if os.path.isdir(full_new):
-            raise OSError("Is a directory:", new)
-
-        if os.path.exists(full_old):
-            if os.path.isfile(full_old):
-                os.rename(full_old, full_new)
-            elif os.path.isdir(full_old):
-                raise OSError("Is a directory:", old)
-        else:
-            raise OSError("Not exists:", old)
-
-    def writefile(self, path, instream, start=None, end=None, append=False):
-        """Write data to a file.
-
-        See zope3's interfaces/ftp.py:IFileSystem for details of the
-        handling of the various arguments.
-        """
-        path = self._sanitize(path)
-        full_path = self._full(path)
-        if os.path.exists(full_path):
-            if os.path.isdir(full_path):
-                raise OSError("Is a directory:", path)
-        else:
-            dirname = os.path.dirname(full_path)
-            if dirname:
-                if not os.path.exists(dirname):
-                    old_mask = os.umask(0o002)
-                    try:
-                        os.makedirs(dirname)
-                    finally:
-                        os.umask(old_mask)
-
-        if start and start < 0:
-            raise ValueError("Negative start argument:", start)
-        if end and end < 0:
-            raise ValueError("Negative end argument:", end)
-        if start and end and end <= start:
-            return
-        if append:
-            open_flag = 'ab'
-        elif start or end:
-            open_flag = "r+b"
-            if not os.path.exists(full_path):
-                with open(full_path, 'wb'):
-                    pass
-
-        else:
-            open_flag = 'wb'
-        with open(full_path, open_flag) as outstream:
-            if start:
-                outstream.seek(start)
-            chunk = instream.read()
-            while chunk:
-                outstream.write(chunk)
-                chunk = instream.read()
-            if not end:
-                outstream.truncate()
-        instream.close()
-
-    def writable(self, path):
-        """Return boolean indicating whether a file at path is writable."""
-        path = self._sanitize(path)
-        full_path = self._full(path)
-        if os.path.exists(full_path):
-            if os.path.isfile(full_path):
-                return True
-            elif os.path.isdir(full_path):
-                return False
-        else:
-            return True
diff --git a/src/txpkgupload/tests/filesystem.txt b/src/txpkgupload/tests/filesystem.txt
index 20b80d9..2dcd81c 100644
--- a/src/txpkgupload/tests/filesystem.txt
+++ b/src/txpkgupload/tests/filesystem.txt
@@ -1,15 +1,8 @@
-
-This is an implementation of IFileSystem which the FTP Server in Zope3
-uses to know what to do when people make FTP commands.
+`UploadFileSystem` provides logic for the few limited interactions with the
+part of the file system we expose over FTP/SFTP.
 
     >>> from txpkgupload.filesystem import UploadFileSystem
 
-The UploadFileSystem class implements the interface IFileSystem.
-
-    >>> from zope.server.interfaces.ftp import IFileSystem
-    >>> IFileSystem.implementedBy(UploadFileSystem)
-    True
-
 First we need to setup our test environment.
 
     >>> import os
@@ -38,12 +31,6 @@ to use.
 
     >>> ufs = UploadFileSystem(rootpath)
 
-An UploadFileSystem object provides the interface IFileSystem.
-
-    >>> from zope.interface.verify import verifyObject
-    >>> verifyObject(IFileSystem, ufs)
-    True
-
 mkdir
 =====
 
@@ -88,434 +75,13 @@ Check if it works as expected after the directory creation:
     >>> os.path.exists(os.path.join(rootpath, "new-dir"))
     False
 
-
-lsinfo
-======
-
-Return information for a unix-style ls listing for the path.
-
-See zope3's interfaces/ftp.py:IFileSystem for details of the
-dictionary's content.
-
-Setup a default dictionary used for generating the dictionaries we
-expect lsinfo to return.
-
-    >>> def clean_mtime(stat_info):
-    ...     """Return a datetime from an mtime, sans microseconds."""
-    ...     mtime = stat_info.st_mtime
-    ...     datestamp = datetime.datetime.fromtimestamp(mtime)
-    ...     datestamp.replace(microsecond=0)
-    ...     return datestamp
-
-    >>> import copy
-    >>> import datetime
-    >>> import stat
-    >>> def_exp = {"type": 'f', 
-    ...     "owner_name": "upload",
-    ...     "owner_readable": True,
-    ...     "owner_writable": True,
-    ...	    "owner_executable": False,
-    ...	    "group_name": "upload",
-    ...	    "group_readable": True,
-    ...     "group_writable": False,
-    ...	    "group_executable": False,
-    ...	    "other_readable": True,
-    ...     "other_writable": False,
-    ...	    "other_executable": False,
-    ...     "nlinks": 1}
-    ...
-
-    >>> os.chmod(full_testfile, stat.S_IRUSR | stat.S_IWUSR | \
-    ...                         stat.S_IRGRP | stat.S_IROTH)
-    >>> exp = copy.copy(def_exp)
-    >>> s = os.stat(full_testfile)
-    >>> exp["name"] = testfile
-    >>> exp["mtime"] = clean_mtime(s)
-    >>> exp["size"] = s[stat.ST_SIZE]
-    >>> info = ufs.lsinfo(testfile)
-    >>> info == exp
-    True
-
-ls
-==
-
-`ls` a sequence of item info objects (see ls_info) for the files in a
-directory.
-
-    >>> expected = [exp]
-    >>> for i in [ "foo", "bar" ]:
-    ...     filename = os.path.join(rootpath, i)
-    ...     with open(filename, 'w'):
-    ...         pass
-    ...     os.chmod(filename, stat.S_IRUSR | stat.S_IWUSR | \
-    ...                         stat.S_IRGRP | stat.S_IROTH)
-    ...     exp = copy.copy(def_exp)
-    ...	    s = os.stat(filename)
-    ...	    exp["name"] = i
-    ...	    exp["mtime"] = clean_mtime(s)
-    ...     exp["size"] = s[stat.ST_SIZE]
-    ...     expected.append(exp)
-    ...
-
-    >>> dir_exp = copy.copy(def_exp)
-    >>> s = os.stat(full_testdir)
-    >>> dir_exp["type"] = "d"
-    >>> dir_exp["name"] = testdir
-    >>> dir_exp["mtime"] = clean_mtime(s)
-    >>> dir_exp["size"] = s[stat.ST_SIZE]
-    >>> dir_exp["nlinks"] = s[stat.ST_NLINK]
-    >>> dir_exp["owner_executable"] = True
-    >>> dir_exp["other_executable"] = True
-    >>> dir_exp["group_executable"] = True
-    >>> expected.append(dir_exp)
-
-We need a helper function to turn the returned and expected data into reliably
-sorted orders for comparison.
-
-    >>> from operator import itemgetter
-    >>> def sorted_listings(ls_infos):
-    ...     # ls_infos will be a sequence of dictionaries.  They need to be
-    ...     # sorted for the sequences to compare equal, so do that on the
-    ...     # dictionary's 'name' key.  The equality test used here
-    ...     # doesn't care about the sort order of the dictionaries.
-    ...     return sorted(ls_infos, key=itemgetter('name'))
-
-    >>> returned = ufs.ls(".")
-    >>> sorted_listings(expected) == sorted_listings(returned)
-    True
-
-If `filter` is not None, include only those names for which `filter`
-returns a true value.
-
-    >>> def always_false_filter(name):
-    ...     return False
-    >>> def always_true_filter(name):
-    ...     return True
-    >>> def arbitrary_filter(name):
-    ...    if name == "foo" or name == "baz":
-    ...        return True
-    ...    else:
-    ...        return False
-    ...
-    >>> for i in expected:
-    ...     if i["name"] == "foo":
-    ...         filtered_expected = [i];
-    >>> returned = ufs.ls(".", always_true_filter)
-    >>> sorted_listings(expected) == sorted_listings(returned)
-    True
-    >>> returned = ufs.ls(".", always_false_filter)
-    >>> returned == []
-    True
-    >>> returned = ufs.ls(".", arbitrary_filter)
-    >>> sorted_listings(filtered_expected) == sorted_listings(returned)
-    True
-    >>> for i in [ "foo", "bar" ]:
-    ...     ufs.remove(i)
-    ...
-
-readfile
-========
-
-We are not implementing `readfile` as a precautionary measure, i.e. in
-case anyone bypasses the per-session separate directories they still
-aren't able to read any other files and therefore can't abuse the
-server for warez/child porn etc.
-
-Unlike `mkdir` and `rmdir` we will raise an exception so that the
-server returns an error to the client and the client does not receive
-bogus or empty data.
-
-    >>> ufs.readfile(testfile, None)
-    ... # doctest: +IGNORE_EXCEPTION_DETAIL
-    Traceback (most recent call last):
-    ...
-    Unauthorized
-
-The 'type' command returns 'f' for a file, 'd' for a directory and
-None if there is no file.
- 
-    >>> ufs.type(testfile)
-    'f'
-    
-    >>> ufs.type(testdir)
-    'd'
-    
-    >>> ufs.type("does-not-exist") is None
-    True
-
-size
-====
-
-The 'size' command returns the size of the file.  If the file does not
-exist None is returned.
-
-    >>> ufs.size("does-not-exist") is None
-    True
-    
-    >>> ufs.size(testfile) == os.path.getsize(full_testfile)
-    True
-    
-    >>> ufs.size(testdir) == os.path.getsize(full_testdir)
-    True
-
-mtime
-=====
-
-The 'mtime' command returns the mtime of the file.  If the file does not
-exist None is returned.
-
-    >>> ufs.size("does-not-exist") is None
-    True
-    
-    >>> ufs.mtime(testfile) == os.path.getmtime(full_testfile)
-    True
-    
-    >>> ufs.mtime(testdir) == os.path.getmtime(full_testdir)
-    True
-
-remove
-======
-
-The 'remove' command removes a file.  An exception is raised if the
-file does not exist or is a directory.
-
-    >>> ufs.remove("does-not-exist")
-    Traceback (most recent call last):
-    ...
-    OSError: [Errno Not exists:] does-not-exist
-    
-    >>> ufs.remove(testfile)
-    >>> os.path.exists(full_testfile)
-    False
-    >>> with open(full_testfile, 'wb') as f:
-    ...     _ = f.write(b"contents of the file")
-    
-    >>> ufs.remove(testdir)
-    Traceback (most recent call last):
-    ...
-    OSError: [Errno Is a directory:] testdir
-
-rename
-======
-
-The 'rename' command renames a file.  An exception is raised if the
-old filename doesn't exist or if the old or new filename is a
-directory.
-
-    >>> new_testfile = "baz"
-    >>> new_full_testfile = os.path.join(rootpath, new_testfile)
-    
-    >>> ufs.rename("does-not-exist", new_testfile)
-    Traceback (most recent call last):
-    ...
-    OSError: [Errno Not exists:] does-not-exist
-
-    >>> new_testfile = "baz"
-    >>> new_full_testfile = os.path.join(rootpath, new_testfile)
-    >>> ufs.rename(testfile, new_testfile)
-    >>> os.path.exists(full_testfile)
-    False
-    >>> os.path.exists(new_full_testfile)
-    True
-    >>> with open(new_full_testfile, "rb") as f:
-    ...     f.read() == testfile_contents
-    True
-    >>> ufs.rename(new_testfile, testfile)
-    
-    >>> ufs.rename(testdir, new_testfile)
-    Traceback (most recent call last):
-    ...
-    OSError: [Errno Is a directory:] testdir
-    
-    >>> ufs.rename(testfile, testdir)
-    Traceback (most recent call last):
-    ...
-    OSError: [Errno Is a directory:] testdir
-
-names
-=====
-
-The `names` command returns a sequence of the names in the `path`.
-
-    >>> for name in sorted(ufs.names(".")):
-    ...     print(name)
-    testdir
-    testfile
-
-`path` is normalized before used.
-
-    >>> for name in sorted(ufs.names("some-directory/..")):
-    ...     print(name)
-    testdir
-    testfile
-
-'path' under the server root is not allowed:
-
-    >>> ufs.names("..")
-    Traceback (most recent call last):
-    ...
-    OSError: [Errno Path not allowed:] ..
-
-
-If the `filter` argument is provided, each name is only returned if
-the given `filter` function returns True for it.
-
-    >>> ufs.names(".", always_false_filter)
-    []
-
-    >>> for name in sorted(ufs.names(".", always_true_filter)):
-    ...     print(name)
-    testdir
-    testfile
-
-    >>> for i in [ "foo", "bar", "baz", "bat" ]:
-    ...     with open(os.path.join(rootpath, i), 'w'):
-    ...         pass
-    >>> names = ufs.names(".", arbitrary_filter)
-    >>> names.sort()
-    >>> names == ['baz', 'foo']
-    True
-    >>> for i in [ "foo", "bar", "baz", "bat" ]:
-    ...     os.unlink(os.path.join(rootpath, i))
-
-writefile
-=========
-
-`writefile` writes data to a file.
-
-    >>> import io
-    >>> ufs.writefile("upload", io.BytesIO(propaganda))
-    >>> with open(os.path.join(rootpath, "upload"), "rb") as f:
-    ...     f.read() == propaganda
-    True
-    >>> ufs.remove("upload")
-
-If neither `start` nor `end` are specified, then the file contents
-are overwritten.
-
-    >>> ufs.writefile(testfile, io.BytesIO(b"MOO"))
-    >>> with open(full_testfile, "rb") as f:
-    ...     f.read() == b"MOO"
-    True
-    >>> ufs.writefile(testfile, io.BytesIO(testfile_contents))
-
-If `start` or `end` are specified, they must be non-negative.
-
-    >>> ufs.writefile("upload", io.BytesIO(propaganda), -37)
-    Traceback (most recent call last):
-    ...
-    ValueError: ('Negative start argument:', -37)
-
-    >>> ufs.writefile("upload", io.BytesIO(propaganda), 1, -43)
-    Traceback (most recent call last):
-    ...
-    ValueError: ('Negative end argument:', -43)
-
-If `start` or `end` is not None, then only part of the file is
-written. The remainder of the file is unchanged.
-
-    >>> ufs.writefile(testfile, io.BytesIO(b"MOO"), 9, 12)
-    >>> with open(full_testfile, "rb") as f:
-    ...     f.read() == b"contents MOOthe file"
-    True
-    >>> ufs.writefile(testfile, io.BytesIO(testfile_contents))
-
-If `end` is None, then the file is truncated after the data are
-written.  
-
-    >>> ufs.writefile(testfile, io.BytesIO(b"MOO"), 9)
-    >>> with open(full_testfile, "rb") as f:
-    ...     f.read() == b"contents MOO"
-    True
-    >>> ufs.writefile(testfile, io.BytesIO(testfile_contents))
-
-If `start` is specified and the file doesn't exist or is shorter
-than start, the file will contain undefined data before start.
-
-    >>> ufs.writefile("didnt-exist", io.BytesIO(b"MOO"), 9)
-    >>> with open(os.path.join(rootpath, "didnt-exist"), "rb") as f:
-    ...     f.read() == b"\x00\x00\x00\x00\x00\x00\x00\x00\x00MOO"
-    True
-    >>> ufs.remove("didnt-exist")
-
-If `end` is not None and there isn't enough data in `instream` to fill
-out the file, then the missing data is undefined.
-
-    >>> ufs.writefile(testfile, io.BytesIO(b"MOO"), 9, 15)
-    >>> with open(full_testfile, "rb") as f:
-    ...     f.read() == b"contents MOOthe file"
-    True
-    >>> ufs.writefile(testfile, io.BytesIO(testfile_contents))
-
-If `end` is less than or the same as `start no data is writen to the file.
-
-    >>> ufs.writefile(testfile, io.BytesIO(b"MOO"), 9, 4)
-    >>> with open(full_testfile, "rb") as f:
-    ...     f.read() == b"contents of the file"
-    True
-
-    >>> ufs.writefile(testfile, io.BytesIO(b"MOO"), 9, 9)
-    >>> with open(full_testfile, "rb") as f:
-    ...     f.read() == b"contents of the file"
-    True
-
-If `append` is true the file is appended to rather than being
-overwritten.
-
-    >>> ufs.writefile(testfile, io.BytesIO(b"MOO"), append=True)
-    >>> with open(full_testfile, "rb") as f:
-    ...     f.read() == b"contents of the fileMOO"
-    True
-    >>> ufs.writefile(testfile, io.BytesIO(testfile_contents))
-
-Additionally, if `append` is true, `start` and `end` are ignored.
-
-    >>> ufs.writefile(testfile, io.BytesIO(b"MOO"), 10, 13, append=True)
-    >>> with open(full_testfile, "rb") as f:
-    ...     f.read() == b"contents of the fileMOO"
-    True
-    >>> ufs.writefile(testfile, io.BytesIO(testfile_contents))
-
-'writefile' is able to create inexistent directories in a requested
-path:
-
-    >>> os.path.exists(os.path.join(rootpath, "foo"))
-    False
-    >>> ufs.writefile("foo/bar", io.BytesIO(b"fake"))
-    >>> os.path.exists(os.path.join(rootpath, "foo/bar"))
-    True
-    >>> with open(os.path.join(rootpath, "foo/bar"), "rb") as f:
-    ...     f.read() == b"fake"
-    True
-
-
-writable
-========
-
-`writable` returns a boolean indicating whether `path` is writable or
-not.
-
-    >>> ufs.writable(testfile)
-    True
-
-`writable` returns True if `path` is a non-existent file.
-
-    >>> ufs.writable("does-not-exist")
-    True
-
-`writable` returns False if `path` is a directory as we don't allow
-the creation of sub-directories.
-
-    >>> ufs.writable(testdir)
-    False
-
 path checking
 =============
 
 `path` arguments must be normalized.
 
-    >>> ufs.type(os.path.join("non-existent-dir", "..", testfile))
-    'f'
+    >>> ufs._sanitize(os.path.join("non-existent-dir", "..", testfile))
+    'testfile'
 
 
 Cleanup the server root:
@@ -528,84 +94,8 @@ Cleanup the server root:
     ...          os.remove(full_path)
 
 
-Dealing with inexistent path:
-
-    >>> ufs.type("foo/bar") is None
-    True
-    >>> ufs.mtime("foo/bar") is None
-    True
-    >>> ufs.size("foo/bar") is None
-    True
-    >>> ufs.writable("foo/bar")
-    True
-    >>> ufs.names("foo/bar")
-    Traceback (most recent call last):
-    ...
-    OSError: [Errno Not exists:] foo/bar
-    >>> ufs.ls("foo/bar")
-    Traceback (most recent call last):
-    ...
-    OSError: [Errno Not exists:] foo/bar
-    >>> ufs.lsinfo("foo/bar")
-    Traceback (most recent call last):
-    ...
-    OSError: [Errno Not exists:] foo/bar
-    >>> ufs.remove("foo/bar")
-    Traceback (most recent call last):
-    ...
-    OSError: [Errno Not exists:] foo/bar
-    >>> ufs.rename("foo/bar", "baz")
-    Traceback (most recent call last):
-    ...
-    OSError: [Errno Not exists:] foo/bar
-    >>> ufs.rename("baz", "foo/bar")
-    Traceback (most recent call last):
-    ...
-    OSError: [Errno Not exists:] baz
-
-
 Dealing with paths outside the server root directory:
 
-    >>> ufs.type("..")
-    Traceback (most recent call last):
-    ...
-    OSError: [Errno Path not allowed:] ..
-    >>> ufs.mtime("..")
-    Traceback (most recent call last):
-    ...
-    OSError: [Errno Path not allowed:] ..
-    >>>	ufs.size("..")
-    Traceback (most recent call last):
-    ...
-    OSError: [Errno Path not allowed:] ..
-    >>> ufs.writable("..")
-    Traceback (most recent call last):
-    ...
-    OSError: [Errno Path not allowed:] ..
-    >>> ufs.names("..")
-    Traceback (most recent call last):
-    ...
-    OSError: [Errno Path not allowed:] ..
-    >>> ufs.ls("..")
-    Traceback (most recent call last):
-    ...
-    OSError: [Errno Path not allowed:] ..
-    >>> ufs.lsinfo("..")
-    Traceback (most recent call last):
-    ...
-    OSError: [Errno Path not allowed:] ..
-    >>> ufs.remove("..")
-    Traceback (most recent call last):
-    ...
-    OSError: [Errno Path not allowed:] ..
-    >>> ufs.rename("..", "baz")
-    Traceback (most recent call last):
-    ...
-    OSError: [Errno Path not allowed:] ..
-    >>> ufs.rename("baz", "..")
-    Traceback (most recent call last):
-    ...
-    OSError: [Errno Path not allowed:] ..
     >>> ufs.mkdir("..")
     Traceback (most recent call last):
     ...
@@ -621,4 +111,3 @@ Dealing with paths outside the server root directory:
 Finally, cleanup after ourselves.
 
     >>> shutil.rmtree(rootpath)
-