Commit 6b4883de authored by Antoine Pitrou's avatar Antoine Pitrou

PEP 3151 / issue #12555: reworking the OS and IO exception hierarchy.

parent 983b1434
......@@ -45,18 +45,18 @@ typedef struct {
PyObject *myerrno;
PyObject *strerror;
PyObject *filename;
} PyEnvironmentErrorObject;
#ifdef MS_WINDOWS
typedef struct {
PyException_HEAD
PyObject *myerrno;
PyObject *strerror;
PyObject *filename;
PyObject *winerror;
} PyWindowsErrorObject;
#endif
Py_ssize_t written; /* only for BlockingIOError, -1 otherwise */
} PyOSErrorObject;
/* Compatibility typedefs */
typedef PyOSErrorObject PyEnvironmentErrorObject;
#ifdef MS_WINDOWS
typedef PyOSErrorObject PyWindowsErrorObject;
#endif
#endif /* !Py_LIMITED_API */
/* Error handling definitions */
......@@ -132,10 +132,9 @@ PyAPI_DATA(PyObject *) PyExc_LookupError;
PyAPI_DATA(PyObject *) PyExc_AssertionError;
PyAPI_DATA(PyObject *) PyExc_AttributeError;
PyAPI_DATA(PyObject *) PyExc_BufferError;
PyAPI_DATA(PyObject *) PyExc_EOFError;
PyAPI_DATA(PyObject *) PyExc_FloatingPointError;
PyAPI_DATA(PyObject *) PyExc_EnvironmentError;
PyAPI_DATA(PyObject *) PyExc_IOError;
PyAPI_DATA(PyObject *) PyExc_OSError;
PyAPI_DATA(PyObject *) PyExc_ImportError;
PyAPI_DATA(PyObject *) PyExc_IndexError;
......@@ -160,6 +159,27 @@ PyAPI_DATA(PyObject *) PyExc_UnicodeDecodeError;
PyAPI_DATA(PyObject *) PyExc_UnicodeTranslateError;
PyAPI_DATA(PyObject *) PyExc_ValueError;
PyAPI_DATA(PyObject *) PyExc_ZeroDivisionError;
PyAPI_DATA(PyObject *) PyExc_BlockingIOError;
PyAPI_DATA(PyObject *) PyExc_BrokenPipeError;
PyAPI_DATA(PyObject *) PyExc_ChildProcessError;
PyAPI_DATA(PyObject *) PyExc_ConnectionError;
PyAPI_DATA(PyObject *) PyExc_ConnectionAbortedError;
PyAPI_DATA(PyObject *) PyExc_ConnectionRefusedError;
PyAPI_DATA(PyObject *) PyExc_ConnectionResetError;
PyAPI_DATA(PyObject *) PyExc_FileExistsError;
PyAPI_DATA(PyObject *) PyExc_FileNotFoundError;
PyAPI_DATA(PyObject *) PyExc_InterruptedError;
PyAPI_DATA(PyObject *) PyExc_IsADirectoryError;
PyAPI_DATA(PyObject *) PyExc_NotADirectoryError;
PyAPI_DATA(PyObject *) PyExc_PermissionError;
PyAPI_DATA(PyObject *) PyExc_ProcessLookupError;
PyAPI_DATA(PyObject *) PyExc_TimeoutError;
/* Compatibility aliases */
PyAPI_DATA(PyObject *) PyExc_EnvironmentError;
PyAPI_DATA(PyObject *) PyExc_IOError;
#ifdef MS_WINDOWS
PyAPI_DATA(PyObject *) PyExc_WindowsError;
#endif
......@@ -167,8 +187,6 @@ PyAPI_DATA(PyObject *) PyExc_WindowsError;
PyAPI_DATA(PyObject *) PyExc_VMSError;
#endif
PyAPI_DATA(PyObject *) PyExc_BufferError;
PyAPI_DATA(PyObject *) PyExc_RecursionErrorInst;
/* Predefined warning categories */
......
......@@ -23,16 +23,8 @@ DEFAULT_BUFFER_SIZE = 8 * 1024 # bytes
# defined in io.py. We don't use real inheritance though, because we don't
# want to inherit the C implementations.
class BlockingIOError(IOError):
"""Exception raised when I/O would block on a non-blocking I/O stream."""
def __init__(self, errno, strerror, characters_written=0):
super().__init__(errno, strerror)
if not isinstance(characters_written, int):
raise TypeError("characters_written must be a integer")
self.characters_written = characters_written
# Rebind for compatibility
BlockingIOError = BlockingIOError
def open(file, mode="r", buffering=-1, encoding=None, errors=None,
......
......@@ -321,7 +321,7 @@ if win32:
firstchunk = overlapped.getbuffer()
assert lenfirstchunk == len(firstchunk)
except IOError as e:
if e.errno == win32.ERROR_BROKEN_PIPE:
if e.winerror == win32.ERROR_BROKEN_PIPE:
raise EOFError
raise
buf.write(firstchunk)
......@@ -669,7 +669,7 @@ if sys.platform == 'win32':
try:
win32.ConnectNamedPipe(handle, win32.NULL)
except WindowsError as e:
if e.args[0] != win32.ERROR_PIPE_CONNECTED:
if e.winerror != win32.ERROR_PIPE_CONNECTED:
raise
return PipeConnection(handle)
......@@ -692,8 +692,8 @@ if sys.platform == 'win32':
0, win32.NULL, win32.OPEN_EXISTING, 0, win32.NULL
)
except WindowsError as e:
if e.args[0] not in (win32.ERROR_SEM_TIMEOUT,
win32.ERROR_PIPE_BUSY) or _check_timeout(t):
if e.winerror not in (win32.ERROR_SEM_TIMEOUT,
win32.ERROR_PIPE_BUSY) or _check_timeout(t):
raise
else:
break
......
......@@ -11,11 +11,6 @@ BaseException
+-- AssertionError
+-- AttributeError
+-- BufferError
+-- EnvironmentError
| +-- IOError
| +-- OSError
| +-- WindowsError (Windows)
| +-- VMSError (VMS)
+-- EOFError
+-- ImportError
+-- LookupError
......@@ -24,6 +19,22 @@ BaseException
+-- MemoryError
+-- NameError
| +-- UnboundLocalError
+-- OSError
| +-- BlockingIOError
| +-- ChildProcessError
| +-- ConnectionError
| | +-- BrokenPipeError
| | +-- ConnectionAbortedError
| | +-- ConnectionRefusedError
| | +-- ConnectionResetError
| +-- FileExistsError
| +-- FileNotFoundError
| +-- InterruptedError
| +-- IsADirectoryError
| +-- NotADirectoryError
| +-- PermissionError
| +-- ProcessLookupError
| +-- TimeoutError
+-- ReferenceError
+-- RuntimeError
| +-- NotImplementedError
......
......@@ -34,7 +34,7 @@ PENDING_FUTURE = create_future(state=PENDING)
RUNNING_FUTURE = create_future(state=RUNNING)
CANCELLED_FUTURE = create_future(state=CANCELLED)
CANCELLED_AND_NOTIFIED_FUTURE = create_future(state=CANCELLED_AND_NOTIFIED)
EXCEPTION_FUTURE = create_future(state=FINISHED, exception=IOError())
EXCEPTION_FUTURE = create_future(state=FINISHED, exception=OSError())
SUCCESSFUL_FUTURE = create_future(state=FINISHED, result=42)
......@@ -501,7 +501,7 @@ class FutureTests(unittest.TestCase):
'<Future at 0x[0-9a-f]+ state=cancelled>')
self.assertRegex(
repr(EXCEPTION_FUTURE),
'<Future at 0x[0-9a-f]+ state=finished raised IOError>')
'<Future at 0x[0-9a-f]+ state=finished raised OSError>')
self.assertRegex(
repr(SUCCESSFUL_FUTURE),
'<Future at 0x[0-9a-f]+ state=finished returned int>')
......@@ -512,7 +512,7 @@ class FutureTests(unittest.TestCase):
f2 = create_future(state=RUNNING)
f3 = create_future(state=CANCELLED)
f4 = create_future(state=CANCELLED_AND_NOTIFIED)
f5 = create_future(state=FINISHED, exception=IOError())
f5 = create_future(state=FINISHED, exception=OSError())
f6 = create_future(state=FINISHED, result=5)
self.assertTrue(f1.cancel())
......@@ -566,7 +566,7 @@ class FutureTests(unittest.TestCase):
CANCELLED_FUTURE.result, timeout=0)
self.assertRaises(futures.CancelledError,
CANCELLED_AND_NOTIFIED_FUTURE.result, timeout=0)
self.assertRaises(IOError, EXCEPTION_FUTURE.result, timeout=0)
self.assertRaises(OSError, EXCEPTION_FUTURE.result, timeout=0)
self.assertEqual(SUCCESSFUL_FUTURE.result(timeout=0), 42)
def test_result_with_success(self):
......@@ -605,7 +605,7 @@ class FutureTests(unittest.TestCase):
self.assertRaises(futures.CancelledError,
CANCELLED_AND_NOTIFIED_FUTURE.exception, timeout=0)
self.assertTrue(isinstance(EXCEPTION_FUTURE.exception(timeout=0),
IOError))
OSError))
self.assertEqual(SUCCESSFUL_FUTURE.exception(timeout=0), None)
def test_exception_with_success(self):
......@@ -614,14 +614,14 @@ class FutureTests(unittest.TestCase):
time.sleep(1)
with f1._condition:
f1._state = FINISHED
f1._exception = IOError()
f1._exception = OSError()
f1._condition.notify_all()
f1 = create_future(state=PENDING)
t = threading.Thread(target=notification)
t.start()
self.assertTrue(isinstance(f1.exception(timeout=5), IOError))
self.assertTrue(isinstance(f1.exception(timeout=5), OSError))
@test.support.reap_threads
def test_main():
......
......@@ -46,8 +46,8 @@ class ExceptionTests(unittest.TestCase):
fp.close()
unlink(TESTFN)
self.raise_catch(IOError, "IOError")
self.assertRaises(IOError, open, 'this file does not exist', 'r')
self.raise_catch(OSError, "OSError")
self.assertRaises(OSError, open, 'this file does not exist', 'r')
self.raise_catch(ImportError, "ImportError")
self.assertRaises(ImportError, __import__, "undefined_module")
......@@ -192,11 +192,35 @@ class ExceptionTests(unittest.TestCase):
except NameError:
pass
else:
self.assertEqual(str(WindowsError(1001)), "1001")
self.assertEqual(str(WindowsError(1001, "message")),
"[Error 1001] message")
self.assertEqual(WindowsError(1001, "message").errno, 22)
self.assertEqual(WindowsError(1001, "message").winerror, 1001)
self.assertIs(WindowsError, OSError)
self.assertEqual(str(OSError(1001)), "1001")
self.assertEqual(str(OSError(1001, "message")),
"[Errno 1001] message")
# POSIX errno (9 aka EBADF) is untranslated
w = OSError(9, 'foo', 'bar')
self.assertEqual(w.errno, 9)
self.assertEqual(w.winerror, None)
self.assertEqual(str(w), "[Errno 9] foo: 'bar'")
# ERROR_PATH_NOT_FOUND (win error 3) becomes ENOENT (2)
w = OSError(0, 'foo', 'bar', 3)
self.assertEqual(w.errno, 2)
self.assertEqual(w.winerror, 3)
self.assertEqual(w.strerror, 'foo')
self.assertEqual(w.filename, 'bar')
self.assertEqual(str(w), "[Error 3] foo: 'bar'")
# Unknown win error becomes EINVAL (22)
w = OSError(0, 'foo', None, 1001)
self.assertEqual(w.errno, 22)
self.assertEqual(w.winerror, 1001)
self.assertEqual(w.strerror, 'foo')
self.assertEqual(w.filename, None)
self.assertEqual(str(w), "[Error 1001] foo")
# Non-numeric "errno"
w = OSError('bar', 'foo')
self.assertEqual(w.errno, 'bar')
self.assertEqual(w.winerror, None)
self.assertEqual(w.strerror, 'foo')
self.assertEqual(w.filename, None)
def testAttributes(self):
# test that exception attributes are happy
......@@ -274,11 +298,12 @@ class ExceptionTests(unittest.TestCase):
'start' : 0, 'end' : 1}),
]
try:
# More tests are in test_WindowsError
exceptionList.append(
(WindowsError, (1, 'strErrorStr', 'filenameStr'),
{'args' : (1, 'strErrorStr'),
'strerror' : 'strErrorStr', 'winerror' : 1,
'errno' : 22, 'filename' : 'filenameStr'})
'strerror' : 'strErrorStr', 'winerror' : None,
'errno' : 1, 'filename' : 'filenameStr'})
)
except NameError:
pass
......
......@@ -248,18 +248,19 @@ class FileCookieJarTests(unittest.TestCase):
self.assertEqual(c._cookies["www.acme.com"]["/"]["boo"].value, None)
def test_bad_magic(self):
# IOErrors (eg. file doesn't exist) are allowed to propagate
# OSErrors (eg. file doesn't exist) are allowed to propagate
filename = test.support.TESTFN
for cookiejar_class in LWPCookieJar, MozillaCookieJar:
c = cookiejar_class()
try:
c.load(filename="for this test to work, a file with this "
"filename should not exist")
except IOError as exc:
# exactly IOError, not LoadError
self.assertIs(exc.__class__, IOError)
except OSError as exc:
# an OSError subclass (likely FileNotFoundError), but not
# LoadError
self.assertIsNot(exc.__class__, LoadError)
else:
self.fail("expected IOError for invalid filename")
self.fail("expected OSError for invalid filename")
# Invalid contents of cookies file (eg. bad magic string)
# causes a LoadError.
try:
......
......@@ -2643,12 +2643,6 @@ class MiscIOTest(unittest.TestCase):
def test_blockingioerror(self):
# Various BlockingIOError issues
self.assertRaises(TypeError, self.BlockingIOError)
self.assertRaises(TypeError, self.BlockingIOError, 1)
self.assertRaises(TypeError, self.BlockingIOError, 1, 2, 3, 4)
self.assertRaises(TypeError, self.BlockingIOError, 1, "", None)
b = self.BlockingIOError(1, "")
self.assertEqual(b.characters_written, 0)
class C(str):
pass
c = C("")
......
......@@ -563,8 +563,7 @@ class MmapTests(unittest.TestCase):
f.close()
def test_error(self):
self.assertTrue(issubclass(mmap.error, EnvironmentError))
self.assertIn("mmap.error", str(mmap.error))
self.assertIs(mmap.error, OSError)
def test_io_methods(self):
data = b"0123456789"
......
import builtins
import os
import select
import socket
import sys
import unittest
import errno
from errno import EEXIST
from test import support
class SubOSError(OSError):
pass
class HierarchyTest(unittest.TestCase):
def test_builtin_errors(self):
self.assertEqual(OSError.__name__, 'OSError')
self.assertIs(IOError, OSError)
self.assertIs(EnvironmentError, OSError)
def test_socket_errors(self):
self.assertIs(socket.error, IOError)
self.assertIs(socket.gaierror.__base__, OSError)
self.assertIs(socket.herror.__base__, OSError)
self.assertIs(socket.timeout.__base__, OSError)
def test_select_error(self):
self.assertIs(select.error, OSError)
# mmap.error is tested in test_mmap
_pep_map = """
+-- BlockingIOError EAGAIN, EALREADY, EWOULDBLOCK, EINPROGRESS
+-- ChildProcessError ECHILD
+-- ConnectionError
+-- BrokenPipeError EPIPE, ESHUTDOWN
+-- ConnectionAbortedError ECONNABORTED
+-- ConnectionRefusedError ECONNREFUSED
+-- ConnectionResetError ECONNRESET
+-- FileExistsError EEXIST
+-- FileNotFoundError ENOENT
+-- InterruptedError EINTR
+-- IsADirectoryError EISDIR
+-- NotADirectoryError ENOTDIR
+-- PermissionError EACCES, EPERM
+-- ProcessLookupError ESRCH
+-- TimeoutError ETIMEDOUT
"""
def _make_map(s):
_map = {}
for line in s.splitlines():
line = line.strip('+- ')
if not line:
continue
excname, _, errnames = line.partition(' ')
for errname in filter(None, errnames.strip().split(', ')):
_map[getattr(errno, errname)] = getattr(builtins, excname)
return _map
_map = _make_map(_pep_map)
def test_errno_mapping(self):
# The OSError constructor maps errnos to subclasses
# A sample test for the basic functionality
e = OSError(EEXIST, "Bad file descriptor")
self.assertIs(type(e), FileExistsError)
# Exhaustive testing
for errcode, exc in self._map.items():
e = OSError(errcode, "Some message")
self.assertIs(type(e), exc)
othercodes = set(errno.errorcode) - set(self._map)
for errcode in othercodes:
e = OSError(errcode, "Some message")
self.assertIs(type(e), OSError)
def test_OSError_subclass_mapping(self):
# When constructing an OSError subclass, errno mapping isn't done
e = SubOSError(EEXIST, "Bad file descriptor")
self.assertIs(type(e), SubOSError)
class AttributesTest(unittest.TestCase):
def test_windows_error(self):
if os.name == "nt":
self.assertIn('winerror', dir(OSError))
else:
self.assertNotIn('winerror', dir(OSError))
def test_posix_error(self):
e = OSError(EEXIST, "File already exists", "foo.txt")
self.assertEqual(e.errno, EEXIST)
self.assertEqual(e.args[0], EEXIST)
self.assertEqual(e.strerror, "File already exists")
self.assertEqual(e.filename, "foo.txt")
if os.name == "nt":
self.assertEqual(e.winerror, None)
@unittest.skipUnless(os.name == "nt", "Windows-specific test")
def test_errno_translation(self):
# ERROR_ALREADY_EXISTS (183) -> EEXIST
e = OSError(0, "File already exists", "foo.txt", 183)
self.assertEqual(e.winerror, 183)
self.assertEqual(e.errno, EEXIST)
self.assertEqual(e.args[0], EEXIST)
self.assertEqual(e.strerror, "File already exists")
self.assertEqual(e.filename, "foo.txt")
def test_blockingioerror(self):
args = ("a", "b", "c", "d", "e")
for n in range(6):
e = BlockingIOError(*args[:n])
with self.assertRaises(AttributeError):
e.characters_written
e = BlockingIOError("a", "b", 3)
self.assertEqual(e.characters_written, 3)
e.characters_written = 5
self.assertEqual(e.characters_written, 5)
# XXX VMSError not tested
def test_main():
support.run_unittest(__name__)
if __name__=="__main__":
test_main()
......@@ -1339,7 +1339,7 @@ def xinclude_loader(href, parse="xml", encoding=None):
try:
data = XINCLUDE[href]
except KeyError:
raise IOError("resource not found")
raise OSError("resource not found")
if parse == "xml":
from xml.etree.ElementTree import XML
return XML(data)
......@@ -1404,7 +1404,7 @@ def xinclude():
>>> document = xinclude_loader("C5.xml")
>>> ElementInclude.include(document, xinclude_loader)
Traceback (most recent call last):
IOError: resource not found
OSError: resource not found
>>> # print(serialize(document)) # C5
"""
......@@ -1611,7 +1611,7 @@ def bug_xmltoolkit55():
class ExceptionFile:
def read(self, x):
raise IOError
raise OSError
def xmltoolkit60():
"""
......@@ -1619,7 +1619,7 @@ def xmltoolkit60():
Handle crash in stream source.
>>> tree = ET.parse(ExceptionFile())
Traceback (most recent call last):
IOError
OSError
"""
......
......@@ -1547,6 +1547,8 @@ class URLopener:
return getattr(self, name)(url)
else:
return getattr(self, name)(url, data)
except HTTPError:
raise
except socket.error as msg:
raise IOError('socket error', msg).with_traceback(sys.exc_info()[2])
......
......@@ -10,6 +10,8 @@ What's New in Python 3.3 Alpha 1?
Core and Builtins
-----------------
- PEP 3151 / issue #12555: reworking the OS and IO exception hierarchy.
- Add internal API for static strings (_Py_identifier et.al.).
- Issue #13063: the Windows error ERROR_NO_DATA (numbered 232 and described
......
......@@ -90,89 +90,6 @@ PyDoc_STRVAR(module_doc,
);
/*
* BlockingIOError extends IOError
*/
static int
blockingioerror_init(PyBlockingIOErrorObject *self, PyObject *args,
PyObject *kwds)
{
PyObject *myerrno = NULL, *strerror = NULL;
PyObject *baseargs = NULL;
Py_ssize_t written = 0;
assert(PyTuple_Check(args));
self->written = 0;
if (!PyArg_ParseTuple(args, "OO|n:BlockingIOError",
&myerrno, &strerror, &written))
return -1;
baseargs = PyTuple_Pack(2, myerrno, strerror);
if (baseargs == NULL)
return -1;
/* This will take care of initializing of myerrno and strerror members */
if (((PyTypeObject *)PyExc_IOError)->tp_init(
(PyObject *)self, baseargs, kwds) == -1) {
Py_DECREF(baseargs);
return -1;
}
Py_DECREF(baseargs);
self->written = written;
return 0;
}
static PyMemberDef blockingioerror_members[] = {
{"characters_written", T_PYSSIZET, offsetof(PyBlockingIOErrorObject, written), 0},
{NULL} /* Sentinel */
};
static PyTypeObject _PyExc_BlockingIOError = {
PyVarObject_HEAD_INIT(NULL, 0)
"BlockingIOError", /*tp_name*/
sizeof(PyBlockingIOErrorObject), /*tp_basicsize*/
0, /*tp_itemsize*/
0, /*tp_dealloc*/
0, /*tp_print*/
0, /*tp_getattr*/
0, /*tp_setattr*/
0, /*tp_compare */
0, /*tp_repr*/
0, /*tp_as_number*/
0, /*tp_as_sequence*/
0, /*tp_as_mapping*/
0, /*tp_hash */
0, /*tp_call*/
0, /*tp_str*/
0, /*tp_getattro*/
0, /*tp_setattro*/
0, /*tp_as_buffer*/
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
PyDoc_STR("Exception raised when I/O would block "
"on a non-blocking I/O stream"), /* tp_doc */
0, /* tp_traverse */
0, /* tp_clear */
0, /* tp_richcompare */
0, /* tp_weaklistoffset */
0, /* tp_iter */
0, /* tp_iternext */
0, /* tp_methods */
blockingioerror_members, /* tp_members */
0, /* tp_getset */
0, /* tp_base */
0, /* tp_dict */
0, /* tp_descr_get */
0, /* tp_descr_set */
0, /* tp_dictoffset */
(initproc)blockingioerror_init, /* tp_init */
0, /* tp_alloc */
0, /* tp_new */
};
PyObject *PyExc_BlockingIOError = (PyObject *)&_PyExc_BlockingIOError;
/*
* The main open() function
*/
......@@ -694,9 +611,11 @@ PyInit__io(void)
state->unsupported_operation) < 0)
goto fail;
/* BlockingIOError */
_PyExc_BlockingIOError.tp_base = (PyTypeObject *) PyExc_IOError;
ADD_TYPE(&_PyExc_BlockingIOError, "BlockingIOError");
/* BlockingIOError, for compatibility */
Py_INCREF(PyExc_BlockingIOError);
if (PyModule_AddObject(m, "BlockingIOError",
(PyObject *) PyExc_BlockingIOError) < 0)
goto fail;
/* Concrete base types of the IO ABCs.
(the ABCs themselves are declared through inheritance in io.py)
......
......@@ -60,15 +60,6 @@ extern Py_ssize_t _PyIO_find_line_ending(
#define DEFAULT_BUFFER_SIZE (8 * 1024) /* bytes */
typedef struct {
PyException_HEAD
PyObject *myerrno;
PyObject *strerror;
PyObject *filename; /* Not used, but part of the IOError object */
Py_ssize_t written;
} PyBlockingIOErrorObject;
PyAPI_DATA(PyObject *) PyExc_BlockingIOError;
/*
* Offset type for positioning.
*/
......
......@@ -622,14 +622,14 @@ static Py_ssize_t *
_buffered_check_blocking_error(void)
{
PyObject *t, *v, *tb;
PyBlockingIOErrorObject *err;
PyOSErrorObject *err;
PyErr_Fetch(&t, &v, &tb);
if (v == NULL || !PyErr_GivenExceptionMatches(v, PyExc_BlockingIOError)) {
PyErr_Restore(t, v, tb);
return NULL;
}
err = (PyBlockingIOErrorObject *) v;
err = (PyOSErrorObject *) v;
/* TODO: sanity check (err->written >= 0) */
PyErr_Restore(t, v, tb);
return &err->written;
......
......@@ -78,8 +78,6 @@ my_getpagesize(void)
# define MAP_ANONYMOUS MAP_ANON
#endif
static PyObject *mmap_module_error;
typedef enum
{
ACCESS_DEFAULT,
......@@ -459,7 +457,7 @@ mmap_size_method(mmap_object *self,
{
struct stat buf;
if (-1 == fstat(self->fd, &buf)) {
PyErr_SetFromErrno(mmap_module_error);
PyErr_SetFromErrno(PyExc_OSError);
return NULL;
}
#ifdef HAVE_LARGEFILE_SUPPORT
......@@ -549,7 +547,7 @@ mmap_resize_method(mmap_object *self,
void *newmap;
if (ftruncate(self->fd, self->offset + new_size) == -1) {
PyErr_SetFromErrno(mmap_module_error);
PyErr_SetFromErrno(PyExc_OSError);
return NULL;
}
......@@ -564,7 +562,7 @@ mmap_resize_method(mmap_object *self,
#endif
if (newmap == (void *)-1)
{
PyErr_SetFromErrno(mmap_module_error);
PyErr_SetFromErrno(PyExc_OSError);
return NULL;
}
self->data = newmap;
......@@ -605,7 +603,7 @@ mmap_flush_method(mmap_object *self, PyObject *args)
/* XXX semantics of return value? */
/* XXX flags for msync? */
if (-1 == msync(self->data + offset, size, MS_SYNC)) {
PyErr_SetFromErrno(mmap_module_error);
PyErr_SetFromErrno(PyExc_OSError);
return NULL;
}
return PyLong_FromLong(0);
......@@ -1205,7 +1203,7 @@ new_mmap_object(PyTypeObject *type, PyObject *args, PyObject *kwdict)
fd = devzero = open("/dev/zero", O_RDWR);
if (devzero == -1) {
Py_DECREF(m_obj);
PyErr_SetFromErrno(mmap_module_error);
PyErr_SetFromErrno(PyExc_OSError);
return NULL;
}
#endif
......@@ -1213,7 +1211,7 @@ new_mmap_object(PyTypeObject *type, PyObject *args, PyObject *kwdict)
m_obj->fd = dup(fd);
if (m_obj->fd == -1) {
Py_DECREF(m_obj);
PyErr_SetFromErrno(mmap_module_error);
PyErr_SetFromErrno(PyExc_OSError);
return NULL;
}
}
......@@ -1229,7 +1227,7 @@ new_mmap_object(PyTypeObject *type, PyObject *args, PyObject *kwdict)
if (m_obj->data == (char *)-1) {
m_obj->data = NULL;
Py_DECREF(m_obj);
PyErr_SetFromErrno(mmap_module_error);
PyErr_SetFromErrno(PyExc_OSError);
return NULL;
}
m_obj->access = (access_mode)access;
......@@ -1310,12 +1308,12 @@ new_mmap_object(PyTypeObject *type, PyObject *args, PyObject *kwdict)
if (fileno != -1 && fileno != 0) {
/* Ensure that fileno is within the CRT's valid range */
if (_PyVerify_fd(fileno) == 0) {
PyErr_SetFromErrno(mmap_module_error);
PyErr_SetFromErrno(PyExc_OSError);
return NULL;
}
fh = (HANDLE)_get_osfhandle(fileno);
if (fh==(HANDLE)-1) {
PyErr_SetFromErrno(mmap_module_error);
PyErr_SetFromErrno(PyExc_OSError);
return NULL;
}
/* Win9x appears to need us seeked to zero */
......@@ -1469,11 +1467,7 @@ PyInit_mmap(void)
dict = PyModule_GetDict(module);
if (!dict)
return NULL;
mmap_module_error = PyErr_NewException("mmap.error",
PyExc_EnvironmentError , NULL);
if (mmap_module_error == NULL)
return NULL;
PyDict_SetItemString(dict, "error", mmap_module_error);
PyDict_SetItemString(dict, "error", PyExc_OSError);
PyDict_SetItemString(dict, "mmap", (PyObject*) &mmap_object_type);
#ifdef PROT_EXEC
setint(dict, "PROT_EXEC", PROT_EXEC);
......
......@@ -54,8 +54,6 @@ extern void bzero(void *, int);
# endif
#endif
static PyObject *SelectError;
/* list of Python objects and their file descriptor */
typedef struct {
PyObject *obj; /* owned reference */
......@@ -274,11 +272,11 @@ select_select(PyObject *self, PyObject *args)
#ifdef MS_WINDOWS
if (n == SOCKET_ERROR) {
PyErr_SetExcFromWindowsErr(SelectError, WSAGetLastError());
PyErr_SetExcFromWindowsErr(PyExc_OSError, WSAGetLastError());
}
#else
if (n < 0) {
PyErr_SetFromErrno(SelectError);
PyErr_SetFromErrno(PyExc_OSError);
}
#endif
else {
......@@ -425,7 +423,7 @@ poll_modify(pollObject *self, PyObject *args)
return NULL;
if (PyDict_GetItem(self->dict, key) == NULL) {
errno = ENOENT;
PyErr_SetFromErrno(PyExc_IOError);
PyErr_SetFromErrno(PyExc_OSError);
return NULL;
}
value = PyLong_FromLong(events);
......@@ -524,7 +522,7 @@ poll_poll(pollObject *self, PyObject *args)
Py_END_ALLOW_THREADS
if (poll_result < 0) {
PyErr_SetFromErrno(SelectError);
PyErr_SetFromErrno(PyExc_OSError);
return NULL;
}
......@@ -764,7 +762,7 @@ newPyEpoll_Object(PyTypeObject *type, int sizehint, SOCKET fd)
}
if (self->epfd < 0) {
Py_DECREF(self);
PyErr_SetFromErrno(PyExc_IOError);
PyErr_SetFromErrno(PyExc_OSError);
return NULL;
}
return (PyObject *)self;
......@@ -797,7 +795,7 @@ pyepoll_close(pyEpoll_Object *self)
{
errno = pyepoll_internal_close(self);
if (errno < 0) {
PyErr_SetFromErrno(PyExc_IOError);
PyErr_SetFromErrno(PyExc_OSError);
return NULL;
}
Py_RETURN_NONE;
......@@ -890,7 +888,7 @@ pyepoll_internal_ctl(int epfd, int op, PyObject *pfd, unsigned int events)
}
if (result < 0) {
PyErr_SetFromErrno(PyExc_IOError);
PyErr_SetFromErrno(PyExc_OSError);
return NULL;
}
Py_RETURN_NONE;
......@@ -914,7 +912,7 @@ pyepoll_register(pyEpoll_Object *self, PyObject *args, PyObject *kwds)
PyDoc_STRVAR(pyepoll_register_doc,
"register(fd[, eventmask]) -> None\n\
\n\
Registers a new fd or raises an IOError if the fd is already registered.\n\
Registers a new fd or raises an OSError if the fd is already registered.\n\
fd is the target file descriptor of the operation.\n\
events is a bit set composed of the various EPOLL constants; the default\n\
is EPOLL_IN | EPOLL_OUT | EPOLL_PRI.\n\
......@@ -1013,7 +1011,7 @@ pyepoll_poll(pyEpoll_Object *self, PyObject *args, PyObject *kwds)
nfds = epoll_wait(self->epfd, evs, maxevents, timeout);
Py_END_ALLOW_THREADS
if (nfds < 0) {
PyErr_SetFromErrno(PyExc_IOError);
PyErr_SetFromErrno(PyExc_OSError);
goto error;
}
......@@ -1404,7 +1402,7 @@ newKqueue_Object(PyTypeObject *type, SOCKET fd)
}
if (self->kqfd < 0) {
Py_DECREF(self);
PyErr_SetFromErrno(PyExc_IOError);
PyErr_SetFromErrno(PyExc_OSError);
return NULL;
}
return (PyObject *)self;
......@@ -1436,7 +1434,7 @@ kqueue_queue_close(kqueue_queue_Object *self)
{
errno = kqueue_queue_internal_close(self);
if (errno < 0) {
PyErr_SetFromErrno(PyExc_IOError);
PyErr_SetFromErrno(PyExc_OSError);
return NULL;
}
Py_RETURN_NONE;
......@@ -1778,9 +1776,8 @@ PyInit_select(void)
if (m == NULL)
return NULL;
SelectError = PyErr_NewException("select.error", NULL, NULL);
Py_INCREF(SelectError);
PyModule_AddObject(m, "error", SelectError);
Py_INCREF(PyExc_OSError);
PyModule_AddObject(m, "error", PyExc_OSError);
#ifdef PIPE_BUF
#ifdef HAVE_BROKEN_PIPE_BUF
......
This diff is collapsed.
This diff is collapsed.
......@@ -496,10 +496,11 @@ PyObject *PyErr_SetExcFromWindowsErrWithFilenameObject(
return NULL;
}
if (filenameObject != NULL)
v = Py_BuildValue("(iOO)", err, message, filenameObject);
else
v = Py_BuildValue("(iO)", err, message);
if (filenameObject == NULL)
filenameObject = Py_None;
/* This is the constructor signature for passing a Windows error code.
The POSIX translation will be figured out by the constructor. */
v = Py_BuildValue("(iOOi)", 0, message, filenameObject, err);
Py_DECREF(message);
if (v != NULL) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment