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.
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(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 @@
 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 @@
 /* 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 @@
 			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 @@
 		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 @@
 		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 @@
 
 /* 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 @@
 
 		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 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