mirror of
https://github.com/python/cpython.git
synced 2025-07-27 13:14:41 +00:00
Change WindowsError to carry the Win32 error code in winerror,
and the DOS error code in errno. Revert changes where WindowsError catch blocks unnecessarily special-case OSError.
This commit is contained in:
parent
38e3b7d2d3
commit
879768dd97
8 changed files with 234 additions and 37 deletions
|
@ -399,11 +399,15 @@ Raised when an \keyword{assert} statement fails.
|
||||||
\begin{excdesc}{WindowsError}
|
\begin{excdesc}{WindowsError}
|
||||||
Raised when a Windows-specific error occurs or when the error number
|
Raised when a Windows-specific error occurs or when the error number
|
||||||
does not correspond to an \cdata{errno} value. The
|
does not correspond to an \cdata{errno} value. The
|
||||||
\member{errno} and \member{strerror} values are created from the
|
\member{winerror} and \member{strerror} values are created from the
|
||||||
return values of the \cfunction{GetLastError()} and
|
return values of the \cfunction{GetLastError()} and
|
||||||
\cfunction{FormatMessage()} functions from the Windows Platform API.
|
\cfunction{FormatMessage()} functions from the Windows Platform API.
|
||||||
|
The \member{errno} value maps the \member{winerror} value to
|
||||||
|
corresponding \code{errno.h} values.
|
||||||
This is a subclass of \exception{OSError}.
|
This is a subclass of \exception{OSError}.
|
||||||
\versionadded{2.0}
|
\versionadded{2.0}
|
||||||
|
\versionchanged[Previous versions put the \cfunction{GetLastError()}
|
||||||
|
codes into \member{errno}]{2.5}
|
||||||
\end{excdesc}
|
\end{excdesc}
|
||||||
|
|
||||||
\begin{excdesc}{ZeroDivisionError}
|
\begin{excdesc}{ZeroDivisionError}
|
||||||
|
|
|
@ -24,12 +24,6 @@ __all__ = [ 'Mailbox', 'Maildir', 'mbox', 'MH', 'Babyl', 'MMDF',
|
||||||
'BabylMessage', 'MMDFMessage', 'UnixMailbox',
|
'BabylMessage', 'MMDFMessage', 'UnixMailbox',
|
||||||
'PortableUnixMailbox', 'MmdfMailbox', 'MHMailbox', 'BabylMailbox' ]
|
'PortableUnixMailbox', 'MmdfMailbox', 'MHMailbox', 'BabylMailbox' ]
|
||||||
|
|
||||||
if sys.platform != 'win32':
|
|
||||||
# Define WindowsError so that we can use it in an except statement
|
|
||||||
# even on non-Windows systems
|
|
||||||
class WindowsError:
|
|
||||||
pass
|
|
||||||
|
|
||||||
class Mailbox:
|
class Mailbox:
|
||||||
"""A group of messages in a particular place."""
|
"""A group of messages in a particular place."""
|
||||||
|
|
||||||
|
@ -268,9 +262,6 @@ class Maildir(Mailbox):
|
||||||
self.remove(key)
|
self.remove(key)
|
||||||
except KeyError:
|
except KeyError:
|
||||||
pass
|
pass
|
||||||
except WindowsError, e:
|
|
||||||
if e.errno != 2: # ERROR_FILE_NOT_FOUND
|
|
||||||
raise
|
|
||||||
except OSError, e:
|
except OSError, e:
|
||||||
if e.errno != errno.ENOENT:
|
if e.errno != errno.ENOENT:
|
||||||
raise
|
raise
|
||||||
|
@ -426,12 +417,6 @@ class Maildir(Mailbox):
|
||||||
path = os.path.join(self._path, 'tmp', uniq)
|
path = os.path.join(self._path, 'tmp', uniq)
|
||||||
try:
|
try:
|
||||||
os.stat(path)
|
os.stat(path)
|
||||||
except WindowsError, e:
|
|
||||||
if e.errno == 2: # ERROR_FILE_NOT_FOUND
|
|
||||||
Maildir._count += 1
|
|
||||||
return open(path, 'wb+')
|
|
||||||
else:
|
|
||||||
raise
|
|
||||||
except OSError, e:
|
except OSError, e:
|
||||||
if e.errno == errno.ENOENT:
|
if e.errno == errno.ENOENT:
|
||||||
Maildir._count += 1
|
Maildir._count += 1
|
||||||
|
@ -579,12 +564,6 @@ class _singlefileMailbox(Mailbox):
|
||||||
self._file.close()
|
self._file.close()
|
||||||
try:
|
try:
|
||||||
os.rename(new_file.name, self._path)
|
os.rename(new_file.name, self._path)
|
||||||
except WindowsError, e:
|
|
||||||
if e.errno == 183: # ERROR_ALREADY_EXISTS
|
|
||||||
os.remove(self._path)
|
|
||||||
os.rename(new_file.name, self._path)
|
|
||||||
else:
|
|
||||||
raise
|
|
||||||
except OSError, e:
|
except OSError, e:
|
||||||
if e.errno == errno.EEXIST:
|
if e.errno == errno.EEXIST:
|
||||||
os.remove(self._path)
|
os.remove(self._path)
|
||||||
|
@ -1856,13 +1835,6 @@ def _lock_file(f, dotlock=True):
|
||||||
else:
|
else:
|
||||||
os.rename(pre_lock.name, f.name + '.lock')
|
os.rename(pre_lock.name, f.name + '.lock')
|
||||||
dotlock_done = True
|
dotlock_done = True
|
||||||
except WindowsError, e:
|
|
||||||
if e.errno == 183: # ERROR_ALREADY_EXISTS
|
|
||||||
os.remove(pre_lock.name)
|
|
||||||
raise ExternalClashError('dot lock unavailable: %s' %
|
|
||||||
f.name)
|
|
||||||
else:
|
|
||||||
raise
|
|
||||||
except OSError, e:
|
except OSError, e:
|
||||||
if e.errno == errno.EEXIST:
|
if e.errno == errno.EEXIST:
|
||||||
os.remove(pre_lock.name)
|
os.remove(pre_lock.name)
|
||||||
|
|
|
@ -327,10 +327,6 @@ def mkdtemp(suffix="", prefix=template, dir=None):
|
||||||
try:
|
try:
|
||||||
_os.mkdir(file, 0700)
|
_os.mkdir(file, 0700)
|
||||||
return file
|
return file
|
||||||
except WindowsError, e:
|
|
||||||
if e.errno == 183: # ERROR_ALREADY_EXISTS
|
|
||||||
continue # try again
|
|
||||||
raise
|
|
||||||
except OSError, e:
|
except OSError, e:
|
||||||
if e.errno == _errno.EEXIST:
|
if e.errno == _errno.EEXIST:
|
||||||
continue # try again
|
continue # try again
|
||||||
|
|
|
@ -12,6 +12,11 @@ What's New in Python 2.5 alpha 2?
|
||||||
Core and builtins
|
Core and builtins
|
||||||
-----------------
|
-----------------
|
||||||
|
|
||||||
|
- WindowsError now has two error code attributes: errno, which carries
|
||||||
|
the error values from errno.h, and winerror, which carries the error
|
||||||
|
values from winerror.h. Previous versions put the winerror.h values
|
||||||
|
(from GetLastError()) into the errno attribute.
|
||||||
|
|
||||||
- Patch #1475845: Raise IndentationError for unexpected indent.
|
- Patch #1475845: Raise IndentationError for unexpected indent.
|
||||||
|
|
||||||
- Patch #1479181: split open() and file() from being aliases for each other.
|
- Patch #1479181: split open() and file() from being aliases for each other.
|
||||||
|
|
78
PC/errmap.h
Normal file
78
PC/errmap.h
Normal file
|
@ -0,0 +1,78 @@
|
||||||
|
/* Generated file. Do not edit. */
|
||||||
|
int winerror_to_errno(int winerror)
|
||||||
|
{
|
||||||
|
switch(winerror) {
|
||||||
|
case 2: return 2;
|
||||||
|
case 3: return 2;
|
||||||
|
case 4: return 24;
|
||||||
|
case 5: return 13;
|
||||||
|
case 6: return 9;
|
||||||
|
case 7: return 12;
|
||||||
|
case 8: return 12;
|
||||||
|
case 9: return 12;
|
||||||
|
case 10: return 7;
|
||||||
|
case 11: return 8;
|
||||||
|
case 15: return 2;
|
||||||
|
case 16: return 13;
|
||||||
|
case 17: return 18;
|
||||||
|
case 18: return 2;
|
||||||
|
case 19: return 13;
|
||||||
|
case 20: return 13;
|
||||||
|
case 21: return 13;
|
||||||
|
case 22: return 13;
|
||||||
|
case 23: return 13;
|
||||||
|
case 24: return 13;
|
||||||
|
case 25: return 13;
|
||||||
|
case 26: return 13;
|
||||||
|
case 27: return 13;
|
||||||
|
case 28: return 13;
|
||||||
|
case 29: return 13;
|
||||||
|
case 30: return 13;
|
||||||
|
case 31: return 13;
|
||||||
|
case 32: return 13;
|
||||||
|
case 33: return 13;
|
||||||
|
case 34: return 13;
|
||||||
|
case 35: return 13;
|
||||||
|
case 36: return 13;
|
||||||
|
case 53: return 2;
|
||||||
|
case 65: return 13;
|
||||||
|
case 67: return 2;
|
||||||
|
case 80: return 17;
|
||||||
|
case 82: return 13;
|
||||||
|
case 83: return 13;
|
||||||
|
case 89: return 11;
|
||||||
|
case 108: return 13;
|
||||||
|
case 109: return 32;
|
||||||
|
case 112: return 28;
|
||||||
|
case 114: return 9;
|
||||||
|
case 128: return 10;
|
||||||
|
case 129: return 10;
|
||||||
|
case 130: return 9;
|
||||||
|
case 132: return 13;
|
||||||
|
case 145: return 41;
|
||||||
|
case 158: return 13;
|
||||||
|
case 161: return 2;
|
||||||
|
case 164: return 11;
|
||||||
|
case 167: return 13;
|
||||||
|
case 183: return 17;
|
||||||
|
case 188: return 8;
|
||||||
|
case 189: return 8;
|
||||||
|
case 190: return 8;
|
||||||
|
case 191: return 8;
|
||||||
|
case 192: return 8;
|
||||||
|
case 193: return 8;
|
||||||
|
case 194: return 8;
|
||||||
|
case 195: return 8;
|
||||||
|
case 196: return 8;
|
||||||
|
case 197: return 8;
|
||||||
|
case 198: return 8;
|
||||||
|
case 199: return 8;
|
||||||
|
case 200: return 8;
|
||||||
|
case 201: return 8;
|
||||||
|
case 202: return 8;
|
||||||
|
case 206: return 2;
|
||||||
|
case 215: return 11;
|
||||||
|
case 1816: return 12;
|
||||||
|
default: return EINVAL;
|
||||||
|
}
|
||||||
|
}
|
5
PC/errmap.mak
Normal file
5
PC/errmap.mak
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
errmap.h: generrmap.exe
|
||||||
|
.\generrmap.exe > errmap.h
|
||||||
|
|
||||||
|
genermap.exe: generrmap.c
|
||||||
|
cl generrmap.c
|
20
PC/generrmap.c
Normal file
20
PC/generrmap.c
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
/* Extract the mapping of Win32 error codes to errno */
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
printf("/* Generated file. Do not edit. */\n");
|
||||||
|
printf("int winerror_to_errno(int winerror)\n");
|
||||||
|
printf("{\n\tswitch(winerror) {\n");
|
||||||
|
for(i=1; i < 65000; i++) {
|
||||||
|
_dosmaperr(i);
|
||||||
|
if (errno == EINVAL)
|
||||||
|
continue;
|
||||||
|
printf("\t\tcase %d: return %d;\n", i, errno);
|
||||||
|
}
|
||||||
|
printf("\t\tdefault: return EINVAL;\n");
|
||||||
|
printf("\t}\n}\n");
|
||||||
|
}
|
|
@ -704,15 +704,132 @@ PyMethodDef EnvironmentError_methods[] = {
|
||||||
{NULL, NULL}
|
{NULL, NULL}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
PyDoc_STRVAR(IOError__doc__, "I/O operation failed.");
|
PyDoc_STRVAR(IOError__doc__, "I/O operation failed.");
|
||||||
|
|
||||||
PyDoc_STRVAR(OSError__doc__, "OS system call failed.");
|
PyDoc_STRVAR(OSError__doc__, "OS system call failed.");
|
||||||
|
|
||||||
#ifdef MS_WINDOWS
|
#ifdef MS_WINDOWS
|
||||||
|
#include "errmap.h"
|
||||||
|
|
||||||
PyDoc_STRVAR(WindowsError__doc__, "MS-Windows OS system call failed.");
|
PyDoc_STRVAR(WindowsError__doc__, "MS-Windows OS system call failed.");
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
WindowsError__init__(PyObject *self, PyObject *args)
|
||||||
|
{
|
||||||
|
PyObject *o_errcode, *result;
|
||||||
|
long errcode, posix_errno;
|
||||||
|
result = EnvironmentError__init__(self, args);
|
||||||
|
if (!result)
|
||||||
|
return NULL;
|
||||||
|
self = get_self(args);
|
||||||
|
if (!self)
|
||||||
|
goto failed;
|
||||||
|
/* Set errno to the POSIX errno, and winerror to the Win32
|
||||||
|
error code. */
|
||||||
|
o_errcode = PyObject_GetAttrString(self, "errno");
|
||||||
|
if (!o_errcode)
|
||||||
|
goto failed;
|
||||||
|
errcode = PyInt_AsLong(o_errcode);
|
||||||
|
if (!errcode == -1 && PyErr_Occurred())
|
||||||
|
goto failed;
|
||||||
|
posix_errno = winerror_to_errno(errcode);
|
||||||
|
if (PyObject_SetAttrString(self, "winerror", o_errcode) < 0)
|
||||||
|
goto failed;
|
||||||
|
Py_DECREF(o_errcode);
|
||||||
|
o_errcode = PyInt_FromLong(posix_errno);
|
||||||
|
if (!o_errcode)
|
||||||
|
goto failed;
|
||||||
|
if (PyObject_SetAttrString(self, "errno", o_errcode) < 0)
|
||||||
|
goto failed;
|
||||||
|
Py_DECREF(o_errcode);
|
||||||
|
return result;
|
||||||
|
failed:
|
||||||
|
/* Could not set errno. */
|
||||||
|
Py_XDECREF(o_errcode);
|
||||||
|
Py_DECREF(self);
|
||||||
|
Py_DECREF(result);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
WindowsError__str__(PyObject *self, PyObject *args)
|
||||||
|
{
|
||||||
|
PyObject *originalself = self;
|
||||||
|
PyObject *filename;
|
||||||
|
PyObject *serrno;
|
||||||
|
PyObject *strerror;
|
||||||
|
PyObject *rtnval = NULL;
|
||||||
|
|
||||||
|
if (!PyArg_ParseTuple(args, "O:__str__", &self))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
filename = PyObject_GetAttrString(self, "filename");
|
||||||
|
serrno = PyObject_GetAttrString(self, "winerror");
|
||||||
|
strerror = PyObject_GetAttrString(self, "strerror");
|
||||||
|
if (!filename || !serrno || !strerror)
|
||||||
|
goto finally;
|
||||||
|
|
||||||
|
if (filename != Py_None) {
|
||||||
|
PyObject *fmt = PyString_FromString("[Error %s] %s: %s");
|
||||||
|
PyObject *repr = PyObject_Repr(filename);
|
||||||
|
PyObject *tuple = PyTuple_New(3);
|
||||||
|
|
||||||
|
if (!fmt || !repr || !tuple) {
|
||||||
|
Py_XDECREF(fmt);
|
||||||
|
Py_XDECREF(repr);
|
||||||
|
Py_XDECREF(tuple);
|
||||||
|
goto finally;
|
||||||
|
}
|
||||||
|
|
||||||
|
PyTuple_SET_ITEM(tuple, 0, serrno);
|
||||||
|
PyTuple_SET_ITEM(tuple, 1, strerror);
|
||||||
|
PyTuple_SET_ITEM(tuple, 2, repr);
|
||||||
|
|
||||||
|
rtnval = PyString_Format(fmt, tuple);
|
||||||
|
|
||||||
|
Py_DECREF(fmt);
|
||||||
|
Py_DECREF(tuple);
|
||||||
|
/* already freed because tuple owned only reference */
|
||||||
|
serrno = NULL;
|
||||||
|
strerror = NULL;
|
||||||
|
}
|
||||||
|
else if (PyObject_IsTrue(serrno) && PyObject_IsTrue(strerror)) {
|
||||||
|
PyObject *fmt = PyString_FromString("[Error %s] %s");
|
||||||
|
PyObject *tuple = PyTuple_New(2);
|
||||||
|
|
||||||
|
if (!fmt || !tuple) {
|
||||||
|
Py_XDECREF(fmt);
|
||||||
|
Py_XDECREF(tuple);
|
||||||
|
goto finally;
|
||||||
|
}
|
||||||
|
|
||||||
|
PyTuple_SET_ITEM(tuple, 0, serrno);
|
||||||
|
PyTuple_SET_ITEM(tuple, 1, strerror);
|
||||||
|
|
||||||
|
rtnval = PyString_Format(fmt, tuple);
|
||||||
|
|
||||||
|
Py_DECREF(fmt);
|
||||||
|
Py_DECREF(tuple);
|
||||||
|
/* already freed because tuple owned only reference */
|
||||||
|
serrno = NULL;
|
||||||
|
strerror = NULL;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
rtnval = EnvironmentError__str__(originalself, args);
|
||||||
|
|
||||||
|
finally:
|
||||||
|
Py_XDECREF(filename);
|
||||||
|
Py_XDECREF(serrno);
|
||||||
|
Py_XDECREF(strerror);
|
||||||
|
return rtnval;
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
PyMethodDef WindowsError_methods[] = {
|
||||||
|
{"__init__", WindowsError__init__, METH_VARARGS},
|
||||||
|
{"__str__", WindowsError__str__, METH_VARARGS},
|
||||||
|
{NULL, NULL}
|
||||||
|
};
|
||||||
#endif /* MS_WINDOWS */
|
#endif /* MS_WINDOWS */
|
||||||
|
|
||||||
#ifdef __VMS
|
#ifdef __VMS
|
||||||
|
@ -1760,7 +1877,7 @@ static struct {
|
||||||
{"OSError", &PyExc_OSError, &PyExc_EnvironmentError, OSError__doc__},
|
{"OSError", &PyExc_OSError, &PyExc_EnvironmentError, OSError__doc__},
|
||||||
#ifdef MS_WINDOWS
|
#ifdef MS_WINDOWS
|
||||||
{"WindowsError", &PyExc_WindowsError, &PyExc_OSError,
|
{"WindowsError", &PyExc_WindowsError, &PyExc_OSError,
|
||||||
WindowsError__doc__},
|
WindowsError__doc__, WindowsError_methods},
|
||||||
#endif /* MS_WINDOWS */
|
#endif /* MS_WINDOWS */
|
||||||
#ifdef __VMS
|
#ifdef __VMS
|
||||||
{"VMSError", &PyExc_VMSError, &PyExc_OSError,
|
{"VMSError", &PyExc_VMSError, &PyExc_OSError,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue