Index: Modules/_struct.c =================================================================== --- Modules/_struct.c (revision 70307) +++ Modules/_struct.c (working copy) @@ -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 Index: Lib/test/test_struct.py =================================================================== --- Lib/test/test_struct.py (revision 70307) +++ Lib/test/test_struct.py (working copy) @@ -471,11 +471,6 @@ self.check_float_coerce(endian + fmt, 1.0) self.check_float_coerce(endian + fmt, 1.5) - def test_issue4228(self): - # Packing a long may yield either 32 or 64 bits - x = struct.pack('L', -1)[:4] - self.assertEqual(x, b'\xff'*4) - def test_unpack_from(self): test_string = b'abcd01234' fmt = '4s'