bpo-28029: Make "".replace("", s, n) returning s for any n != 0. (GH-16981)

This commit is contained in:
Serhiy Storchaka 2019-10-30 12:03:53 +02:00 committed by GitHub
parent 25fc088607
commit 865c3b257f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 18 additions and 9 deletions

View File

@ -99,6 +99,11 @@ Other Language Changes
ignored for empty strings. ignored for empty strings.
(Contributed by Victor Stinner in :issue:`37388`.) (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 New Modules
=========== ===========

View File

@ -505,6 +505,7 @@ class BaseTest:
EQ("", "", "replace", "A", "") EQ("", "", "replace", "A", "")
EQ("", "", "replace", "A", "A") EQ("", "", "replace", "A", "A")
EQ("", "", "replace", "", "", 100) EQ("", "", "replace", "", "", 100)
EQ("A", "", "replace", "", "A", 100)
EQ("", "", "replace", "", "", sys.maxsize) EQ("", "", "replace", "", "", sys.maxsize)
# interleave (from=="", 'to' gets inserted everywhere) # interleave (from=="", 'to' gets inserted everywhere)

View File

@ -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.

View File

@ -680,9 +680,13 @@ stringlib_replace(PyObject *self,
const char *to_s, Py_ssize_t to_len, const char *to_s, Py_ssize_t to_len,
Py_ssize_t maxcount) Py_ssize_t maxcount)
{ {
if (STRINGLIB_LEN(self) < from_len) {
/* nothing to do; return the original bytes */
return return_self(self);
}
if (maxcount < 0) { if (maxcount < 0) {
maxcount = PY_SSIZE_T_MAX; maxcount = PY_SSIZE_T_MAX;
} else if (maxcount == 0 || STRINGLIB_LEN(self) == 0) { } else if (maxcount == 0) {
/* nothing to do; return the original bytes */ /* nothing to do; return the original bytes */
return return_self(self); return return_self(self);
} }
@ -699,13 +703,6 @@ stringlib_replace(PyObject *self,
return stringlib_replace_interleave(self, to_s, to_len, maxcount); 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) { if (to_len == 0) {
/* delete all occurrences of 'from' bytes */ /* delete all occurrences of 'from' bytes */
if (from_len == 1) { if (from_len == 1) {

View File

@ -10572,9 +10572,12 @@ replace(PyObject *self, PyObject *str1,
int mayshrink; int mayshrink;
Py_UCS4 maxchar, maxchar_str1, maxchar_str2; Py_UCS4 maxchar, maxchar_str1, maxchar_str2;
if (slen < len1)
goto nothing;
if (maxcount < 0) if (maxcount < 0)
maxcount = PY_SSIZE_T_MAX; maxcount = PY_SSIZE_T_MAX;
else if (maxcount == 0 || slen == 0) else if (maxcount == 0)
goto nothing; goto nothing;
if (str1 == str2) if (str1 == str2)