Skip to content

Commit 07aadb1

Browse files
committed
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.
1 parent 0d62a06 commit 07aadb1

File tree

4 files changed

+28
-7
lines changed

4 files changed

+28
-7
lines changed

Include/pyerrors.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -225,10 +225,14 @@ PyAPI_FUNC(PyObject *) PyErr_NewException(char *name, PyObject *base,
225225
PyAPI_FUNC(void) PyErr_WriteUnraisable(PyObject *);
226226

227227
/* Issue a warning or exception */
228-
PyAPI_FUNC(int) PyErr_Warn(PyObject *, char *);
228+
PyAPI_FUNC(int) PyErr_WarnEx(PyObject *category, const char *msg,
229+
Py_ssize_t stack_level);
229230
PyAPI_FUNC(int) PyErr_WarnExplicit(PyObject *, const char *,
230231
const char *, int,
231232
const char *, PyObject *);
233+
/* PyErr_Warn is only for backwards compatability and will be removed.
234+
Use PyErr_WarnEx instead. */
235+
#define PyErr_Warn(category, msg) PyErr_WarnEx(category, msg, 1)
232236

233237
/* In sigcheck.c or signalmodule.c */
234238
PyAPI_FUNC(int) PyErr_CheckSignals(void);

Misc/NEWS

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,10 @@ What's New in Python 2.5 beta 3?
1212
Core and builtins
1313
-----------------
1414

15+
- Add PyErr_WarnEx() so C code can pass the stacklevel to warnings.warn().
16+
This provides the proper warning for struct.pack().
17+
PyErr_Warn() is now deprecated in favor of PyErr_WarnEx().
18+
1519
- Patch #1531113: Fix augmented assignment with yield expressions.
1620
Also fix a SystemError when trying to assign to yield expressions.
1721

Modules/_struct.c

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,8 @@ get_ulonglong(PyObject *v, unsigned PY_LONG_LONG *p)
214214
/* Helper routine to get a Python integer and raise the appropriate error
215215
if it isn't one */
216216

217+
#define INT_OVERFLOW "struct integer overflow masking is deprecated"
218+
217219
static int
218220
get_wrapped_long(PyObject *v, long *p)
219221
{
@@ -223,7 +225,7 @@ get_wrapped_long(PyObject *v, long *p)
223225
PyObject *wrapped;
224226
long x;
225227
PyErr_Clear();
226-
if (PyErr_Warn(PyExc_DeprecationWarning, "struct integer overflow masking is deprecated") < 0)
228+
if (PyErr_WarnEx(PyExc_DeprecationWarning, INT_OVERFLOW, 2) < 0)
227229
return -1;
228230
wrapped = PyNumber_And(v, pylong_ulong_mask);
229231
if (wrapped == NULL)
@@ -250,7 +252,7 @@ get_wrapped_ulong(PyObject *v, unsigned long *p)
250252
wrapped = PyNumber_And(v, pylong_ulong_mask);
251253
if (wrapped == NULL)
252254
return -1;
253-
if (PyErr_Warn(PyExc_DeprecationWarning, "struct integer overflow masking is deprecated") < 0) {
255+
if (PyErr_WarnEx(PyExc_DeprecationWarning, INT_OVERFLOW, 2) < 0) {
254256
Py_DECREF(wrapped);
255257
return -1;
256258
}
@@ -345,8 +347,8 @@ _range_error(const formatdef *f, int is_unsigned)
345347
Py_XDECREF(ptraceback);
346348
if (msg == NULL)
347349
return -1;
348-
rval = PyErr_Warn(PyExc_DeprecationWarning,
349-
PyString_AS_STRING(msg));
350+
rval = PyErr_WarnEx(PyExc_DeprecationWarning,
351+
PyString_AS_STRING(msg), 2);
350352
Py_DECREF(msg);
351353
if (rval == 0)
352354
return 0;

Python/errors.c

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -632,7 +632,7 @@ extern PyObject *PyModule_GetWarningsModule(void);
632632

633633
/* Function to issue a warning message; may raise an exception. */
634634
int
635-
PyErr_Warn(PyObject *category, char *message)
635+
PyErr_WarnEx(PyObject *category, const char *message, Py_ssize_t stack_level)
636636
{
637637
PyObject *dict, *func = NULL;
638638
PyObject *warnings_module = PyModule_GetWarningsModule();
@@ -650,14 +650,25 @@ PyErr_Warn(PyObject *category, char *message)
650650

651651
if (category == NULL)
652652
category = PyExc_RuntimeWarning;
653-
res = PyObject_CallFunction(func, "sO", message, category);
653+
res = PyObject_CallFunction(func, "sOn",
654+
message, category, stack_level);
654655
if (res == NULL)
655656
return -1;
656657
Py_DECREF(res);
657658
return 0;
658659
}
659660
}
660661

662+
/* PyErr_Warn is only for backwards compatability and will be removed.
663+
Use PyErr_WarnEx instead. */
664+
665+
#undef PyErr_Warn
666+
667+
int
668+
PyErr_Warn(PyObject *category, char *message)
669+
{
670+
return PyErr_WarnEx(category, message, 1);
671+
}
661672

662673
/* Warning with explicit origin */
663674
int

0 commit comments

Comments
 (0)