From 07aadb14f39c585a463f19ec0496860a100051ad Mon Sep 17 00:00:00 2001 From: Neal Norwitz Date: Sun, 30 Jul 2006 06:55:48 +0000 Subject: Add PyErr_WarnEx() so C code can pass the stacklevel to warnings.warn(). This provides the proper warning for struct.pack(). PyErr_Warn() is now deprecated in favor of PyErr_WarnEx(). As mentioned by Tim Peters on python-dev. --- Include/pyerrors.h | 6 +++++- Misc/NEWS | 4 ++++ Modules/_struct.c | 10 ++++++---- Python/errors.c | 15 +++++++++++++-- 4 files changed, 28 insertions(+), 7 deletions(-) diff --git a/Include/pyerrors.h b/Include/pyerrors.h index 6fa6ed7..ae1d990 100644 --- a/Include/pyerrors.h +++ b/Include/pyerrors.h @@ -225,10 +225,14 @@ PyAPI_FUNC(PyObject *) PyErr_NewException(char *name, PyObject *base, PyAPI_FUNC(void) PyErr_WriteUnraisable(PyObject *); /* Issue a warning or exception */ -PyAPI_FUNC(int) PyErr_Warn(PyObject *, char *); +PyAPI_FUNC(int) PyErr_WarnEx(PyObject *category, const char *msg, + Py_ssize_t stack_level); PyAPI_FUNC(int) PyErr_WarnExplicit(PyObject *, const char *, const char *, int, const char *, PyObject *); +/* PyErr_Warn is only for backwards compatability and will be removed. + Use PyErr_WarnEx instead. */ +#define PyErr_Warn(category, msg) PyErr_WarnEx(category, msg, 1) /* In sigcheck.c or signalmodule.c */ PyAPI_FUNC(int) PyErr_CheckSignals(void); diff --git a/Misc/NEWS b/Misc/NEWS index 141850d..dac1129 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -12,6 +12,10 @@ What's New in Python 2.5 beta 3? Core and builtins ----------------- +- Add PyErr_WarnEx() so C code can pass the stacklevel to warnings.warn(). + This provides the proper warning for struct.pack(). + PyErr_Warn() is now deprecated in favor of PyErr_WarnEx(). + - Patch #1531113: Fix augmented assignment with yield expressions. Also fix a SystemError when trying to assign to yield expressions. diff --git a/Modules/_struct.c b/Modules/_struct.c index 7e30892..3774dfd 100644 --- a/Modules/_struct.c +++ b/Modules/_struct.c @@ -214,6 +214,8 @@ get_ulonglong(PyObject *v, unsigned PY_LONG_LONG *p) /* Helper routine to get a Python integer and raise the appropriate error if it isn't one */ +#define INT_OVERFLOW "struct integer overflow masking is deprecated" + static int get_wrapped_long(PyObject *v, long *p) { @@ -223,7 +225,7 @@ get_wrapped_long(PyObject *v, long *p) PyObject *wrapped; long x; PyErr_Clear(); - if (PyErr_Warn(PyExc_DeprecationWarning, "struct integer overflow masking is deprecated") < 0) + if (PyErr_WarnEx(PyExc_DeprecationWarning, INT_OVERFLOW, 2) < 0) return -1; wrapped = PyNumber_And(v, pylong_ulong_mask); if (wrapped == NULL) @@ -250,7 +252,7 @@ get_wrapped_ulong(PyObject *v, unsigned long *p) wrapped = PyNumber_And(v, pylong_ulong_mask); if (wrapped == NULL) return -1; - if (PyErr_Warn(PyExc_DeprecationWarning, "struct integer overflow masking is deprecated") < 0) { + if (PyErr_WarnEx(PyExc_DeprecationWarning, INT_OVERFLOW, 2) < 0) { Py_DECREF(wrapped); return -1; } @@ -345,8 +347,8 @@ _range_error(const formatdef *f, int is_unsigned) Py_XDECREF(ptraceback); if (msg == NULL) return -1; - rval = PyErr_Warn(PyExc_DeprecationWarning, - PyString_AS_STRING(msg)); + rval = PyErr_WarnEx(PyExc_DeprecationWarning, + PyString_AS_STRING(msg), 2); Py_DECREF(msg); if (rval == 0) return 0; diff --git a/Python/errors.c b/Python/errors.c index 56463a3..43d89bd 100644 --- a/Python/errors.c +++ b/Python/errors.c @@ -632,7 +632,7 @@ extern PyObject *PyModule_GetWarningsModule(void); /* Function to issue a warning message; may raise an exception. */ int -PyErr_Warn(PyObject *category, char *message) +PyErr_WarnEx(PyObject *category, const char *message, Py_ssize_t stack_level) { PyObject *dict, *func = NULL; PyObject *warnings_module = PyModule_GetWarningsModule(); @@ -650,7 +650,8 @@ PyErr_Warn(PyObject *category, char *message) if (category == NULL) category = PyExc_RuntimeWarning; - res = PyObject_CallFunction(func, "sO", message, category); + res = PyObject_CallFunction(func, "sOn", + message, category, stack_level); if (res == NULL) return -1; Py_DECREF(res); @@ -658,6 +659,16 @@ PyErr_Warn(PyObject *category, char *message) } } +/* PyErr_Warn is only for backwards compatability and will be removed. + Use PyErr_WarnEx instead. */ + +#undef PyErr_Warn + +int +PyErr_Warn(PyObject *category, char *message) +{ + return PyErr_WarnEx(category, message, 1); +} /* Warning with explicit origin */ int -- cgit v0.12