[Patches] Windows specific exception.
Mark Hammond
mhammond@skippinet.com.au
Thu, 17 Feb 2000 19:03:26 +1100
This is a multi-part message in MIME format.
------=_NextPart_000_006A_01BF7979.ABA479F0
Content-Type: text/plain;
charset="iso-8859-1"
Content-Transfer-Encoding: 7bit
This is a set of patches as discussed on python-dev to add a new standard
Windows error to the code. Most of the changes should be obvious, but the
following are worth noting:
* No support for string exceptions (as OK'd by Guido)
* Changes to a recent patch by Chris Tismer to errors.c. Chris' patch
always used FormatMessage() to get the error message passing the error code
from errno - but errno and FormatMessage use a different numbering scheme.
The main reason the patch looked OK was that ENOFILE==ERROR_FILE_NOT_FOUND -
but that is about the only shared error code :-). The MS CRT docs tell you
to use _sys_errlist()/_sys_nerr. My patch does also this, and adds a very
similar function specifically for win32 error codes.
For example, under Windows the existing CVS version of Python yields:
>>> os.unlink(sys.executable)
...
OSError: [Errno 13] The data is invalid: 'L:\\src\\...'
Wheras the new code correctly reports:
OSError: [Errno 13] Permission denied: '...'
When I hear back about this I will submit the win32reg module (which depends
on these patches)
Thanks,
Mark.
Release info:
I confirm that, to the best of my knowledge and belief, this contribution is
free of any claims of third parties under copyright, patent or other rights
or interests ("claims"). To the extent that I have any such claims, I
hereby grant to CNRI a nonexclusive, irrevocable, royalty-free, worldwide
license to reproduce, distribute, perform and/or display publicly, prepare
derivative versions, and otherwise use this contribution as part of the
Python software and its related documentation, or any derivative versions
thereof, at no cost to CNRI or its licensed users, and to authorize others
to do so.
I acknowledge that CNRI may, at its sole discretion, decide whether or not
to incorporate this contribution in the Python software and its related
documentation. I further grant CNRI permission to use my name and other
identifying information provided to CNRI by me for use in connection with
the Python software and its related documentation.
------=_NextPart_000_006A_01BF7979.ABA479F0
Content-Type: text/plain;
name="diff.txt"
Content-Transfer-Encoding: quoted-printable
Content-Disposition: attachment;
filename="diff.txt"
Index: errors.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
RCS file: /projects/cvsroot/python/dist/src/Python/errors.c,v
retrieving revision 2.41
diff -c -r2.41 errors.c
*** errors.c 1999/04/21 15:27:31 2.41
--- errors.c 2000/02/17 07:59:05
***************
*** 289,294 ****
--- 289,297 ----
PyObject *v;
char *s;
int i =3D errno;
+ #ifdef MS_WIN32
+ char *s_buf =3D NULL;
+ #endif
#ifdef EINTR
if (i =3D=3D EINTR && PyErr_CheckSignals())
return NULL;
***************
*** 300,319 ****
s =3D strerror(i);
#else
{
! int len =3D FormatMessage(
! FORMAT_MESSAGE_ALLOCATE_BUFFER |
! FORMAT_MESSAGE_FROM_SYSTEM |
! FORMAT_MESSAGE_IGNORE_INSERTS,
! NULL, /* no message source */
! i,
! MAKELANGID(LANG_NEUTRAL,
! SUBLANG_DEFAULT), /* Default language */
! (LPTSTR) &s,
! 0, /* size not used */
! NULL); /* no args */
! /* remove trailing cr/lf and dots */
! while (len > 0 && s[len-1] <=3D '.')
! s[--len] =3D '\0';
}
#endif
if (filename !=3D NULL && Py_UseClassExceptionsFlag)
--- 303,333 ----
s =3D strerror(i);
#else
{
! /* Note that the Win32 errors do not lineup with the
! errno error. So if the error is in the MSVC error
! table, we use it, otherwise we assume it really _is_=20
! a Win32 error code
! */
! if (i < _sys_nerr) {
! s =3D _sys_errlist[i];
! }
! else {
! int len =3D FormatMessage(
! FORMAT_MESSAGE_ALLOCATE_BUFFER |
! FORMAT_MESSAGE_FROM_SYSTEM |
! FORMAT_MESSAGE_IGNORE_INSERTS,
! NULL, /* no message source */
! i,
! MAKELANGID(LANG_NEUTRAL,
! SUBLANG_DEFAULT), /* Default language */
! (LPTSTR) &s_buf,
! 0, /* size not used */
! NULL); /* no args */
! s =3D s_buf;
! /* remove trailing cr/lf and dots */
! while (len > 0 && s[len-1] < '.')
! s[--len] =3D '\0';
! }
}
#endif
if (filename !=3D NULL && Py_UseClassExceptionsFlag)
***************
*** 325,331 ****
Py_DECREF(v);
}
#ifdef MS_WIN32
! LocalFree(s);
#endif
return NULL;
}
--- 339,345 ----
Py_DECREF(v);
}
#ifdef MS_WIN32
! LocalFree(s_buf);
#endif
return NULL;
}
***************
*** 337,342 ****
--- 351,401 ----
{
return PyErr_SetFromErrnoWithFilename(exc, NULL);
}
+=20
+ #ifdef MS_WINDOWS=20
+ /* Windows specific error code handling */
+ PyObject *PyErr_SetFromWindowsErrWithFilename(
+ int ierr,=20
+ const char *filename)
+ {
+ int len;
+ char *s;
+ PyObject *v;
+ DWORD err =3D (DWORD)ierr;
+ if (err=3D=3D0) err =3D GetLastError();
+ len =3D FormatMessage(
+ /* Error API error */
+ FORMAT_MESSAGE_ALLOCATE_BUFFER |
+ FORMAT_MESSAGE_FROM_SYSTEM |
+ FORMAT_MESSAGE_IGNORE_INSERTS,
+ NULL, /* no message source */
+ err,
+ MAKELANGID(LANG_NEUTRAL,
+ SUBLANG_DEFAULT), /* Default language */
+ (LPTSTR) &s,
+ 0, /* size not used */
+ NULL); /* no args */
+ /* remove trailing cr/lf */
+ while (len > 0 && s[len-1] < '.')
+ s[--len] =3D '\0';
+ if (filename !=3D NULL && Py_UseClassExceptionsFlag)
+ v =3D Py_BuildValue("(iss)", err, s, filename);
+ else
+ v =3D Py_BuildValue("(is)", err, s);
+ if (v !=3D NULL) {
+ PyErr_SetObject(PyExc_EnvironmentError, v);
+ Py_DECREF(v);
+ }
+ LocalFree(s);
+ return NULL;
+ }
+=20
+ PyObject *PyErr_SetFromWindowsErr(int ierr)
+ {
+ return PyErr_SetFromWindowsErrWithFilename(ierr, NULL);
+=20
+ }
+ #endif /* MS_WINDOWS */
=20
void
PyErr_BadInternalCall()
Index: bltinmodule.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
RCS file: /projects/cvsroot/python/dist/src/Python/bltinmodule.c,v
retrieving revision 2.147
diff -c -r2.147 bltinmodule.c
*** bltinmodule.c 1999/12/23 14:16:55 2.147
--- bltinmodule.c 2000/02/17 07:59:15
***************
*** 2262,2267 ****
--- 2262,2270 ----
PyObject *PyExc_TypeError;
PyObject *PyExc_ValueError;
PyObject *PyExc_ZeroDivisionError;
+ #ifdef MS_WINDOWS
+ PyObject *PyExc_WindowsError;
+ #endif
=20
PyObject *PyExc_MemoryErrorInst;
=20
***************
*** 2303,2308 ****
--- 2306,2314 ----
{"UnboundLocalError", &PyExc_UnboundLocalError, 1},
{"TypeError", &PyExc_TypeError, 1},
{"ValueError", &PyExc_ValueError, 1},
+ #ifdef MS_WINDOWS
+ {"WindowsError", &PyExc_WindowsError, 1},
+ #endif
{"ZeroDivisionError", &PyExc_ZeroDivisionError, 1},
{NULL, NULL}
};
Index: pyerrors.h
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
RCS file: /projects/cvsroot/python/dist/src/Include/pyerrors.h,v
retrieving revision 2.33
diff -c -r2.33 pyerrors.h
*** pyerrors.h 1999/06/22 14:46:42 2.33
--- pyerrors.h 2000/02/17 07:59:23
***************
*** 81,89 ****
extern DL_IMPORT(PyObject *) PyExc_UnboundLocalError;
extern DL_IMPORT(PyObject *) PyExc_ValueError;
extern DL_IMPORT(PyObject *) PyExc_ZeroDivisionError;
=20
- extern DL_IMPORT(PyObject *) PyExc_MemoryErrorInst;
=20
=20
/* Convenience functions */
=20
--- 81,92 ----
extern DL_IMPORT(PyObject *) PyExc_UnboundLocalError;
extern DL_IMPORT(PyObject *) PyExc_ValueError;
extern DL_IMPORT(PyObject *) PyExc_ZeroDivisionError;
+ #ifdef MS_WINDOWS
+ extern DL_IMPORT(PyObject *) PyExc_WindowsError;
+ #endif
=20
=20
+ extern DL_IMPORT(PyObject *) PyExc_MemoryErrorInst;
=20
/* Convenience functions */
=20
***************
*** 92,97 ****
--- 95,104 ----
extern DL_IMPORT(PyObject *) PyErr_SetFromErrno Py_PROTO((PyObject =
*));
extern DL_IMPORT(PyObject *) PyErr_SetFromErrnoWithFilename =
Py_PROTO((PyObject *, char *));
extern DL_IMPORT(PyObject *) PyErr_Format Py_PROTO((PyObject *, const =
char *, ...));
+ #ifdef MS_WINDOWS
+ extern DL_IMPORT(PyObject *) PyErr_SetFromWindowsErrWithFilename(int, =
const char *);
+ extern DL_IMPORT(PyObject *) PyErr_SetFromWindowsErr(int);
+ #endif
=20
extern DL_IMPORT(void) PyErr_BadInternalCall Py_PROTO((void));
=20
Index: exceptions.py
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
RCS file: /projects/cvsroot/python/dist/src/Lib/exceptions.py,v
retrieving revision 1.16
diff -c -r1.16 exceptions.py
*** exceptions.py 1999/08/19 21:17:08 1.16
--- exceptions.py 2000/02/17 07:59:31
***************
*** 139,144 ****
--- 139,148 ----
"""OS system call failed."""
pass
=20
+ class WindowsError(OSError):
+ """MS-Windows OS system call failed."""
+ pass
+=20
class RuntimeError(StandardError):
"""Unspecified run-time error."""
pass
------=_NextPart_000_006A_01BF7979.ABA479F0--