mirror of
https://github.com/astral-sh/ruff.git
synced 2025-08-30 23:27:27 +00:00
Remove spaces from import statements (#7859)
**Summary** Remove spaces from import statements such as ```python import tqdm . tqdm from tqdm . auto import tqdm ``` See also #7760 for a better solution. **Test Plan** New fixtures
This commit is contained in:
parent
644011fb14
commit
0f759af3cf
5 changed files with 29 additions and 4 deletions
|
@ -9,6 +9,8 @@ import foo\
|
|||
from foo\
|
||||
.bar import baz
|
||||
|
||||
import tqdm . tqdm
|
||||
|
||||
# At the top-level, force one empty line after an import, but allow up to two empty
|
||||
# lines.
|
||||
import os
|
||||
|
|
|
@ -35,3 +35,5 @@ from a import \
|
|||
( # comment
|
||||
bar,
|
||||
)
|
||||
|
||||
from tqdm . auto import tqdm
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
use ruff_formatter::{FormatOwnedWithRule, FormatRefWithRule};
|
||||
use ruff_python_ast::Identifier;
|
||||
use ruff_python_trivia::is_python_whitespace;
|
||||
use ruff_text_size::Ranged;
|
||||
|
||||
use crate::prelude::*;
|
||||
|
@ -31,6 +32,7 @@ impl<'ast> IntoFormat<PyFormatContext<'ast>> for Identifier {
|
|||
/// A formatter for a dot-delimited identifier, as seen in import statements:
|
||||
/// ```python
|
||||
/// import foo.bar
|
||||
/// from tqdm . auto import tqdm
|
||||
/// ```
|
||||
///
|
||||
/// Dot-delimited identifiers can contain newlines via continuations (backslashes) after the
|
||||
|
@ -54,14 +56,25 @@ impl<'a> DotDelimitedIdentifier<'a> {
|
|||
|
||||
impl Format<PyFormatContext<'_>> for DotDelimitedIdentifier<'_> {
|
||||
fn fmt(&self, f: &mut PyFormatter) -> FormatResult<()> {
|
||||
// An import identifier can contain newlines by inserting continuations (backslashes) after
|
||||
// An import identifier can contain whitespace around the dots:
|
||||
// ```python
|
||||
// import importlib . metadata
|
||||
// ```
|
||||
// It can also contain newlines by inserting continuations (backslashes) after
|
||||
// a dot-delimited segment, as in:
|
||||
// ```python
|
||||
// import foo\
|
||||
// .bar
|
||||
// .bar
|
||||
// ```
|
||||
if memchr::memchr(b'\\', f.context().source()[self.0.range()].as_bytes()).is_some() {
|
||||
text(self.0.as_str(), Some(self.0.start())).fmt(f)
|
||||
if f.context().source()[self.0.range()]
|
||||
.chars()
|
||||
.any(|c| is_python_whitespace(c) || matches!(c, '\n' | '\r' | '\\'))
|
||||
{
|
||||
let no_whitespace: String = f.context().source()[self.0.range()]
|
||||
.chars()
|
||||
.filter(|c| !is_python_whitespace(*c) && !matches!(c, '\n' | '\r' | '\\'))
|
||||
.collect();
|
||||
text(&no_whitespace, Some(self.0.start())).fmt(f)
|
||||
} else {
|
||||
source_text_slice(self.0.range()).fmt(f)
|
||||
}
|
||||
|
|
|
@ -15,6 +15,8 @@ import foo\
|
|||
from foo\
|
||||
.bar import baz
|
||||
|
||||
import tqdm . tqdm
|
||||
|
||||
# At the top-level, force one empty line after an import, but allow up to two empty
|
||||
# lines.
|
||||
import os
|
||||
|
@ -110,6 +112,8 @@ import foo.bar
|
|||
|
||||
from foo.bar import baz
|
||||
|
||||
import tqdm.tqdm
|
||||
|
||||
# At the top-level, force one empty line after an import, but allow up to two empty
|
||||
# lines.
|
||||
import os
|
||||
|
|
|
@ -41,6 +41,8 @@ from a import \
|
|||
( # comment
|
||||
bar,
|
||||
)
|
||||
|
||||
from tqdm . auto import tqdm
|
||||
```
|
||||
|
||||
## Output
|
||||
|
@ -115,6 +117,8 @@ from a import (
|
|||
from a import ( # comment
|
||||
bar,
|
||||
)
|
||||
|
||||
from tqdm.auto import tqdm
|
||||
```
|
||||
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue