[Python-checkins] r70497 - in python/branches/py3k: Lib/test/test_struct.py Misc/ACKS Misc/NEWS Modules/_struct.c

mark.dickinson python-checkins at python.org
Sat Mar 21 11:26:42 CET 2009


Author: mark.dickinson
Date: Sat Mar 21 11:26:31 2009
New Revision: 70497

Log:
- 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.


Modified:
   python/branches/py3k/Lib/test/test_struct.py
   python/branches/py3k/Misc/ACKS
   python/branches/py3k/Misc/NEWS
   python/branches/py3k/Modules/_struct.c

Modified: python/branches/py3k/Lib/test/test_struct.py
==============================================================================
--- python/branches/py3k/Lib/test/test_struct.py	(original)
+++ python/branches/py3k/Lib/test/test_struct.py	Sat Mar 21 11:26:31 2009
@@ -2,8 +2,6 @@
 import unittest
 import struct
 import warnings
-warnings.filterwarnings("ignore", "struct integer overflow masking is deprecated",
-                        DeprecationWarning)
 
 from functools import wraps
 from test.support import TestFailed, verbose, run_unittest
@@ -17,11 +15,9 @@
     import _struct
 except ImportError:
     PY_STRUCT_RANGE_CHECKING = 0
-    PY_STRUCT_OVERFLOW_MASKING = 1
     PY_STRUCT_FLOAT_COERCE = 2
 else:
     PY_STRUCT_RANGE_CHECKING = getattr(_struct, '_PY_STRUCT_RANGE_CHECKING', 0)
-    PY_STRUCT_OVERFLOW_MASKING = getattr(_struct, '_PY_STRUCT_OVERFLOW_MASKING', 0)
     PY_STRUCT_FLOAT_COERCE = getattr(_struct, '_PY_STRUCT_FLOAT_COERCE', 0)
 
 def string_reverse(s):
@@ -51,8 +47,7 @@
     except (struct.error, OverflowError):
         pass
     except DeprecationWarning:
-        if not PY_STRUCT_OVERFLOW_MASKING:
-            raise TestFailed("%s%s expected to raise DeprecationWarning" % (
+        raise TestFailed("%s%s expected to raise DeprecationWarning" % (
                 func.__name__, args))
     else:
         raise TestFailed("%s%s did not raise error" % (
@@ -471,11 +466,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'

Modified: python/branches/py3k/Misc/ACKS
==============================================================================
--- python/branches/py3k/Misc/ACKS	(original)
+++ python/branches/py3k/Misc/ACKS	Sat Mar 21 11:26:31 2009
@@ -620,6 +620,7 @@
 Ty Sarna
 Ben Sayer
 Michael Scharf
+Andreas Schawo
 Neil Schemenauer
 David Scherer
 Gregor Schmid

Modified: python/branches/py3k/Misc/NEWS
==============================================================================
--- python/branches/py3k/Misc/NEWS	(original)
+++ python/branches/py3k/Misc/NEWS	Sat Mar 21 11:26:31 2009
@@ -44,6 +44,13 @@
 - Issue #5016: FileIO.seekable() could return False if the file position
   was negative when truncated to a C int. Patch by Victor Stinner.
 
+Extension Modules
+-----------------
+
+- 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'.
+
 
 What's New in Python 3.1 alpha 1
 ================================

Modified: python/branches/py3k/Modules/_struct.c
==============================================================================
--- python/branches/py3k/Modules/_struct.c	(original)
+++ python/branches/py3k/Modules/_struct.c	Sat Mar 21 11:26:31 2009
@@ -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


More information about the Python-checkins mailing list