From f7eb51204a2bbbee1294ffb2c539bb6a4169d627 Mon Sep 17 00:00:00 2001 From: Yongjin Date: Sun, 26 Mar 2023 10:07:03 +0900 Subject: [PATCH] Returns new string when (str|bytes).replace get empty original string --- Lib/test/string_tests.py | 3 +++ vm/src/builtins/str.rs | 6 ++++-- vm/src/bytesinner.rs | 4 +++- 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/Lib/test/string_tests.py b/Lib/test/string_tests.py index 56658b2a4..ea82b0166 100644 --- a/Lib/test/string_tests.py +++ b/Lib/test/string_tests.py @@ -1202,6 +1202,9 @@ class MixinStrUnicodeUserStringTest: self.checkequal(False, 'asd', '__contains__', 'asdf') self.checkequal(False, '', '__contains__', 'asdf') + + # TODO: RUSTPYTHON + @unittest.expectedFailure def test_subscript(self): self.checkequal('a', 'abc', '__getitem__', 0) self.checkequal('c', 'abc', '__getitem__', -1) diff --git a/vm/src/builtins/str.rs b/vm/src/builtins/str.rs index dad7f0840..bf8a27d70 100644 --- a/vm/src/builtins/str.rs +++ b/vm/src/builtins/str.rs @@ -826,9 +826,11 @@ impl PyStr { let s = self.as_str(); match count { OptionalArg::Present(max_count) if max_count >= 0 => { - if max_count == 0 || s.is_empty() { + if max_count == 0 || (s.is_empty() && !old.is_empty()) { // nothing to do; return the original bytes - s.into() + s.to_owned() + } else if s.is_empty() && old.is_empty() { + new.as_str().to_owned() } else { s.replacen(old.as_str(), new.as_str(), max_count as usize) } diff --git a/vm/src/bytesinner.rs b/vm/src/bytesinner.rs index baae00a65..410b7d175 100644 --- a/vm/src/bytesinner.rs +++ b/vm/src/bytesinner.rs @@ -847,9 +847,11 @@ impl PyBytesInner { // stringlib_replace in CPython let maxcount = match maxcount { OptionalArg::Present(maxcount) if maxcount >= 0 => { - if maxcount == 0 || self.elements.is_empty() { + if maxcount == 0 || (self.elements.is_empty() && !from.is_empty()) { // nothing to do; return the original bytes return Ok(self.elements.clone()); + } else if self.elements.is_empty() && from.is_empty() { + return Ok(to.elements); } Some(maxcount as usize) }