Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unify enums used for internal representation of quoting style #10383

Merged
merged 3 commits into from
Mar 13, 2024

Conversation

AlexWaygood
Copy link
Member

@AlexWaygood AlexWaygood commented Mar 13, 2024

Summary

Currently we have four enums across the codebase for representing the fact that Python strings can either use single quotes (') or double quotes ("):

#[derive(Debug, Default, Copy, Clone, Hash, PartialEq, Eq, is_macro::Is)]
pub enum QuoteStyle {
/// E.g. '
Single,
/// E.g. "
#[default]
Double,
}

/// The quotation character used to quote a string, byte, or fstring literal.
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
pub enum QuoteChar {
/// A single quote: `'`
Single,
/// A double quote: '"'
Double,
}

/// The quotation style used in Python source code.
#[derive(Debug, Default, PartialEq, Eq, Copy, Clone)]
pub enum Quote {
Single,
#[default]
Double,
}

#[derive(Debug, PartialEq, Eq, Copy, Clone, Hash, is_macro::Is)]
pub enum Quote {
Single,
Double,
}

This means we have a lot of impl From<QuoteEnum> for IdenticalOtherQuoteEnum methods, and it's generally somewhat confusing to keep track of the subtle differences between them. This PR unfies them into one enum in ruff_python_ast::str::QuoteStyle.

Using ruff_python_ast::str::QuoteStyle in the formatter would have created an awkward name clash with ruff_python_formatter::options::QuoteStyle, so I renamed ruff_python_formatter::options::QuoteStyle to ruff_python_formatter::options::QuotePreference. This seemed to me to more accurately reflect what that enum was for, but an alternative here would have been to rename ruff_python_ast::str::QuoteStyle. (Yet another alternative would be to always use the fully qualified name of ruff_python_ast::str:QuoteStyle in the formatter crate, but that felt too cumbersome to me.)

Test Plan

cargo test

@AlexWaygood AlexWaygood added the internal An internal refactor or improvement label Mar 13, 2024
@AlexWaygood AlexWaygood force-pushed the simplify-quote-enums branch from d39cd95 to 05f68dd Compare March 13, 2024 14:31
@AlexWaygood AlexWaygood requested a review from dhruvmanila March 13, 2024 14:40
Copy link
Contributor

github-actions bot commented Mar 13, 2024

ruff-ecosystem results

Linter (stable)

✅ ecosystem check detected no linter changes.

Linter (preview)

✅ ecosystem check detected no linter changes.

Formatter (stable)

✅ ecosystem check detected no format changes.

Formatter (preview)

✅ ecosystem check detected no format changes.

@dhruvmanila
Copy link
Member

Using ruff_python_ast::str::QuoteStyle in the formatter would have created an awkward name clash with ruff_python_ast::options::QuoteStyle, so I renamed ruff_python_ast::options::QuoteStyle to ruff_python_ast::options::QuotePreference.

Another option would be to use ruff_python_ast::str::Quote and keep the ruff_python_formatter::options::QuoteStyle. There's a chance that I might get confused with QuoteStyle's value coming from the quote-style config option 😅. This would mean that the enum usage would be Quote::Single, Quote::Double, quote.is_single, quote.is_double, etc. What do you think? @AlexWaygood

@AlexWaygood
Copy link
Member Author

here's a chance that I might get confused with QuoteStyle's value coming from the quote-style config option 😅. This would mean that the enum usage would be Quote::Single, Quote::Double, quote.is_single, quote.is_double, etc. What do you think? @AlexWaygood

Ahh, that makes sense... I should have checked what the config option was called, sorry!

I'll change the formatter enum's name back, and change the ruff_python_ast enum to Quote 👍

Copy link
Member

@dhruvmanila dhruvmanila left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is great! So many lines red lines :)

Comment on lines -231 to +235
let expr = self.semantic.current_expression()?;
let string_range = self.indexer.fstring_ranges().innermost(expr.start())?;
let trailing_quote = trailing_quote(self.locator.slice(string_range))?;

// Invert the quote character, if it's a single quote.
match trailing_quote {
"'" => Some(Quote::Double),
"\"" => Some(Quote::Single),
_ => None,
}
let ast::ExprFString { value, .. } = self
.semantic
.current_expressions()
.find_map(|expr| expr.as_f_string_expr())?;
Some(value.iter().next()?.quote_style().opposite())
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh nice, I like this change as the current_expressions start with innermost f-string in case of nested f-strings.

@AlexWaygood AlexWaygood enabled auto-merge (squash) March 13, 2024 17:12
@AlexWaygood AlexWaygood merged commit c2e15f3 into astral-sh:main Mar 13, 2024
16 checks passed
@AlexWaygood AlexWaygood deleted the simplify-quote-enums branch March 13, 2024 17:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
internal An internal refactor or improvement
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants