From 6cb8b665a224a3e56f496b06f843702abbe61a8e Mon Sep 17 00:00:00 2001 From: Jeong YunWon Date: Wed, 11 Mar 2020 04:52:35 +0900 Subject: [PATCH] Fix str.expandtab() for newlines --- Lib/test/string_tests.py | 2 -- vm/src/obj/objstr.rs | 35 ++++++++++++++++++++++++----------- 2 files changed, 24 insertions(+), 13 deletions(-) diff --git a/Lib/test/string_tests.py b/Lib/test/string_tests.py index 4af8a70ee..121a9dca6 100644 --- a/Lib/test/string_tests.py +++ b/Lib/test/string_tests.py @@ -327,8 +327,6 @@ class BaseTest: self.checkequal('HELLO', 'HELLO', 'upper') self.checkraises(TypeError, 'hello', 'upper', 42) - # TODO: RUSTPYTHON - @unittest.expectedFailure def test_expandtabs(self): self.checkequal('abc\rab def\ng hi', 'abc\rab\tdef\ng\thi', 'expandtabs') diff --git a/vm/src/obj/objstr.rs b/vm/src/obj/objstr.rs index e3b186cf4..46a6ab41f 100644 --- a/vm/src/obj/objstr.rs +++ b/vm/src/obj/objstr.rs @@ -184,6 +184,12 @@ struct SplitLineArgs { keepends: OptionalArg, } +#[derive(FromArgs)] +struct ExpandtabsArgs { + #[pyarg(positional_or_keyword, optional = true)] + tabsize: OptionalArg, +} + #[pyimpl(flags(BASETYPE))] impl PyString { #[pyslot] @@ -1079,21 +1085,28 @@ impl PyString { } #[pymethod] - fn expandtabs(&self, tab_stop: OptionalArg) -> String { - let tab_stop = tab_stop.into_option().unwrap_or(8 as usize); + fn expandtabs(&self, args: ExpandtabsArgs) -> String { + let tab_stop = args.tabsize.unwrap_or(8); let mut expanded_str = String::with_capacity(self.value.len()); let mut tab_size = tab_stop; let mut col_count = 0 as usize; for ch in self.value.chars() { - // 0x0009 is tab - if ch == 0x0009 as char { - let num_spaces = tab_size - col_count; - col_count += num_spaces; - let expand = " ".repeat(num_spaces); - expanded_str.push_str(&expand); - } else { - expanded_str.push(ch); - col_count += 1; + match ch { + '\t' => { + let num_spaces = tab_size - col_count; + col_count += num_spaces; + let expand = " ".repeat(num_spaces); + expanded_str.push_str(&expand); + } + '\r' | '\n' => { + expanded_str.push(ch); + col_count = 0; + tab_size = 0; + } + _ => { + expanded_str.push(ch); + col_count += 1; + } } if col_count >= tab_size { tab_size += tab_stop;