Index: Lib/test/test_struct.py =================================================================== --- Lib/test/test_struct.py (revision 71749) +++ Lib/test/test_struct.py (working copy) @@ -11,12 +11,7 @@ IS32BIT = sys.maxsize == 0x7fffffff del sys -try: - import _struct -except ImportError: - PY_STRUCT_FLOAT_COERCE = 2 -else: - PY_STRUCT_FLOAT_COERCE = getattr(_struct, '_PY_STRUCT_FLOAT_COERCE', 0) +import _struct def string_reverse(s): return s[::-1] @@ -40,27 +35,6 @@ class StructTest(unittest.TestCase): - @with_warning_restore - def check_float_coerce(self, format, number): - # SF bug 1530559. struct.pack raises TypeError where it used to convert. - if PY_STRUCT_FLOAT_COERCE == 2: - # Test for pre-2.5 struct module - packed = struct.pack(format, number) - floored = struct.unpack(format, packed)[0] - self.assertEqual(floored, int(number), - "did not correcly coerce float to int") - return - try: - struct.pack(format, number) - except (struct.error, TypeError): - if PY_STRUCT_FLOAT_COERCE: - self.fail("expected DeprecationWarning for float coerce") - except DeprecationWarning: - if not PY_STRUCT_FLOAT_COERCE: - self.fail("expected to raise struct.error for float coerce") - else: - self.fail("did not raise error for float coerce") - def test_isbigendian(self): self.assertEqual((struct.pack('=i', 1)[0] == 0), ISBIGENDIAN) @@ -437,14 +411,6 @@ self.assertRaises((struct.error, OverflowError), struct.pack, endian + 'L', sys.maxsize * 4) - def XXXtest_1530559(self): - # XXX This is broken: see the bug report - # SF bug 1530559. struct.pack raises TypeError where it used to convert. - for endian in ('', '>', '<'): - for fmt in ('B', 'H', 'I', 'L', 'b', 'h', 'i', 'l'): - self.check_float_coerce(endian + fmt, 1.0) - self.check_float_coerce(endian + fmt, 1.5) - def test_unpack_from(self): test_string = b'abcd01234' fmt = '4s' Index: Modules/_struct.c =================================================================== --- Modules/_struct.c (revision 71749) +++ Modules/_struct.c (working copy) @@ -12,17 +12,6 @@ static PyTypeObject PyStructType; -/* If PY_STRUCT_FLOAT_COERCE is defined, the struct module will allow float - arguments for integer formats with a warning for backwards - compatibility. */ - -#define PY_STRUCT_FLOAT_COERCE 1 - -#ifdef PY_STRUCT_FLOAT_COERCE -#define FLOAT_COERCE "integer argument expected, got float" -#endif - - /* The translation function for each format character is table driven */ typedef struct _formatdef { char format; @@ -100,58 +89,41 @@ #pragma options align=reset #endif -/* Helper to get a PyLongObject by hook or by crook. Caller should decref. */ +/* Helper to get a PyLongObject. Caller should decref. */ static PyObject * get_pylong(PyObject *v) { - PyNumberMethods *m; - assert(v != NULL); - if (PyLong_Check(v)) { - Py_INCREF(v); - return v; + if (!PyLong_Check(v)) { + PyErr_SetString(StructError, + "required argument is not an integer"); + return NULL; } - m = Py_TYPE(v)->tp_as_number; - if (m != NULL && m->nb_int != NULL) { - v = m->nb_int(v); - if (v == NULL) - return NULL; - if (PyLong_Check(v)) - return v; - Py_DECREF(v); - } - PyErr_SetString(StructError, - "cannot convert argument to long"); - return NULL; + + Py_INCREF(v); + return v; } -/* Helper routine to get a Python integer and raise the appropriate error - if it isn't one */ +/* Helper routine to get a C long and raise the appropriate error if it isn't + one */ static int get_long(PyObject *v, long *p) { - long x = PyLong_AsLong(v); + long x; + + if (!PyLong_Check(v)) { + PyErr_SetString(StructError, + "required argument is not an integer"); + return -1; + } + x = PyLong_AsLong(v); if (x == -1 && PyErr_Occurred()) { -#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_long(o, p); - Py_DECREF(o); - return res; - } -#endif - if (PyErr_ExceptionMatches(PyExc_TypeError)) + if (PyErr_ExceptionMatches(PyExc_OverflowError)) PyErr_SetString(StructError, - "required argument is not an integer"); + "argument cannot be represented as " + "a C long"); return -1; } *p = x; @@ -164,20 +136,22 @@ static int get_ulong(PyObject *v, unsigned long *p) { - if (PyLong_Check(v)) { - unsigned long x = PyLong_AsUnsignedLong(v); - if (x == (unsigned long)(-1) && PyErr_Occurred()) - return -1; - *p = x; - return 0; - } - if (get_long(v, (long *)p) < 0) - return -1; - if (((long)*p) < 0) { + unsigned long x; + + if (!PyLong_Check(v)) { PyErr_SetString(StructError, - "unsigned argument is < 0"); + "required argument is not an integer"); return -1; } + x = PyLong_AsUnsignedLong(v); + if (x == (unsigned long)-1 && PyErr_Occurred()) { + if (PyErr_ExceptionMatches(PyExc_OverflowError)) + PyErr_SetString(StructError, + "argument cannot be represented as " + "a C unsigned long"); + return -1; + } + *p = x; return 0; } @@ -189,15 +163,19 @@ get_longlong(PyObject *v, PY_LONG_LONG *p) { PY_LONG_LONG x; - - v = get_pylong(v); - if (v == NULL) + if (!PyLong_Check(v)) { + PyErr_SetString(StructError, + "required argument is not an integer"); return -1; - assert(PyLong_Check(v)); + } x = PyLong_AsLongLong(v); - Py_DECREF(v); - if (x == (PY_LONG_LONG)-1 && PyErr_Occurred()) + if (x == -1 && PyErr_Occurred()) { + if (PyErr_ExceptionMatches(PyExc_OverflowError)) + PyErr_SetString(StructError, + "argument cannot be represented as " + "a C long long"); return -1; + } *p = x; return 0; } @@ -208,15 +186,19 @@ get_ulonglong(PyObject *v, unsigned PY_LONG_LONG *p) { unsigned PY_LONG_LONG x; - - v = get_pylong(v); - if (v == NULL) + if (!PyLong_Check(v)) { + PyErr_SetString(StructError, + "required argument is not an integer"); return -1; - assert(PyLong_Check(v)); + } x = PyLong_AsUnsignedLongLong(v); - Py_DECREF(v); - if (x == (unsigned PY_LONG_LONG)-1 && PyErr_Occurred()) + if (x == -1 && PyErr_Occurred()) { + if (PyErr_ExceptionMatches(PyExc_OverflowError)) + PyErr_SetString(StructError, + "argument cannot be represented as " + "a C unsigned long long"); return -1; + } *p = x; return 0; } @@ -1962,7 +1944,7 @@ { PyObject *ver, *m; - ver = PyBytes_FromString("0.2"); + ver = PyBytes_FromString("0.3"); if (ver == NULL) return NULL; @@ -2028,9 +2010,5 @@ PyModule_AddObject(m, "__version__", ver); -#ifdef PY_STRUCT_FLOAT_COERCE - PyModule_AddIntConstant(m, "_PY_STRUCT_FLOAT_COERCE", 1); -#endif return m; - }