def _check_path(self, src, path_type, dest=None, force=False):
        """Check a new destination path in the archive.

            Since it is possible for multiple plugins to collect the same
            paths, and since plugins can now run concurrently, it is possible
            for two threads to race in archive methods: historically the
            archive class only needed to test for the actual presence of a
            path, since it was impossible for another `Archive` client to
            enter the class while another method invocation was being
            dispatched.

            Deal with this by implementing a locking scheme for operations
            that modify the path structure of the archive, and by testing
            explicitly for conflicts with any existing content at the
            specified destination path.

            It is not an error to attempt to create a path that already
            exists in the archive so long as the type of the object to be
            added matches the type of object already found at the path.

            It is an error to attempt to re-create an existing path with
            a different path type (for example, creating a symbolic link
            at a path already occupied by a regular file).

            :param src: the source path to be copied to the archive
            :param path_type: the type of object to be copied
            :param dest: an optional destination path
            :param force: force file creation even if the path exists
            :returns: An absolute destination path if the path should be
                      copied now or `None` otherwise
        """
        dest = dest or self.dest_path(src)
        if path_type == P_DIR:
            dest_dir = dest
        else:
            dest_dir = os.path.split(dest)[0]
        if not dest_dir:
            return dest

        # Check containing directory presence and path type
        if os.path.exists(dest_dir) and not os.path.isdir(dest_dir):
            raise ValueError("path '%s' exists and is not a directory" %
                             dest_dir)
        elif not os.path.exists(dest_dir):
            src_dir = src if path_type == P_DIR else os.path.split(src)[0]
            self._make_leading_paths(src_dir)

        def is_special(mode):
            return any([
                stat.S_ISBLK(mode),
                stat.S_ISCHR(mode),
                stat.S_ISFIFO(mode),
                stat.S_ISSOCK(mode)
            ])

        if force:
            return dest

        # Check destination path presence and type
        if os.path.exists(dest):
            # Use lstat: we care about the current object, not the referent.
            st = os.lstat(dest)
            ve_msg = "path '%s' exists and is not a %s"
            if path_type == P_FILE and not stat.S_ISREG(st.st_mode):
                raise ValueError(ve_msg % (dest, "regular file"))
            if path_type == P_LINK and not stat.S_ISLNK(st.st_mode):
                raise ValueError(ve_msg % (dest, "symbolic link"))
            if path_type == P_NODE and not is_special(st.st_mode):
                raise ValueError(ve_msg % (dest, "special file"))
            if path_type == P_DIR and not stat.S_ISDIR(st.st_mode):
                raise ValueError(ve_msg % (dest, "directory"))
            # Path has already been copied: skip
            return None
        return dest
def _check_path ( self , src , path_type , dest = None , force = False ) : dest = dest or self . dest_path ( src ) if path_type == P_DIR : dest_dir = dest else : dest_dir = os . path . split ( dest ) [ 0 ] if not dest_dir : return dest if os . path . exists ( dest_dir ) and not os . path . isdir ( dest_dir ) : raise ValueError ( "path '%s' exists and is not a directory" % dest_dir ) elif not os . path . exists ( dest_dir ) : src_dir = src if path_type == P_DIR else os . path . split ( src ) [ 0 ] self . _make_leading_paths ( src_dir ) def is_special ( mode ) : return any ( [ stat . S_ISBLK ( mode ) , stat . S_ISCHR ( mode ) , stat . S_ISFIFO ( mode ) , stat . S_ISSOCK ( mode ) ] ) if force : return dest if os . path . exists ( dest ) : st = os . lstat ( dest ) ve_msg = "path '%s' exists and is not a %s" if path_type == P_FILE and not stat . S_ISREG ( st . st_mode ) : raise ValueError ( ve_msg % ( dest , "regular file" ) ) if path_type == P_LINK and not stat . S_ISLNK ( st . st_mode ) : raise ValueError ( ve_msg % ( dest , "symbolic link" ) ) if path_type == P_NODE and not is_special ( st . st_mode ) : raise ValueError ( ve_msg % ( dest , "special file" ) ) if path_type == P_DIR and not stat . S_ISDIR ( st . st_mode ) : raise ValueError ( ve_msg % ( dest , "directory" ) ) return None return dest
Check a new destination path in the archive.

            Since it is possible for multiple plugins to collect the same
            paths, and since plugins can now run concurrently, it is possible
            for two threads to race in archive methods: historically the
            archive class only needed to test for the actual presence of a
            path, since it was impossible for another `Archive` client to
            enter the class while another method invocation was being
            dispatched.

            Deal with this by implementing a locking scheme for operations
            that modify the path structure of the archive, and by testing
            explicitly for conflicts with any existing content at the
            specified destination path.

            It is not an error to attempt to create a path that already
            exists in the archive so long as the type of the object to be
            added matches the type of object already found at the path.

            It is an error to attempt to re-create an existing path with
            a different path type (for example, creating a symbolic link
            at a path already occupied by a regular file).

            :param src: the source path to be copied to the archive
            :param path_type: the type of object to be copied
            :param dest: an optional destination path
            :param force: force file creation even if the path exists
            :returns: An absolute destination path if the path should be
                      copied now or `None` otherwise