From fb14e3b3a19dd96cc9ba6fc7819dae3c1007ca4b Mon Sep 17 00:00:00 2001 From: Mathieu Bridon Date: Mon, 20 Oct 2014 14:02:18 +0200 Subject: [PATCH 1/2] New NoSpaceError This introduces a new OSError subclass, to handle cases where there is no space left when trying to perform an operation. It logically follows from the other OSError subclasses, and allows replacing the following: >>> try: ... do_something() ... except OSError as e: ... import errno ... if e.errno == errno.ENOSPC: ... handle_error() By the much nicer: >>> try: ... do_something() ... except NoSpaceError: ... handle_error() --- Doc/c-api/exceptions.rst | 5 +++++ Doc/library/exceptions.rst | 6 ++++++ Include/pyerrors.h | 1 + Lib/test/exception_hierarchy.txt | 1 + Lib/test/test_pep3151.py | 1 + Objects/exceptions.c | 5 +++++ 6 files changed, 19 insertions(+) diff --git a/Doc/c-api/exceptions.rst b/Doc/c-api/exceptions.rst index 8e70560..3a6209a 100644 --- a/Doc/c-api/exceptions.rst +++ b/Doc/c-api/exceptions.rst @@ -788,6 +788,8 @@ the variables: +-----------------------------------------+---------------------------------+----------+ | :c:data:`PyExc_NameError` | :exc:`NameError` | | +-----------------------------------------+---------------------------------+----------+ +| :c:data:`PyExc_NoSpaceError` | :exc:`NoSpaceError` | | ++-----------------------------------------+---------------------------------+----------+ | :c:data:`PyExc_NotADirectoryError` | :exc:`NotADirectoryError` | | +-----------------------------------------+---------------------------------+----------+ | :c:data:`PyExc_NotImplementedError` | :exc:`NotImplementedError` | | @@ -829,6 +831,8 @@ the variables: :c:data:`PyExc_PermissionError`, :c:data:`PyExc_ProcessLookupError` and :c:data:`PyExc_TimeoutError` were introduced following :pep:`3151`. +.. versionadded:: 3.5 + :c:data:`PyExc_NoSpaceError`. These are compatibility aliases to :c:data:`PyExc_OSError`: @@ -871,6 +875,7 @@ These are compatibility aliases to :c:data:`PyExc_OSError`: single: PyExc_KeyboardInterrupt single: PyExc_MemoryError single: PyExc_NameError + single: PyExc_NoSpaceError single: PyExc_NotADirectoryError single: PyExc_NotImplementedError single: PyExc_OSError diff --git a/Doc/library/exceptions.rst b/Doc/library/exceptions.rst index 74d6fcb..1940fb3 100644 --- a/Doc/library/exceptions.rst +++ b/Doc/library/exceptions.rst @@ -543,6 +543,12 @@ depending on the system error code. on a directory. Corresponds to :c:data:`errno` ``EISDIR``. +.. exception:: NoSpaceError + + Raised when a file operation fails because the underlying storage does not + have enough space left. + Corresponds to :c:data:`errno` ``ENOSPC``. + .. exception:: NotADirectoryError Raised when a directory operation (such as :func:`os.listdir`) is requested diff --git a/Include/pyerrors.h b/Include/pyerrors.h index 65b09f0..14add1a 100644 --- a/Include/pyerrors.h +++ b/Include/pyerrors.h @@ -192,6 +192,7 @@ PyAPI_DATA(PyObject *) PyExc_FileExistsError; PyAPI_DATA(PyObject *) PyExc_FileNotFoundError; PyAPI_DATA(PyObject *) PyExc_InterruptedError; PyAPI_DATA(PyObject *) PyExc_IsADirectoryError; +PyAPI_DATA(PyObject *) PyExc_NoSpaceError; PyAPI_DATA(PyObject *) PyExc_NotADirectoryError; PyAPI_DATA(PyObject *) PyExc_PermissionError; PyAPI_DATA(PyObject *) PyExc_ProcessLookupError; diff --git a/Lib/test/exception_hierarchy.txt b/Lib/test/exception_hierarchy.txt index 1c1f69f..f72a416 100644 --- a/Lib/test/exception_hierarchy.txt +++ b/Lib/test/exception_hierarchy.txt @@ -31,6 +31,7 @@ BaseException | +-- FileNotFoundError | +-- InterruptedError | +-- IsADirectoryError + | +-- NoSpaceError | +-- NotADirectoryError | +-- PermissionError | +-- ProcessLookupError diff --git a/Lib/test/test_pep3151.py b/Lib/test/test_pep3151.py index 7d4a5d8..ed925ba 100644 --- a/Lib/test/test_pep3151.py +++ b/Lib/test/test_pep3151.py @@ -64,6 +64,7 @@ class HierarchyTest(unittest.TestCase): +-- FileNotFoundError ENOENT +-- InterruptedError EINTR +-- IsADirectoryError EISDIR + +-- NoSpaceError ENOSPC +-- NotADirectoryError ENOTDIR +-- PermissionError EACCES, EPERM +-- ProcessLookupError ESRCH diff --git a/Objects/exceptions.c b/Objects/exceptions.c index 5532821..4214c20 100644 --- a/Objects/exceptions.c +++ b/Objects/exceptions.c @@ -1200,6 +1200,8 @@ MiddlingExtendsException(PyExc_OSError, FileNotFoundError, OSError, "File not found."); MiddlingExtendsException(PyExc_OSError, IsADirectoryError, OSError, "Operation doesn't work on directories."); +MiddlingExtendsException(PyExc_OSError, NoSpaceError, OSError, + "No space left on device."); MiddlingExtendsException(PyExc_OSError, NotADirectoryError, OSError, "Operation only works on directories."); MiddlingExtendsException(PyExc_OSError, InterruptedError, OSError, @@ -2521,6 +2523,7 @@ _PyExc_Init(PyObject *bltinmod) PRE_INIT(FileExistsError); PRE_INIT(FileNotFoundError); PRE_INIT(IsADirectoryError); + PRE_INIT(NoSpaceError); PRE_INIT(NotADirectoryError); PRE_INIT(InterruptedError); PRE_INIT(PermissionError); @@ -2615,6 +2618,8 @@ _PyExc_Init(PyObject *bltinmod) ADD_ERRNO(FileNotFoundError, ENOENT); POST_INIT(IsADirectoryError); ADD_ERRNO(IsADirectoryError, EISDIR); + POST_INIT(NoSpaceError); + ADD_ERRNO(NoSpaceError, ENOSPC); POST_INIT(NotADirectoryError); ADD_ERRNO(NotADirectoryError, ENOTDIR); POST_INIT(InterruptedError); -- 2.1.0