diff Modules/_struct.c @ 39380:9cb4565e60ca legacy-trunk

Fix #1530559, struct.pack raises TypeError where it used to convert. Passing float arguments to struct.pack when integers are expected now triggers a DeprecationWarning.
author Bob Ippolito <bob@redivi.com>
date Fri, 04 Aug 2006 23:59:21 +0000
parents 7dc5f3ede4cd
children a2f26f944b65 0bffca64ccc4
line wrap: on
line diff
--- a/Modules/_struct.c	Fri Aug 04 22:00:35 2006 +0000
+++ b/Modules/_struct.c	Fri Aug 04 23:59:21 2006 +0000
@@ -31,6 +31,17 @@
 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. */
+
+#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;
@@ -135,6 +146,21 @@
 {
 	long x = PyInt_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_Int(v);
+			if (o == NULL)
+				return -1;
+			res = get_long(o, p);
+			Py_DECREF(o);
+			return res;
+		}
+#endif
 		if (PyErr_ExceptionMatches(PyExc_TypeError))
 			PyErr_SetString(StructError,
 					"required argument is not an integer");
@@ -225,6 +251,21 @@
 			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_Int(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);
@@ -249,6 +290,21 @@
 	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_Int(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;
@@ -1815,4 +1871,8 @@
 #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
+
 }