Browse Source

Define TrashPermissionError (#21)

Thomas Kluyver 3 years ago
committed by Virgil Dupras
4 changed files with 45 additions and 4 deletions
  1. +9
  2. +2
  3. +25
  4. +9

+ 9
- 1
README.rst View File

@@ -29,7 +29,15 @@ Usage
>>> from send2trash import send2trash
>>> send2trash('some_file')

When there's a problem ``OSError`` is raised.
On Freedesktop platforms (Linux, BSD, etc.), you may not be able to efficiently
trash some files. In these cases, an exception ``send2trash.TrashPermissionError``
is raised, so that the application can handle this case. This inherits from
``PermissionError`` (``OSError`` on Python 2). Specifically, this affects
files on a different device to the user's home directory, where the root of the
device does not have a ``.Trash`` directory, and we don't have permission to
create a ``.Trash-$UID`` directory.

For any other problem, ``OSError`` is raised.

.. _PyGObject:
.. _GIO:

+ 2
- 0
send2trash/ View File

@@ -6,6 +6,8 @@

import sys

from .exceptions import TrashPermissionError

if sys.platform == 'darwin':
from .plat_osx import send2trash
elif sys.platform == 'win32':

+ 25
- 0
send2trash/ View File

@@ -0,0 +1,25 @@
import errno
from .compat import PY3

if PY3:
_permission_error = PermissionError
_permission_error = OSError

class TrashPermissionError(_permission_error):
"""A permission error specific to a trash directory.

Raising this error indicates that permissions prevent us efficiently
trashing a file, although we might still have permission to delete it.
This is *not* used when permissions prevent removing the file itself:
that will be raised as a regular PermissionError (OSError on Python 2).

Application code that catches this may try to simply delete the file,
or prompt the user to decide, or (on Freedesktop platforms), move it to
'home trash' as a fallback. This last option probably involves copying the
data between partitions, devices, or network drives, so we don't do it as
a fallback.
def __init__(self, filename):
_permission_error.__init__(self, errno.EACCES, "Permission denied",

+ 9
- 3
send2trash/ View File

@@ -16,6 +16,7 @@

from __future__ import unicode_literals

import errno
import sys
import os
import os.path as op
@@ -28,6 +29,7 @@ except ImportError:
from urllib import quote

from .compat import text_type, environb
from .exceptions import TrashPermissionError

fsencode = os.fsencode # Python 3
@@ -134,9 +136,13 @@ def find_ext_volume_global_trash(volume_root):
def find_ext_volume_fallback_trash(volume_root):
# from [2] Trash directories (1) create a .Trash-$uid dir.
trash_dir = op.join(volume_root, TOPDIR_FALLBACK)
# Try to make the directory, if we can't the OSError exception will escape
# be thrown out of send2trash.
# Try to make the directory, if we lack permission, raise TrashPermissionError
except OSError as e:
if e.errno == errno.EACCES:
raise TrashPermissionError(e.filename)
return trash_dir

def find_ext_volume_trash(volume_root):