- Issue #5463: In struct module, remove deprecated overflow wrapping
  when packing an integer: for example, struct.pack('=L', -1) now
  raises struct.error instead of returning b'\xff\xff\xff\xff'.

  Thanks Andreas Schawo for the patch.
diff --git a/Modules/_struct.c b/Modules/_struct.c
index 57441c4..3cc9fa0 100644
--- a/Modules/_struct.c
+++ b/Modules/_struct.c
@@ -12,20 +12,6 @@
 
 static PyTypeObject PyStructType;
 
-/* If PY_STRUCT_OVERFLOW_MASKING is defined, the struct module will wrap all input
-   numbers for explicit endians such that they fit in the given type, much
-   like explicit casting in C. A warning will be raised if the number did
-   not originally fit within the range of the requested type. If it is
-   not defined, then all range errors and overflow will be struct.error
-   exceptions. */
-
-#define PY_STRUCT_OVERFLOW_MASKING 1
-
-#ifdef PY_STRUCT_OVERFLOW_MASKING
-static PyObject *pylong_ulong_mask = NULL;
-static PyObject *pyint_zero = NULL;
-#endif
-
 /* If PY_STRUCT_FLOAT_COERCE is defined, the struct module will allow float
    arguments for integer formats with a warning for backwards
    compatibility. */
@@ -237,107 +223,9 @@
 
 #endif
 
-#ifdef PY_STRUCT_OVERFLOW_MASKING
 
-/* 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)
-{
-	if (get_long(v, p) < 0) {
-		if (PyLong_Check(v) &&
-		    PyErr_ExceptionMatches(PyExc_OverflowError)) {
-			PyObject *wrapped;
-			long x;
-			PyErr_Clear();
-#ifdef PY_STRUCT_FLOAT_COERCE
-			if (PyFloat_Check(v)) {
-				PyObject *o;
-				int res;
-				PyErr_Clear();
-				if (PyErr_WarnEx(PyExc_DeprecationWarning, FLOAT_COERCE, 2) < 0)
-					return -1;
-				o = PyNumber_Long(v);
-				if (o == NULL)
-					return -1;
-				res = get_wrapped_long(o, p);
-				Py_DECREF(o);
-				return res;
-			}
-#endif
-			if (PyErr_WarnEx(PyExc_DeprecationWarning, INT_OVERFLOW, 2) < 0)
-				return -1;
-			wrapped = PyNumber_And(v, pylong_ulong_mask);
-			if (wrapped == NULL)
-				return -1;
-			x = (long)PyLong_AsUnsignedLong(wrapped);
-			Py_DECREF(wrapped);
-			if (x == -1 && PyErr_Occurred())
-				return -1;
-			*p = x;
-		} else {
-			return -1;
-		}
-	}
-	return 0;
-}
-
-static int
-get_wrapped_ulong(PyObject *v, unsigned long *p)
-{
-	long x = (long)PyLong_AsUnsignedLong(v);
-	if (x == -1 && PyErr_Occurred()) {
-		PyObject *wrapped;
-		PyErr_Clear();
-#ifdef PY_STRUCT_FLOAT_COERCE
-		if (PyFloat_Check(v)) {
-			PyObject *o;
-			int res;
-			PyErr_Clear();
-			if (PyErr_WarnEx(PyExc_DeprecationWarning, FLOAT_COERCE, 2) < 0)
-				return -1;
-			o = PyNumber_Long(v);
-			if (o == NULL)
-				return -1;
-			res = get_wrapped_ulong(o, p);
-			Py_DECREF(o);
-			return res;
-		}
-#endif
-		wrapped = PyNumber_And(v, pylong_ulong_mask);
-		if (wrapped == NULL)
-			return -1;
-		if (PyErr_WarnEx(PyExc_DeprecationWarning, INT_OVERFLOW, 2) < 0) {
-			Py_DECREF(wrapped);
-			return -1;
-		}
-		x = (long)PyLong_AsUnsignedLong(wrapped);
-		Py_DECREF(wrapped);
-		if (x == -1 && PyErr_Occurred())
-			return -1;
-	}
-	*p = (unsigned long)x;
-	return 0;
-}
-
-#define RANGE_ERROR(x, f, flag, mask) \
-	do { \
-		if (_range_error(f, flag) < 0) \
-			return -1; \
-		else \
-			(x) &= (mask); \
-	} while (0)
-
-#else
-
-#define get_wrapped_long get_long
-#define get_wrapped_ulong get_ulong
 #define RANGE_ERROR(x, f, flag, mask) return _range_error(f, flag)
 
-#endif
 
 /* Floating point helpers */
 
@@ -392,26 +280,7 @@
 			~ largest,
 			largest);
 	}
-#ifdef PY_STRUCT_OVERFLOW_MASKING
-	{
-		PyObject *ptype, *pvalue, *ptraceback;
-		PyObject *msg;
-		int rval;
-		PyErr_Fetch(&ptype, &pvalue, &ptraceback);
-		assert(pvalue != NULL);
-		msg = PyObject_Str(pvalue);
-		Py_XDECREF(ptype);
-		Py_XDECREF(pvalue);
-		Py_XDECREF(ptraceback);
-		if (msg == NULL)
-			return -1;
-		rval = PyErr_WarnEx(PyExc_DeprecationWarning,
-				    _PyUnicode_AsString(msg), 2);
-		Py_DECREF(msg);
-		if (rval == 0)
-			return 0;
-	}
-#endif
+
 	return -1;
 }
 
@@ -673,7 +542,7 @@
 {
 	unsigned long x;
 	unsigned int y;
-	if (get_wrapped_ulong(v, &x) < 0)
+	if (get_ulong(v, &x) < 0)
 		return -1;
 	y = (unsigned int)x;
 #if (SIZEOF_LONG > SIZEOF_INT)
@@ -698,7 +567,7 @@
 np_ulong(char *p, PyObject *v, const formatdef *f)
 {
 	unsigned long x;
-	if (get_wrapped_ulong(v, &x) < 0)
+	if (get_ulong(v, &x) < 0)
 		return -1;
 	memcpy(p, (char *)&x, sizeof x);
 	return 0;
@@ -905,7 +774,7 @@
 {
 	long x;
 	Py_ssize_t i;
-	if (get_wrapped_long(v, &x) < 0)
+	if (get_long(v, &x) < 0)
 		return -1;
 	i = f->size;
 	if (i != SIZEOF_LONG) {
@@ -915,10 +784,6 @@
 		else if ((i == 4) && (x < -2147483648L || x > 2147483647L))
 			RANGE_ERROR(x, f, 0, 0xffffffffL);
 #endif
-#ifdef PY_STRUCT_OVERFLOW_MASKING
-		else if ((i == 1) && (x < -128 || x > 127))
-			RANGE_ERROR(x, f, 0, 0xffL);
-#endif
 	}
 	do {
 		p[--i] = (char)x;
@@ -932,7 +797,7 @@
 {
 	unsigned long x;
 	Py_ssize_t i;
-	if (get_wrapped_ulong(v, &x) < 0)
+	if (get_ulong(v, &x) < 0)
 		return -1;
 	i = f->size;
 	if (i != SIZEOF_LONG) {
@@ -1015,14 +880,8 @@
 
 static formatdef bigendian_table[] = {
 	{'x',	1,		0,		NULL},
-#ifdef PY_STRUCT_OVERFLOW_MASKING
-	/* Native packers do range checking without overflow masking. */
-	{'b',	1,		0,		nu_byte,	bp_int},
-	{'B',	1,		0,		nu_ubyte,	bp_uint},
-#else
 	{'b',	1,		0,		nu_byte,	np_byte},
 	{'B',	1,		0,		nu_ubyte,	np_ubyte},
-#endif
 	{'c',	1,		0,		nu_char,	np_char},
 	{'s',	1,		0,		NULL},
 	{'p',	1,		0,		NULL},
@@ -1133,7 +992,7 @@
 {
 	long x;
 	Py_ssize_t i;
-	if (get_wrapped_long(v, &x) < 0)
+	if (get_long(v, &x) < 0)
 		return -1;
 	i = f->size;
 	if (i != SIZEOF_LONG) {
@@ -1143,10 +1002,6 @@
 		else if ((i == 4) && (x < -2147483648L || x > 2147483647L))
 			RANGE_ERROR(x, f, 0, 0xffffffffL);
 #endif
-#ifdef PY_STRUCT_OVERFLOW_MASKING
-		else if ((i == 1) && (x < -128 || x > 127))
-			RANGE_ERROR(x, f, 0, 0xffL);
-#endif
 	}
 	do {
 		*p++ = (char)x;
@@ -1160,7 +1015,7 @@
 {
 	unsigned long x;
 	Py_ssize_t i;
-	if (get_wrapped_ulong(v, &x) < 0)
+	if (get_ulong(v, &x) < 0)
 		return -1;
 	i = f->size;
 	if (i != SIZEOF_LONG) {
@@ -1234,14 +1089,8 @@
 
 static formatdef lilendian_table[] = {
 	{'x',	1,		0,		NULL},
-#ifdef PY_STRUCT_OVERFLOW_MASKING
-	/* Native packers do range checking without overflow masking. */
-	{'b',	1,		0,		nu_byte,	lp_int},
-	{'B',	1,		0,		nu_ubyte,	lp_uint},
-#else
 	{'b',	1,		0,		nu_byte,	np_byte},
 	{'B',	1,		0,		nu_ubyte,	np_ubyte},
-#endif
 	{'c',	1,		0,		nu_char,	np_char},
 	{'s',	1,		0,		NULL},
 	{'p',	1,		0,		NULL},
@@ -2125,26 +1974,6 @@
 	if (PyType_Ready(&PyStructType) < 0)
 		return NULL;
 
-#ifdef PY_STRUCT_OVERFLOW_MASKING
-	if (pyint_zero == NULL) {
-		pyint_zero = PyLong_FromLong(0);
-		if (pyint_zero == NULL)
-			return NULL;
-	}
-	if (pylong_ulong_mask == NULL) {
-#if (SIZEOF_LONG == 4)
-		pylong_ulong_mask = PyLong_FromString("FFFFFFFF", NULL, 16);
-#else
-		pylong_ulong_mask = PyLong_FromString("FFFFFFFFFFFFFFFF", NULL, 16);
-#endif
-		if (pylong_ulong_mask == NULL)
-			return NULL;
-	}
-
-#else
-	/* This speed trick can't be used until overflow masking goes away, because
-	   native endian always raises exceptions instead of overflow masking. */
-
 	/* Check endian and swap in faster functions */
 	{
 		int one = 1;
@@ -2183,7 +2012,6 @@
 			native++;
 		}
 	}
-#endif
 
 	/* Add some symbolic constants to the module */
 	if (StructError == NULL) {
@@ -2201,9 +2029,6 @@
 	PyModule_AddObject(m, "__version__", ver);
 
 	PyModule_AddIntConstant(m, "_PY_STRUCT_RANGE_CHECKING", 1);
-#ifdef PY_STRUCT_OVERFLOW_MASKING
-	PyModule_AddIntConstant(m, "_PY_STRUCT_OVERFLOW_MASKING", 1);
-#endif
 #ifdef PY_STRUCT_FLOAT_COERCE
 	PyModule_AddIntConstant(m, "_PY_STRUCT_FLOAT_COERCE", 1);
 #endif