GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — Dedent -c command-line parameter value (#8056) · RustPython/RustPython@6ba2097

File tree

Expand file treeCollapse file tree
Open diff view settings
Filter options
  • Lib/test
    • test_cmd_line.py
    • test_os.py
  • src
    • settings.rs
Expand file treeCollapse file tree
Open diff view settings
Collapse file

‎Lib/test/test_cmd_line.py‎

Copy file name to clipboardExpand all lines: Lib/test/test_cmd_line.py
-1Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1110,7 +1110,6 @@ def test_int_max_str_digits(self):
11101110
)
11111111
self.assertEqual(res2int(res), (6000, 6000))
11121112

1113-
@unittest.expectedFailure # TODO: RUSTPYTHON
11141113
def test_cmd_dedent(self):
11151114
# test that -c auto-dedents its arguments
11161115
test_cases = [
Collapse file

‎Lib/test/test_os.py‎

Copy file name to clipboardExpand all lines: Lib/test/test_os.py
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2419,7 +2419,7 @@ def test_execve_invalid_env(self):
24192419

24202420
# See https://github.com/python/cpython/issues/137934 and the other
24212421
# related issues for the reason why we cannot test this on Windows.
2422-
@unittest.expectedFailure # TODO: RUSTPYTHON; IndentationError: unexpected indentation
2422+
@unittest.expectedFailure # TODO: RUSTPYTHON; TypeError: MyEnv.__getitem__() takes 1 positional argument but 2 were given
24232423
@unittest.skipIf(os.name == "nt", "POSIX-specific test")
24242424
@unittest.skipUnless(unix_shell and os.path.exists(unix_shell),
24252425
"requires a shell")
Collapse file

‎src/settings.rs‎

Copy file name to clipboardExpand all lines: src/settings.rs
+72-1Lines changed: 72 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,11 @@ fn parse_args() -> Result<(CliArgs, RunMode, Vec<String>), lexopt::Error> {
122122
Short('B') => args.dont_write_bytecode = true,
123123
Short('c') => {
124124
let cmd = parser.value()?.string()?;
125-
return Ok((args, RunMode::Command(cmd), argv("-c".to_owned(), parser)?));
125+
return Ok((
126+
args,
127+
RunMode::Command(dedent(&cmd)),
128+
argv("-c".to_owned(), parser)?,
129+
));
126130
}
127131
Short('d') => args.debug += 1,
128132
Short('E') => args.ignore_environment = true,
@@ -465,3 +469,70 @@ pub(crate) fn split_paths<T: AsRef<std::ffi::OsStr> + ?Sized>(
465469
.into()
466470
})
467471
}
472+
473+
/// Remove common whitespace prefix from all lines in a string.
474+
///
475+
/// This is like textwrap.dedent, and is used to process -c's code
476+
/// argument. It's different from ruff's dedent, which does not
477+
/// distinguish between tab and space characters when dedenting.
478+
fn dedent(input: &str) -> String {
479+
let mut prefix: Option<String> = None;
480+
let isspace = |c| c == ' ' || c == '\t';
481+
482+
// All-whitespace lines become empty.
483+
let deblanked: Vec<&str> = input
484+
.lines()
485+
.map(|line| if line.chars().all(isspace) { "" } else { line })
486+
.collect();
487+
488+
// Find maximum common whitespace prefix, if any.
489+
for line in deblanked.iter() {
490+
if line.is_empty() {
491+
continue;
492+
}
493+
if let Some(ref mut pstr) = prefix {
494+
for (i, (c, pc)) in line.chars().zip(pstr.chars()).enumerate() {
495+
// It's okay if `line` is shorter than `pstr`. At
496+
// least one char in `line` must be non-whitespace,
497+
// and if `line` is shorter than `pstr`, this
498+
// non-whitespace char will be compared to a
499+
// whitespace char, and loop will terminate.
500+
if c != pc {
501+
pstr.truncate(i);
502+
break;
503+
}
504+
}
505+
} else {
506+
let mut pstr = String::new();
507+
for c in line.chars() {
508+
if isspace(c) {
509+
pstr.push(c);
510+
} else {
511+
break;
512+
}
513+
}
514+
prefix = Some(pstr);
515+
continue;
516+
}
517+
}
518+
519+
if let Some(pstr) = prefix {
520+
// Strip common prefix.
521+
deblanked
522+
.iter()
523+
.map(|line| {
524+
if line.is_empty() {
525+
String::from("")
526+
} else {
527+
// All non-empty lines start with pstr, must be at
528+
// least pstr.len() long.
529+
String::from(line.get(pstr.len()..).unwrap())
530+
}
531+
})
532+
.collect::<Vec<_>>()
533+
.join("\n")
534+
} else {
535+
// No prefix found: all lines blank.
536+
deblanked.join("\n")
537+
}
538+
}

0 commit comments

Comments
0 (0)
You are visitor 01402520 — GeezerVison does not store the pages you look up.
Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.