Issue #5463: Remove _PY_STRUCT_RANGE_CHECKING constant from struct
module, and remove associated code from test_struct. This was a
mechanism for skipping some of the tests for overflow behaviour when
packing integers; it's no longer necessary.
diff --git a/Doc/library/struct.rst b/Doc/library/struct.rst
index bd8a7a9..28b0104 100644
--- a/Doc/library/struct.rst
+++ b/Doc/library/struct.rst
@@ -134,6 +134,16 @@
specified number of bytes. As a special case, ``'0s'`` means a single, empty
string (while ``'0c'`` means 0 characters).
+When packing a value ``x`` using one of the integer formats (``'b'``,
+``'B'``, ``'h'``, ``'H'``, ``'i'``, ``'I'``, ``'l'``, ``'L'``,
+``'q'``, ``'Q'``), if ``x`` is outside the valid range for that format
+then :exc:`struct.error` is raised.
+
+.. versionchanged:: 3.1
+ In 3.0, some of the integer formats wrapped out-of-range values and
+ raised :exc:`DeprecationWarning` instead of :exc:`struct.error`.
+
+
The ``'p'`` format character encodes a "Pascal string", meaning a short
variable-length string stored in a fixed number of bytes. The count is the total
number of bytes stored. The first byte stored is the length of the string, or
diff --git a/Lib/test/test_struct.py b/Lib/test/test_struct.py
index 1d10b8f..beeee8f 100644
--- a/Lib/test/test_struct.py
+++ b/Lib/test/test_struct.py
@@ -14,10 +14,8 @@
try:
import _struct
except ImportError:
- PY_STRUCT_RANGE_CHECKING = 0
PY_STRUCT_FLOAT_COERCE = 2
else:
- PY_STRUCT_RANGE_CHECKING = getattr(_struct, '_PY_STRUCT_RANGE_CHECKING', 0)
PY_STRUCT_FLOAT_COERCE = getattr(_struct, '_PY_STRUCT_FLOAT_COERCE', 0)
def string_reverse(s):
@@ -40,20 +38,6 @@
return func(*args, **kw)
return decorator
-@with_warning_restore
-def deprecated_err(func, *args):
- try:
- func(*args)
- except (struct.error, OverflowError):
- pass
- except DeprecationWarning:
- raise TestFailed("%s%s expected to raise DeprecationWarning" % (
- func.__name__, args))
- else:
- raise TestFailed("%s%s did not raise error" % (
- func.__name__, args))
-
-
class StructTest(unittest.TestCase):
@with_warning_restore
@@ -222,12 +206,6 @@
class IntTester(unittest.TestCase):
- # XXX Most std integer modes fail to test for out-of-range.
- # The "i" and "l" codes appear to range-check OK on 32-bit boxes, but
- # fail to check correctly on some 64-bit ones (Tru64 Unix + Compaq C
- # reported by Mark Favas).
- BUGGY_RANGE_CHECK = "bBhHiIlL"
-
def __init__(self, formatpair, bytesize):
self.assertEqual(len(formatpair), 2)
self.formatpair = formatpair
@@ -291,12 +269,10 @@
else:
# x is out of range -- verify pack realizes that.
- if not PY_STRUCT_RANGE_CHECKING and code in self.BUGGY_RANGE_CHECK:
- if verbose:
- print("Skipping buggy range check for code", code)
- else:
- deprecated_err(pack, ">" + code, x)
- deprecated_err(pack, "<" + code, x)
+ self.assertRaises((struct.error, OverflowError),
+ pack, ">" + code, x)
+ self.assertRaises((struct.error, OverflowError),
+ pack, "<" + code, x)
# Much the same for unsigned.
code = self.unsigned_code
@@ -340,12 +316,10 @@
else:
# x is out of range -- verify pack realizes that.
- if not PY_STRUCT_RANGE_CHECKING and code in self.BUGGY_RANGE_CHECK:
- if verbose:
- print("Skipping buggy range check for code", code)
- else:
- deprecated_err(pack, ">" + code, x)
- deprecated_err(pack, "<" + code, x)
+ self.assertRaises((struct.error, OverflowError),
+ pack, ">" + code, x)
+ self.assertRaises((struct.error, OverflowError),
+ pack, "<" + code, x)
def run(self):
from random import randrange
@@ -443,20 +417,24 @@
big = math.ldexp(big, 127 - 24)
self.assertRaises(OverflowError, struct.pack, ">f", big)
- if PY_STRUCT_RANGE_CHECKING:
- def test_1229380(self):
- # SF bug 1229380. No struct.pack exception for some out of
- # range integers
- import sys
- for endian in ('', '>', '<'):
- for fmt in ('B', 'H', 'I', 'L'):
- deprecated_err(struct.pack, endian + fmt, -1)
+ def test_1229380(self):
+ # SF bug 1229380. No struct.pack exception for some out of
+ # range integers
+ import sys
+ for endian in ('', '>', '<'):
+ for fmt in ('B', 'H', 'I', 'L'):
+ self.assertRaises((struct.error, OverflowError), struct.pack,
+ endian + fmt, -1)
- deprecated_err(struct.pack, endian + 'B', 300)
- deprecated_err(struct.pack, endian + 'H', 70000)
+ self.assertRaises((struct.error, OverflowError), struct.pack,
+ endian + 'B', 300)
+ self.assertRaises((struct.error, OverflowError), struct.pack,
+ endian + 'H', 70000)
- deprecated_err(struct.pack, endian + 'I', sys.maxsize * 4)
- deprecated_err(struct.pack, endian + 'L', sys.maxsize * 4)
+ self.assertRaises((struct.error, OverflowError), struct.pack,
+ endian + 'I', sys.maxsize * 4)
+ self.assertRaises((struct.error, OverflowError), struct.pack,
+ endian + 'L', sys.maxsize * 4)
def XXXtest_1530559(self):
# XXX This is broken: see the bug report
diff --git a/Misc/NEWS b/Misc/NEWS
index 9422ef1..96d5eae 100644
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -73,7 +73,9 @@
- Issue #5463: In struct module, remove deprecated overflow wrapping
when packing an integer: struct.pack('=L', -1) now raises
- struct.error instead of returning b'\xff\xff\xff\xff'.
+ struct.error instead of returning b'\xff\xff\xff\xff'. The
+ _PY_STRUCT_RANGE_CHECKING and _PY_STRUCT_OVERFLOW_MASKING constants
+ have been removed from the struct module.
What's New in Python 3.1 alpha 1
diff --git a/Modules/_struct.c b/Modules/_struct.c
index 3cc9fa0..066759a 100644
--- a/Modules/_struct.c
+++ b/Modules/_struct.c
@@ -2028,7 +2028,6 @@
PyModule_AddObject(m, "__version__", ver);
- PyModule_AddIntConstant(m, "_PY_STRUCT_RANGE_CHECKING", 1);
#ifdef PY_STRUCT_FLOAT_COERCE
PyModule_AddIntConstant(m, "_PY_STRUCT_FLOAT_COERCE", 1);
#endif