Skip empty lines when determining base indentation (#9795)

## Summary

It turns out we saw a panic in cases when dedenting blocks like the `def
wrapper` here:

```python
def instrument_url(f: UrlFuncT) -> UrlFuncT:
    # TODO: Type this with ParamSpec to preserve the function signature.
    if not INSTRUMENTING:  # nocoverage -- option is always enabled; should we remove?
        return f
    else:

        def wrapper(
            self: "ZulipTestCase", url: str, info: object = {}, **kwargs: Union[bool, str]
        ) -> HttpResponseBase:
```

Since we relied on the first line to determine the indentation, instead
of the first non-empty line.

## Test Plan

`cargo test`
This commit is contained in:
Charlie Marsh 2024-02-02 11:42:47 -08:00 committed by GitHub
parent e50603caf6
commit ee5b07d4ca
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 196 additions and 3 deletions

View file

@ -138,11 +138,18 @@ pub fn dedent(text: &str) -> Cow<'_, str> {
/// # Panics
/// If the first line is indented by less than the provided indent.
pub fn dedent_to(text: &str, indent: &str) -> String {
// Look at the indentation of the first line, to determine the "baseline" indentation.
// Look at the indentation of the first non-empty line, to determine the "baseline" indentation.
let existing_indent_len = text
.universal_newlines()
.next()
.map_or(0, |line| line.len() - line.trim_start().len());
.find_map(|line| {
let trimmed = line.trim_whitespace_start();
if trimmed.is_empty() || trimmed.starts_with('#') {
None
} else {
Some(line.len() - trimmed.len())
}
})
.unwrap_or_default();
// Determine the amount of indentation to remove.
let dedent_len = existing_indent_len - indent.len();