From: Serhiy Storchaka Date: Wed, 30 Oct 2019 10:03:53 +0000 (+0200) Subject: bpo-28029: Make "".replace("", s, n) returning s for any n != 0. (GH-16981) X-Git-Tag: v3.9.0a1~105 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=865c3b257fe38154a4320c7ee6afb416f665b9c2;p=thirdparty%2FPython%2Fcpython.git bpo-28029: Make "".replace("", s, n) returning s for any n != 0. (GH-16981) --- diff --git a/Doc/whatsnew/3.9.rst b/Doc/whatsnew/3.9.rst index bca222955668..d41e70808d6e 100644 --- a/Doc/whatsnew/3.9.rst +++ b/Doc/whatsnew/3.9.rst @@ -99,6 +99,11 @@ Other Language Changes ignored for empty strings. (Contributed by Victor Stinner in :issue:`37388`.) +* ``"".replace("", s, n)`` now returns ``s`` instead of an empty string for + all non-zero ``n``. It is now consistent with ``"".replace("", s)``. + There are similar changes for :class:`bytes` and :class:`bytearray` objects. + (Contributed by Serhiy Storchaka in :issue:`28029`.) + New Modules =========== diff --git a/Lib/test/string_tests.py b/Lib/test/string_tests.py index 38da941f7f50..948e2a3c3c56 100644 --- a/Lib/test/string_tests.py +++ b/Lib/test/string_tests.py @@ -505,6 +505,7 @@ class BaseTest: EQ("", "", "replace", "A", "") EQ("", "", "replace", "A", "A") EQ("", "", "replace", "", "", 100) + EQ("A", "", "replace", "", "A", 100) EQ("", "", "replace", "", "", sys.maxsize) # interleave (from=="", 'to' gets inserted everywhere) diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-10-29-09-38-54.bpo-28029.AmRMEF.rst b/Misc/NEWS.d/next/Core and Builtins/2019-10-29-09-38-54.bpo-28029.AmRMEF.rst new file mode 100644 index 000000000000..420e53aec9be --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2019-10-29-09-38-54.bpo-28029.AmRMEF.rst @@ -0,0 +1,3 @@ +``"".replace("", s, n)`` now returns ``s`` instead of an empty string for +all non-zero ``n``. There are similar changes for :class:`bytes` and +:class:`bytearray` objects. diff --git a/Objects/stringlib/transmogrify.h b/Objects/stringlib/transmogrify.h index 9506019d5af2..e1165ea38e82 100644 --- a/Objects/stringlib/transmogrify.h +++ b/Objects/stringlib/transmogrify.h @@ -680,9 +680,13 @@ stringlib_replace(PyObject *self, const char *to_s, Py_ssize_t to_len, Py_ssize_t maxcount) { + if (STRINGLIB_LEN(self) < from_len) { + /* nothing to do; return the original bytes */ + return return_self(self); + } if (maxcount < 0) { maxcount = PY_SSIZE_T_MAX; - } else if (maxcount == 0 || STRINGLIB_LEN(self) == 0) { + } else if (maxcount == 0) { /* nothing to do; return the original bytes */ return return_self(self); } @@ -699,13 +703,6 @@ stringlib_replace(PyObject *self, return stringlib_replace_interleave(self, to_s, to_len, maxcount); } - /* Except for b"".replace(b"", b"A") == b"A" there is no way beyond this */ - /* point for an empty self bytes to generate a non-empty bytes */ - /* Special case so the remaining code always gets a non-empty bytes */ - if (STRINGLIB_LEN(self) == 0) { - return return_self(self); - } - if (to_len == 0) { /* delete all occurrences of 'from' bytes */ if (from_len == 1) { diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index 2d60627b1919..5ae0af8ea336 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -10572,9 +10572,12 @@ replace(PyObject *self, PyObject *str1, int mayshrink; Py_UCS4 maxchar, maxchar_str1, maxchar_str2; + if (slen < len1) + goto nothing; + if (maxcount < 0) maxcount = PY_SSIZE_T_MAX; - else if (maxcount == 0 || slen == 0) + else if (maxcount == 0) goto nothing; if (str1 == str2)