From f23851130af4e6e223de1f19073252423e2fccf2 Mon Sep 17 00:00:00 2001 From: Charlie Marsh Date: Mon, 8 May 2023 20:52:41 -0400 Subject: [PATCH] Add `flynt` to documentation (#4295) --- LICENSE | 24 ++++++++++++++ README.md | 1 + crates/ruff/src/rules/flynt/helpers.rs | 3 +- crates/ruff/src/rules/flynt/mod.rs | 8 +++-- .../flynt/rules/static_join_to_fstring.rs | 33 +++++++++---------- docs/faq.md | 2 ++ 6 files changed, 50 insertions(+), 21 deletions(-) diff --git a/LICENSE b/LICENSE index 590eda6e8b055..6a01371bb583a 100644 --- a/LICENSE +++ b/LICENSE @@ -550,6 +550,30 @@ are: THE SOFTWARE. """ +- flynt, licensed as follows: + """ + MIT License + + Copyright (c) 2019-2022 Ilya Kamenshchikov + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + """ - isort, licensed as follows: """ diff --git a/README.md b/README.md index 55c66322e494a..e03235b6a17c9 100644 --- a/README.md +++ b/README.md @@ -281,6 +281,7 @@ quality tools, including: - [flake8-tidy-imports](https://pypi.org/project/flake8-tidy-imports/) - [flake8-type-checking](https://pypi.org/project/flake8-type-checking/) - [flake8-use-pathlib](https://pypi.org/project/flake8-use-pathlib/) +- [flynt](https://pypi.org/project/flynt/) ([#2102](https://github.com/charliermarsh/ruff/issues/2102)) - [isort](https://pypi.org/project/isort/) - [mccabe](https://pypi.org/project/mccabe/) - [pandas-vet](https://pypi.org/project/pandas-vet/) diff --git a/crates/ruff/src/rules/flynt/helpers.rs b/crates/ruff/src/rules/flynt/helpers.rs index e6a6f743a2907..849e62cdea4f7 100644 --- a/crates/ruff/src/rules/flynt/helpers.rs +++ b/crates/ruff/src/rules/flynt/helpers.rs @@ -1,6 +1,7 @@ -use ruff_python_ast::helpers::create_expr; use rustpython_parser::ast::{Constant, Expr, ExprKind}; +use ruff_python_ast::helpers::create_expr; + /// Wrap an expression in a `FormattedValue` with no special formatting. fn to_formatted_value_expr(inner: &Expr) -> Expr { create_expr(ExprKind::FormattedValue { diff --git a/crates/ruff/src/rules/flynt/mod.rs b/crates/ruff/src/rules/flynt/mod.rs index 2d5ca2114a03c..1644a204802d2 100644 --- a/crates/ruff/src/rules/flynt/mod.rs +++ b/crates/ruff/src/rules/flynt/mod.rs @@ -4,12 +4,14 @@ pub(crate) mod rules; #[cfg(test)] mod tests { + use std::path::Path; + + use anyhow::Result; + use test_case::test_case; + use crate::registry::Rule; use crate::test::test_path; use crate::{assert_messages, settings}; - use anyhow::Result; - use std::path::Path; - use test_case::test_case; #[test_case(Rule::StaticJoinToFString, Path::new("FLY002.py"); "FLY002")] fn rules(rule_code: Rule, path: &Path) -> Result<()> { diff --git a/crates/ruff/src/rules/flynt/rules/static_join_to_fstring.rs b/crates/ruff/src/rules/flynt/rules/static_join_to_fstring.rs index 826604616203c..f34fffb0bace4 100644 --- a/crates/ruff/src/rules/flynt/rules/static_join_to_fstring.rs +++ b/crates/ruff/src/rules/flynt/rules/static_join_to_fstring.rs @@ -1,6 +1,6 @@ use rustpython_parser::ast::{Expr, ExprKind}; -use ruff_diagnostics::{AutofixKind, Diagnostic, Edit, Violation}; +use ruff_diagnostics::{AlwaysAutofixableViolation, Diagnostic, Edit, Fix}; use ruff_macros::{derive_message_formats, violation}; use ruff_python_ast::helpers::{create_expr, unparse_expr}; @@ -11,21 +11,18 @@ use crate::rules::flynt::helpers; #[violation] pub struct StaticJoinToFString { pub expr: String, - pub fixable: bool, } -impl Violation for StaticJoinToFString { - const AUTOFIX: AutofixKind = AutofixKind::Sometimes; - +impl AlwaysAutofixableViolation for StaticJoinToFString { #[derive_message_formats] fn message(&self) -> String { - let StaticJoinToFString { expr, .. } = self; + let StaticJoinToFString { expr } = self; format!("Consider `{expr}` instead of string join") } - fn autofix_title_formatter(&self) -> Option String> { - self.fixable - .then_some(|StaticJoinToFString { expr, .. }| format!("Replace with `{expr}`")) + fn autofix_title(&self) -> String { + let StaticJoinToFString { expr } = self; + format!("Replace with `{expr}`") } } @@ -44,12 +41,12 @@ fn build_fstring(joiner: &str, joinees: &[Expr]) -> Option { // gracefully right now. return None; } - if !first { + if !std::mem::take(&mut first) { fstring_elems.push(helpers::to_constant_string(joiner)); } fstring_elems.push(helpers::to_fstring_elem(expr)?); - first = false; } + Some(create_expr(ExprKind::JoinedStr { values: fstring_elems, })) @@ -57,20 +54,20 @@ fn build_fstring(joiner: &str, joinees: &[Expr]) -> Option { pub fn static_join_to_fstring(checker: &mut Checker, expr: &Expr, joiner: &str) { let ExprKind::Call { - func: _, args, keywords, + .. } = &expr.node else { return; }; if !keywords.is_empty() || args.len() != 1 { - // If there are kwargs or more than one argument, - // this is some non-standard string join call. + // If there are kwargs or more than one argument, this is some non-standard + // string join call. return; } - // Get the elements to join; skip e.g. generators, sets, etc. + // Get the elements to join; skip (e.g.) generators, sets, etc. let joinees = match &args[0].node { ExprKind::List { elts, .. } if is_static_length(elts) => elts, ExprKind::Tuple { elts, .. } if is_static_length(elts) => elts, @@ -86,12 +83,14 @@ pub fn static_join_to_fstring(checker: &mut Checker, expr: &Expr, joiner: &str) let mut diagnostic = Diagnostic::new( StaticJoinToFString { expr: contents.clone(), - fixable: true, }, expr.range(), ); if checker.patch(diagnostic.kind.rule()) { - diagnostic.set_fix(Edit::range_replacement(contents, expr.range())); + diagnostic.set_fix(Fix::unspecified(Edit::range_replacement( + contents, + expr.range(), + ))); } checker.diagnostics.push(diagnostic); } diff --git a/docs/faq.md b/docs/faq.md index 1e446b442285c..4cfcd313eaf77 100644 --- a/docs/faq.md +++ b/docs/faq.md @@ -65,6 +65,7 @@ natively, including: - [flake8-tidy-imports](https://pypi.org/project/flake8-tidy-imports/) - [flake8-type-checking](https://pypi.org/project/flake8-type-checking/) - [flake8-use-pathlib](https://pypi.org/project/flake8-use-pathlib/) +- [flynt](https://pypi.org/project/flynt/) ([#2102](https://github.com/charliermarsh/ruff/issues/2102)) - [isort](https://pypi.org/project/isort/) - [mccabe](https://pypi.org/project/mccabe/) - [pandas-vet](https://pypi.org/project/pandas-vet/) @@ -162,6 +163,7 @@ Today, Ruff can be used to replace Flake8 when used with any of the following pl - [flake8-tidy-imports](https://pypi.org/project/flake8-tidy-imports/) - [flake8-type-checking](https://pypi.org/project/flake8-type-checking/) - [flake8-use-pathlib](https://pypi.org/project/flake8-use-pathlib/) +- [flynt](https://pypi.org/project/flynt/) ([#2102](https://github.com/charliermarsh/ruff/issues/2102)) - [mccabe](https://pypi.org/project/mccabe/) - [pandas-vet](https://pypi.org/project/pandas-vet/) - [pep8-naming](https://pypi.org/project/pep8-naming/)