bpo-28029: Make "".replace("", s, n) returning s for any n != 0. (GH-… · python/cpython@865c3b2 (original) (raw)
File tree
5 files changed
lines changed
- Misc/NEWS.d/next/Core and Builtins
5 files changed
lines changed
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -99,6 +99,11 @@ Other Language Changes | ||
99 | 99 | ignored for empty strings. |
100 | 100 | (Contributed by Victor Stinner in :issue:`37388`.) |
101 | 101 | |
102 | +* ``"".replace("", s, n)`` now returns ``s`` instead of an empty string for | |
103 | + all non-zero ``n``. It is now consistent with ``"".replace("", s)``. | |
104 | + There are similar changes for :class:`bytes` and :class:`bytearray` objects. | |
105 | + (Contributed by Serhiy Storchaka in :issue:`28029`.) | |
106 | + | |
102 | 107 | |
103 | 108 | New Modules |
104 | 109 | =========== |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -505,6 +505,7 @@ def test_replace(self): | ||
505 | 505 | EQ("", "", "replace", "A", "") |
506 | 506 | EQ("", "", "replace", "A", "A") |
507 | 507 | EQ("", "", "replace", "", "", 100) |
508 | +EQ("A", "", "replace", "", "A", 100) | |
508 | 509 | EQ("", "", "replace", "", "", sys.maxsize) |
509 | 510 | |
510 | 511 | # interleave (from=="", 'to' gets inserted everywhere) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
1 | +``"".replace("", s, n)`` now returns ``s`` instead of an empty string for | |
2 | +all non-zero ``n``. There are similar changes for :class:`bytes` and | |
3 | +:class:`bytearray` objects. |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -680,9 +680,13 @@ stringlib_replace(PyObject *self, | ||
680 | 680 | const char *to_s, Py_ssize_t to_len, |
681 | 681 | Py_ssize_t maxcount) |
682 | 682 | { |
683 | +if (STRINGLIB_LEN(self) < from_len) { | |
684 | +/* nothing to do; return the original bytes */ | |
685 | +return return_self(self); | |
686 | + } | |
683 | 687 | if (maxcount < 0) { |
684 | 688 | maxcount = PY_SSIZE_T_MAX; |
685 | - } else if (maxcount == 0 | | |
689 | + } else if (maxcount == 0) { | |
686 | 690 | /* nothing to do; return the original bytes */ |
687 | 691 | return return_self(self); |
688 | 692 | } |
@@ -699,13 +703,6 @@ stringlib_replace(PyObject *self, | ||
699 | 703 | return stringlib_replace_interleave(self, to_s, to_len, maxcount); |
700 | 704 | } |
701 | 705 | |
702 | -/* Except for b"".replace(b"", b"A") == b"A" there is no way beyond this */ | |
703 | -/* point for an empty self bytes to generate a non-empty bytes */ | |
704 | -/* Special case so the remaining code always gets a non-empty bytes */ | |
705 | -if (STRINGLIB_LEN(self) == 0) { | |
706 | -return return_self(self); | |
707 | - } | |
708 | - | |
709 | 706 | if (to_len == 0) { |
710 | 707 | /* delete all occurrences of 'from' bytes */ |
711 | 708 | if (from_len == 1) { |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -10572,9 +10572,12 @@ replace(PyObject *self, PyObject *str1, | ||
10572 | 10572 | int mayshrink; |
10573 | 10573 | Py_UCS4 maxchar, maxchar_str1, maxchar_str2; |
10574 | 10574 | |
10575 | +if (slen < len1) | |
10576 | + goto nothing; | |
10577 | + | |
10575 | 10578 | if (maxcount < 0) |
10576 | 10579 | maxcount = PY_SSIZE_T_MAX; |
10577 | -else if (maxcount == 0 | | |
10580 | +else if (maxcount == 0) | |
10578 | 10581 | goto nothing; |
10579 | 10582 | |
10580 | 10583 | if (str1 == str2) |