diff --git a/Lib/test/pickletester.py b/Lib/test/pickletester.py index 9a3a26a8400844..c5b3b27ba1acef 100644 --- a/Lib/test/pickletester.py +++ b/Lib/test/pickletester.py @@ -2964,6 +2964,10 @@ def test_float(self): got = self.loads(pickle) self.assert_is_copy(value, got) + def test_float_whitespace(self): + self.assertEqual(self.loads(b'F 1.2 \n.'), 1.2) + self.assertEqual(self.loads(b'F \t9 \n.'), 9) + @run_with_locales('LC_ALL', 'de_DE', 'fr_FR', '') def test_float_format(self): # make sure that floats are formatted locale independent with proto 0 diff --git a/Misc/NEWS.d/next/Library/2025-06-17-15-21-25.gh-issue-135580.kl7Eux.rst b/Misc/NEWS.d/next/Library/2025-06-17-15-21-25.gh-issue-135580.kl7Eux.rst new file mode 100644 index 00000000000000..4be11929acdba4 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2025-06-17-15-21-25.gh-issue-135580.kl7Eux.rst @@ -0,0 +1 @@ +The :mod:`pickle` ``FLOAT`` opcode now tolerates trailing and leading whitespace in both C and Python implementations. diff --git a/Modules/_pickle.c b/Modules/_pickle.c index cf3ceb43fb3f3f..fed05036dea0b2 100644 --- a/Modules/_pickle.c +++ b/Modules/_pickle.c @@ -5445,25 +5445,18 @@ load_counted_long(PickleState *st, UnpicklerObject *self, int size) static int load_float(PickleState *state, UnpicklerObject *self) { - PyObject *value; - char *endptr, *s; + PyObject *value, *s_obj; + char *s; Py_ssize_t len; - double d; if ((len = _Unpickler_Readline(state, self, &s)) < 0) return -1; if (len < 2) return bad_readline(state); - errno = 0; - d = PyOS_string_to_double(s, &endptr, PyExc_OverflowError); - if (d == -1.0 && PyErr_Occurred()) - return -1; - if ((endptr[0] != '\n') && (endptr[0] != '\0')) { - PyErr_SetString(PyExc_ValueError, "could not convert string to float"); - return -1; - } - value = PyFloat_FromDouble(d); + s_obj = PyUnicode_FromString(s); + value = PyFloat_FromString(s_obj); + if (value == NULL) return -1;