# Buggy code
def trash_free_desktop(path):
    """Partial implementation of
    http://www.freedesktop.org/wiki/Specifications/trash-spec

    No copy fallback, either it can be moved on the same FS or it failes.
    Also doesn't work for files in the trash directory.
    """

    path = abspath(path)

    if not exists(path):
        raise TrashError("Path %s does not exist." % path)

    trash_dir = abspath(get_fd_trash_dir(path))

    # to make things easier
    if path.startswith(join(trash_dir, "")) or path == trash_dir:
        raise TrashError(
            "Can't move files to the trash from within thetrash directory."
        )

    files = join(trash_dir, "files")
    info = join(trash_dir, "info")

    for d in (files, info):
        if not isdir(d):
            os.makedirs(d, 0o700)

    info_ext = ".trashinfo"
    name = basename(path)
    flags = os.O_EXCL | os.O_CREAT | os.O_WRONLY
    mode = 0o644
    try:
        info_path = join(info, name + info_ext)
        info_fd = os.open(info_path, flags, mode)
    except OSError as e:
        if e.errno != errno.EEXIST:
            raise
        i = 2
        while 1:
            head, tail = splitext(name)
            temp_name = "%s.%d%s" % (head, i, tail)
            info_path = join(info, temp_name + info_ext)
            try:
                info_fd = os.open(info_path, flags, mode)
            except OSError as e:
                if e.errno != errno.EEXIST:
                    raise
                i += 1
                continue
            name = temp_name
            break

    parent = dirname(trash_dir)
    if path.startswith(join(parent, "")):
        norm_path = path[len(join(parent, "")) :]
    else:
        norm_path = path

    del_date = time.strftime("%Y-%m-%dT%H:%M:%S", time.localtime())

    data = "[Trash Info]\n"
    data += "Path=%s\n" % urllib.pathname2url(norm_path)
    data += "DeletionDate=%s\n" % del_date
    os.write(info_fd, data)
    os.close(info_fd)

    try:
        # We only move to the same file system.. so this is ok.
        os.rename(path, join(files, name))
    except OSError:
        # In case something failes, remove the info file and raise again
        os.unlink(info_path)
        raise


# Traceback (OSError)
# --&amp;gt; cat MiniDump_20140227_172244.txt
=== SYSTEM INFORMATION:
Quod Libet 3.0.2
Mutagen 1.22
Python 2.7.6 (default, Jan 12 2014, 08:16:39)
[GCC 4.8.2] linux2
Platform Linux-3.13.0-12-generic-x86_64-with-Ubuntu-14.04-trusty

=== STACK TRACE
Traceback (most recent call last):

File &amp;quot;/usr/lib/python2.7/dist-packages/quodlibet/qltk/songsmenu.py&amp;quot;, line 321, in __delete
removed = dict.fromkeys(d.run())

File &amp;quot;/usr/lib/python2.7/dist-packages/quodlibet/qltk/delete.py&amp;quot;, line 102, in run
trash.trash(filename)

File &amp;quot;/usr/lib/python2.7/dist-packages/quodlibet/util/trash.py&amp;quot;, line 131, in trash
trash_free_desktop(path)

File &amp;quot;/usr/lib/python2.7/dist-packages/quodlibet/util/trash.py&amp;quot;, line 74, in trash_free_desktop
os.makedirs(d, 0700)

File &amp;quot;/usr/lib/python2.7/os.py&amp;quot;, line 150, in makedirs
makedirs(head, mode)

File &amp;quot;/usr/lib/python2.7/os.py&amp;quot;, line 157, in makedirs
mkdir(name, mode)

OSError: [Errno 13] Keine Berechtigung: '/mnt/DATA/.Trash-1000'
==================================================================

Hint: &amp;quot;Keine Berechtigung&amp;quot; means &amp;quot;no authorization&amp;quot;

# --&amp;gt; ll /mnt/
drwxr-xr-x 9 root root 4096 Feb 26 11:59 DATA

The file to be deleted resides somewhere in /mnt/DATA/MM/MUSIC/...

I am running KDE Plattform-Version 4.12.2

Thanks !

PS: Nevertheless, QL is a great application !

# Fixed code
def trash_free_desktop(path):
    """Partial implementation of
    http://www.freedesktop.org/wiki/Specifications/trash-spec

    This doesn't work for files in the trash directory.
    """

    path = abspath(path)

    if not exists(path):
        raise TrashError("Path %s does not exist." % path)

    trash_dir = abspath(get_fd_trash_dir(path))

    # to make things easier
    if path.startswith(join(trash_dir, "")) or path == trash_dir:
        raise TrashError(
            "Can't move files to the trash from within thetrash directory."
        )

    files = join(trash_dir, "files")
    info = join(trash_dir, "info")

    for d in (files, info):
        if not isdir(d):
            os.makedirs(d, 0o700)

    info_ext = ".trashinfo"
    name = basename(path)
    flags = os.O_EXCL | os.O_CREAT | os.O_WRONLY
    mode = 0o644
    try:
        info_path = join(info, name + info_ext)
        info_fd = os.open(info_path, flags, mode)
    except OSError as e:
        if e.errno != errno.EEXIST:
            raise
        i = 2
        while 1:
            head, tail = splitext(name)
            temp_name = "%s.%d%s" % (head, i, tail)
            info_path = join(info, temp_name + info_ext)
            try:
                info_fd = os.open(info_path, flags, mode)
            except OSError as e:
                if e.errno != errno.EEXIST:
                    raise
                i += 1
                continue
            name = temp_name
            break

    parent = dirname(trash_dir)
    if path.startswith(join(parent, "")):
        norm_path = path[len(join(parent, "")) :]
    else:
        norm_path = path

    del_date = time.strftime("%Y-%m-%dT%H:%M:%S", time.localtime())

    data = "[Trash Info]\n"
    data += "Path=%s\n" % urllib.pathname2url(norm_path)
    data += "DeletionDate=%s\n" % del_date
    os.write(info_fd, data)
    os.close(info_fd)

    target_path = join(files, name)
    try:
        shutil.move(path, target_path)
    except OSError:
        os.unlink(info_path)
        raise