Compare commits
11 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a332f078db | ||
|
|
e0339b538b | ||
|
|
07b6b7401f | ||
|
|
1db7d9e759 | ||
|
|
621e9ace88 | ||
|
|
f9f77cf617 | ||
|
|
1a2bd984f2 | ||
|
|
4717d0779f | ||
|
|
07409ce201 | ||
|
|
2c0ec97782 | ||
|
|
e520a3a721 |
51
.github/workflows/release.yaml
vendored
51
.github/workflows/release.yaml
vendored
@@ -4,7 +4,7 @@ on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
tag:
|
||||
description: "The version to tag, without the leading 'v'. If omitted, will initiate a dry run skipping uploading artifact."
|
||||
description: "The version to tag, without the leading 'v'. If omitted, will initiate a dry run (no uploads)."
|
||||
type: string
|
||||
sha:
|
||||
description: "Optionally, the full sha of the commit to be released"
|
||||
@@ -392,28 +392,14 @@ jobs:
|
||||
*.tar.gz
|
||||
*.sha256
|
||||
|
||||
release:
|
||||
name: Release
|
||||
validate-tag:
|
||||
name: Validate tag
|
||||
runs-on: ubuntu-latest
|
||||
needs:
|
||||
- macos-universal
|
||||
- macos-x86_64
|
||||
- windows
|
||||
- linux
|
||||
- linux-cross
|
||||
- musllinux
|
||||
- musllinux-cross
|
||||
# If you don't set an input it's a dry run skipping uploading artifact
|
||||
# If you don't set an input tag, it's a dry run (no uploads).
|
||||
if: ${{ inputs.tag }}
|
||||
environment:
|
||||
name: release
|
||||
permissions:
|
||||
# For pypi trusted publishing
|
||||
id-token: write
|
||||
# For GitHub release publishing
|
||||
contents: write
|
||||
steps:
|
||||
- name: Consistency check tag
|
||||
- uses: actions/checkout@v3
|
||||
- name: Check tag consistency
|
||||
run: |
|
||||
version=$(grep "version = " pyproject.toml | sed -e 's/version = "\(.*\)"/\1/g')
|
||||
if [ "${{ inputs.tag }}" != "${version}" ]; then
|
||||
@@ -424,7 +410,7 @@ jobs:
|
||||
else
|
||||
echo "Releasing ${version}"
|
||||
fi
|
||||
- name: Consistency check sha
|
||||
- name: Check SHA consistency
|
||||
if: ${{ inputs.sha }}
|
||||
run: |
|
||||
git_sha=$(git rev-parse HEAD)
|
||||
@@ -436,6 +422,29 @@ jobs:
|
||||
else
|
||||
echo "Releasing ${git_sha}"
|
||||
fi
|
||||
|
||||
release:
|
||||
name: Release
|
||||
runs-on: ubuntu-latest
|
||||
needs:
|
||||
- macos-universal
|
||||
- macos-x86_64
|
||||
- windows
|
||||
- linux
|
||||
- linux-cross
|
||||
- musllinux
|
||||
- musllinux-cross
|
||||
- validate-tag
|
||||
# If you don't set an input tag, it's a dry run (no uploads).
|
||||
if: ${{ inputs.tag }}
|
||||
environment:
|
||||
name: release
|
||||
permissions:
|
||||
# For pypi trusted publishing
|
||||
id-token: write
|
||||
# For GitHub release publishing
|
||||
contents: write
|
||||
steps:
|
||||
- uses: actions/download-artifact@v3
|
||||
with:
|
||||
name: wheels
|
||||
|
||||
18
Cargo.lock
generated
18
Cargo.lock
generated
@@ -733,7 +733,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "flake8-to-ruff"
|
||||
version = "0.0.273"
|
||||
version = "0.0.274"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"clap",
|
||||
@@ -1793,7 +1793,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "ruff"
|
||||
version = "0.0.273"
|
||||
version = "0.0.274"
|
||||
dependencies = [
|
||||
"annotate-snippets 0.9.1",
|
||||
"anyhow",
|
||||
@@ -1889,7 +1889,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "ruff_cli"
|
||||
version = "0.0.273"
|
||||
version = "0.0.274"
|
||||
dependencies = [
|
||||
"annotate-snippets 0.9.1",
|
||||
"anyhow",
|
||||
@@ -2105,7 +2105,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "ruff_text_size"
|
||||
version = "0.0.0"
|
||||
source = "git+https://github.com/astral-sh/RustPython-Parser.git?rev=ed3b4eb72b6e497bbdb4d19dec6621074d724130#ed3b4eb72b6e497bbdb4d19dec6621074d724130"
|
||||
source = "git+https://github.com/astral-sh/RustPython-Parser.git?rev=08ebbe40d7776cac6e3ba66277d435056f2b8dca#08ebbe40d7776cac6e3ba66277d435056f2b8dca"
|
||||
dependencies = [
|
||||
"schemars",
|
||||
"serde",
|
||||
@@ -2183,7 +2183,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "rustpython-ast"
|
||||
version = "0.2.0"
|
||||
source = "git+https://github.com/astral-sh/RustPython-Parser.git?rev=ed3b4eb72b6e497bbdb4d19dec6621074d724130#ed3b4eb72b6e497bbdb4d19dec6621074d724130"
|
||||
source = "git+https://github.com/astral-sh/RustPython-Parser.git?rev=08ebbe40d7776cac6e3ba66277d435056f2b8dca#08ebbe40d7776cac6e3ba66277d435056f2b8dca"
|
||||
dependencies = [
|
||||
"is-macro",
|
||||
"num-bigint",
|
||||
@@ -2194,7 +2194,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "rustpython-format"
|
||||
version = "0.2.0"
|
||||
source = "git+https://github.com/astral-sh/RustPython-Parser.git?rev=ed3b4eb72b6e497bbdb4d19dec6621074d724130#ed3b4eb72b6e497bbdb4d19dec6621074d724130"
|
||||
source = "git+https://github.com/astral-sh/RustPython-Parser.git?rev=08ebbe40d7776cac6e3ba66277d435056f2b8dca#08ebbe40d7776cac6e3ba66277d435056f2b8dca"
|
||||
dependencies = [
|
||||
"bitflags 2.3.1",
|
||||
"itertools",
|
||||
@@ -2206,7 +2206,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "rustpython-literal"
|
||||
version = "0.2.0"
|
||||
source = "git+https://github.com/astral-sh/RustPython-Parser.git?rev=ed3b4eb72b6e497bbdb4d19dec6621074d724130#ed3b4eb72b6e497bbdb4d19dec6621074d724130"
|
||||
source = "git+https://github.com/astral-sh/RustPython-Parser.git?rev=08ebbe40d7776cac6e3ba66277d435056f2b8dca#08ebbe40d7776cac6e3ba66277d435056f2b8dca"
|
||||
dependencies = [
|
||||
"hexf-parse",
|
||||
"is-macro",
|
||||
@@ -2218,7 +2218,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "rustpython-parser"
|
||||
version = "0.2.0"
|
||||
source = "git+https://github.com/astral-sh/RustPython-Parser.git?rev=ed3b4eb72b6e497bbdb4d19dec6621074d724130#ed3b4eb72b6e497bbdb4d19dec6621074d724130"
|
||||
source = "git+https://github.com/astral-sh/RustPython-Parser.git?rev=08ebbe40d7776cac6e3ba66277d435056f2b8dca#08ebbe40d7776cac6e3ba66277d435056f2b8dca"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"is-macro",
|
||||
@@ -2241,7 +2241,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "rustpython-parser-core"
|
||||
version = "0.2.0"
|
||||
source = "git+https://github.com/astral-sh/RustPython-Parser.git?rev=ed3b4eb72b6e497bbdb4d19dec6621074d724130#ed3b4eb72b6e497bbdb4d19dec6621074d724130"
|
||||
source = "git+https://github.com/astral-sh/RustPython-Parser.git?rev=08ebbe40d7776cac6e3ba66277d435056f2b8dca#08ebbe40d7776cac6e3ba66277d435056f2b8dca"
|
||||
dependencies = [
|
||||
"is-macro",
|
||||
"memchr",
|
||||
|
||||
10
Cargo.toml
10
Cargo.toml
@@ -50,15 +50,15 @@ toml = { version = "0.7.2" }
|
||||
# v0.0.1
|
||||
libcst = { git = "https://github.com/charliermarsh/LibCST", rev = "80e4c1399f95e5beb532fdd1e209ad2dbb470438" }
|
||||
# v0.0.3
|
||||
ruff_text_size = { git = "https://github.com/astral-sh/RustPython-Parser.git", rev = "ed3b4eb72b6e497bbdb4d19dec6621074d724130" }
|
||||
ruff_text_size = { git = "https://github.com/astral-sh/RustPython-Parser.git", rev = "08ebbe40d7776cac6e3ba66277d435056f2b8dca" }
|
||||
# v0.0.3
|
||||
rustpython-ast = { git = "https://github.com/astral-sh/RustPython-Parser.git", rev = "ed3b4eb72b6e497bbdb4d19dec6621074d724130" , default-features = false, features = ["all-nodes-with-ranges", "num-bigint"]}
|
||||
rustpython-ast = { git = "https://github.com/astral-sh/RustPython-Parser.git", rev = "08ebbe40d7776cac6e3ba66277d435056f2b8dca" , default-features = false, features = ["all-nodes-with-ranges", "num-bigint"]}
|
||||
# v0.0.3
|
||||
rustpython-format = { git = "https://github.com/astral-sh/RustPython-Parser.git", rev = "ed3b4eb72b6e497bbdb4d19dec6621074d724130", default-features = false, features = ["num-bigint"] }
|
||||
rustpython-format = { git = "https://github.com/astral-sh/RustPython-Parser.git", rev = "08ebbe40d7776cac6e3ba66277d435056f2b8dca", default-features = false, features = ["num-bigint"] }
|
||||
# v0.0.3
|
||||
rustpython-literal = { git = "https://github.com/astral-sh/RustPython-Parser.git", rev = "ed3b4eb72b6e497bbdb4d19dec6621074d724130", default-features = false }
|
||||
rustpython-literal = { git = "https://github.com/astral-sh/RustPython-Parser.git", rev = "08ebbe40d7776cac6e3ba66277d435056f2b8dca", default-features = false }
|
||||
# v0.0.3
|
||||
rustpython-parser = { git = "https://github.com/astral-sh/RustPython-Parser.git", rev = "ed3b4eb72b6e497bbdb4d19dec6621074d724130" , default-features = false, features = ["full-lexer", "all-nodes-with-ranges", "num-bigint"] }
|
||||
rustpython-parser = { git = "https://github.com/astral-sh/RustPython-Parser.git", rev = "08ebbe40d7776cac6e3ba66277d435056f2b8dca" , default-features = false, features = ["full-lexer", "all-nodes-with-ranges", "num-bigint"] }
|
||||
|
||||
[profile.release]
|
||||
lto = "fat"
|
||||
|
||||
@@ -139,7 +139,7 @@ Ruff can also be used as a [pre-commit](https://pre-commit.com) hook:
|
||||
```yaml
|
||||
- repo: https://github.com/astral-sh/ruff-pre-commit
|
||||
# Ruff version.
|
||||
rev: v0.0.273
|
||||
rev: v0.0.274
|
||||
hooks:
|
||||
- id: ruff
|
||||
```
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "flake8-to-ruff"
|
||||
version = "0.0.273"
|
||||
version = "0.0.274"
|
||||
description = """
|
||||
Convert Flake8 configuration files to Ruff configuration files.
|
||||
"""
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "ruff"
|
||||
version = "0.0.273"
|
||||
version = "0.0.274"
|
||||
publish = false
|
||||
authors = { workspace = true }
|
||||
edition = { workspace = true }
|
||||
|
||||
@@ -34,12 +34,3 @@ f"{ascii(bla)}" # OK
|
||||
" intermediary content "
|
||||
f" that flows {repr(obj)} of type {type(obj)}.{additional_message}" # RUF010
|
||||
)
|
||||
|
||||
|
||||
f"{str(bla)}" # RUF010
|
||||
|
||||
f"{str(bla):20}" # RUF010
|
||||
|
||||
f"{bla!s}" # RUF010
|
||||
|
||||
f"{bla!s:20}" # OK
|
||||
|
||||
@@ -185,3 +185,18 @@ def f(arg: Union[Annotated[int, ...], Annotated[Optional[float], ...]] = None):
|
||||
|
||||
def f(arg: Union[Annotated[int, ...], Union[str, bytes]] = None): # RUF011
|
||||
pass
|
||||
|
||||
|
||||
# Quoted
|
||||
|
||||
|
||||
def f(arg: "int" = None):
|
||||
pass
|
||||
|
||||
|
||||
def f(arg: "str" = None):
|
||||
pass
|
||||
|
||||
|
||||
def f(arg: "Optional[int]" = None):
|
||||
pass
|
||||
|
||||
@@ -8,7 +8,7 @@ use ruff_python_ast::source_code::{Indexer, Locator, Stylist};
|
||||
use ruff_python_whitespace::UniversalNewlines;
|
||||
|
||||
use crate::registry::Rule;
|
||||
use crate::rules::copyright::rules::missing_copyright_notice;
|
||||
use crate::rules::flake8_copyright::rules::missing_copyright_notice;
|
||||
use crate::rules::flake8_executable::helpers::{extract_shebang, ShebangDirective};
|
||||
use crate::rules::flake8_executable::rules::{
|
||||
shebang_missing, shebang_newline, shebang_not_executable, shebang_python, shebang_whitespace,
|
||||
|
||||
@@ -375,7 +375,7 @@ pub fn code_to_rule(linter: Linter, code: &str) -> Option<(RuleGroup, Rule)> {
|
||||
(Flake8Simplify, "910") => (RuleGroup::Unspecified, rules::flake8_simplify::rules::DictGetWithNoneDefault),
|
||||
|
||||
// copyright
|
||||
(Copyright, "001") => (RuleGroup::Nursery, rules::copyright::rules::MissingCopyrightNotice),
|
||||
(Copyright, "001") => (RuleGroup::Nursery, rules::flake8_copyright::rules::MissingCopyrightNotice),
|
||||
|
||||
// pyupgrade
|
||||
(Pyupgrade, "001") => (RuleGroup::Unspecified, rules::pyupgrade::rules::UselessMetaclassType),
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
---
|
||||
source: crates/ruff/src/rules/copyright/mod.rs
|
||||
---
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
---
|
||||
source: crates/ruff/src/rules/copyright/mod.rs
|
||||
---
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
---
|
||||
source: crates/ruff/src/rules/copyright/mod.rs
|
||||
---
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
---
|
||||
source: crates/ruff/src/rules/copyright/mod.rs
|
||||
---
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
---
|
||||
source: crates/ruff/src/rules/copyright/mod.rs
|
||||
---
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
---
|
||||
source: crates/ruff/src/rules/copyright/mod.rs
|
||||
---
|
||||
|
||||
@@ -75,7 +75,7 @@ import os
|
||||
"#
|
||||
.trim(),
|
||||
&settings::Settings {
|
||||
copyright: super::settings::Settings {
|
||||
flake8_copyright: super::settings::Settings {
|
||||
author: Some("Ruff".to_string()),
|
||||
..super::settings::Settings::default()
|
||||
},
|
||||
@@ -95,7 +95,7 @@ import os
|
||||
"#
|
||||
.trim(),
|
||||
&settings::Settings {
|
||||
copyright: super::settings::Settings {
|
||||
flake8_copyright: super::settings::Settings {
|
||||
author: Some("Ruff".to_string()),
|
||||
..super::settings::Settings::default()
|
||||
},
|
||||
@@ -113,7 +113,7 @@ import os
|
||||
"#
|
||||
.trim(),
|
||||
&settings::Settings {
|
||||
copyright: super::settings::Settings {
|
||||
flake8_copyright: super::settings::Settings {
|
||||
min_file_size: 256,
|
||||
..super::settings::Settings::default()
|
||||
},
|
||||
@@ -28,7 +28,7 @@ pub(crate) fn missing_copyright_notice(
|
||||
settings: &Settings,
|
||||
) -> Option<Diagnostic> {
|
||||
// Ignore files that are too small to contain a copyright notice.
|
||||
if locator.len() < settings.copyright.min_file_size {
|
||||
if locator.len() < settings.flake8_copyright.min_file_size {
|
||||
return None;
|
||||
}
|
||||
|
||||
@@ -40,8 +40,8 @@ pub(crate) fn missing_copyright_notice(
|
||||
};
|
||||
|
||||
// Locate the copyright notice.
|
||||
if let Some(match_) = settings.copyright.notice_rgx.find(contents) {
|
||||
match settings.copyright.author {
|
||||
if let Some(match_) = settings.flake8_copyright.notice_rgx.find(contents) {
|
||||
match settings.flake8_copyright.author {
|
||||
Some(ref author) => {
|
||||
// Ensure that it's immediately followed by the author.
|
||||
if contents[match_.end()..].trim_start().starts_with(author) {
|
||||
@@ -1,4 +1,4 @@
|
||||
//! Settings for the `copyright` plugin.
|
||||
//! Settings for the `flake8-copyright` plugin.
|
||||
|
||||
use once_cell::sync::Lazy;
|
||||
use regex::Regex;
|
||||
@@ -12,7 +12,7 @@ use ruff_macros::{CacheKey, CombineOptions, ConfigurationOptions};
|
||||
#[serde(
|
||||
deny_unknown_fields,
|
||||
rename_all = "kebab-case",
|
||||
rename = "CopyrightOptions"
|
||||
rename = "Flake8CopyrightOptions"
|
||||
)]
|
||||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||
pub struct Options {
|
||||
@@ -1,5 +1,5 @@
|
||||
---
|
||||
source: crates/ruff/src/rules/copyright/mod.rs
|
||||
source: crates/ruff/src/rules/flake8_copyright/mod.rs
|
||||
---
|
||||
<filename>:1:1: CPY001 Missing copyright notice at top of file
|
||||
|
|
||||
@@ -1,5 +1,5 @@
|
||||
---
|
||||
source: crates/ruff/src/rules/copyright/mod.rs
|
||||
source: crates/ruff/src/rules/flake8_copyright/mod.rs
|
||||
---
|
||||
<filename>:1:1: CPY001 Missing copyright notice at top of file
|
||||
|
|
||||
@@ -0,0 +1,4 @@
|
||||
---
|
||||
source: crates/ruff/src/rules/flake8_copyright/mod.rs
|
||||
---
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
---
|
||||
source: crates/ruff/src/rules/flake8_copyright/mod.rs
|
||||
---
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
---
|
||||
source: crates/ruff/src/rules/flake8_copyright/mod.rs
|
||||
---
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
---
|
||||
source: crates/ruff/src/rules/flake8_copyright/mod.rs
|
||||
---
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
---
|
||||
source: crates/ruff/src/rules/flake8_copyright/mod.rs
|
||||
---
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
---
|
||||
source: crates/ruff/src/rules/flake8_copyright/mod.rs
|
||||
---
|
||||
|
||||
@@ -7,6 +7,28 @@ use ruff_python_ast::call_path::{format_call_path, from_unqualified_name, CallPa
|
||||
use crate::checkers::ast::Checker;
|
||||
use crate::rules::flake8_debugger::types::DebuggerUsingType;
|
||||
|
||||
/// ## What it does
|
||||
/// Checks for the presence of debugger calls and imports.
|
||||
///
|
||||
/// ## Why is this bad?
|
||||
/// Debugger calls and imports should be used for debugging purposes only. The
|
||||
/// presence of a debugger call or import in production code is likely a
|
||||
/// mistake and may cause unintended behavior, such as exposing sensitive
|
||||
/// information or causing the program to hang.
|
||||
///
|
||||
/// Instead, consider using a logging library to log information about the
|
||||
/// program's state, and writing tests to verify that the program behaves
|
||||
/// as expected.
|
||||
///
|
||||
/// ## Example
|
||||
/// ```python
|
||||
/// def foo():
|
||||
/// breakpoint()
|
||||
/// ```
|
||||
///
|
||||
/// ## References
|
||||
/// - [Python documentation: `pdb` — The Python Debugger](https://docs.python.org/3/library/pdb.html)
|
||||
/// - [Python documentation: `logging` — Logging facility for Python](https://docs.python.org/3/library/logging.html)
|
||||
#[violation]
|
||||
pub struct Debugger {
|
||||
using_type: DebuggerUsingType,
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
#![allow(clippy::useless_format)]
|
||||
pub mod airflow;
|
||||
pub mod copyright;
|
||||
pub mod eradicate;
|
||||
pub mod flake8_2020;
|
||||
pub mod flake8_annotations;
|
||||
@@ -12,6 +11,7 @@ pub mod flake8_bugbear;
|
||||
pub mod flake8_builtins;
|
||||
pub mod flake8_commas;
|
||||
pub mod flake8_comprehensions;
|
||||
pub mod flake8_copyright;
|
||||
pub mod flake8_datetimez;
|
||||
pub mod flake8_debugger;
|
||||
pub mod flake8_django;
|
||||
|
||||
@@ -12,7 +12,7 @@ use crate::registry::AsRule;
|
||||
/// ## Why is this bad?
|
||||
/// NumPy's `np.int` has long been an alias of the builtin `int`. The same
|
||||
/// goes for `np.float`, `np.bool`, and others. These aliases exist
|
||||
/// primarily primarily for historic reasons, and have been a cause of
|
||||
/// primarily for historic reasons, and have been a cause of
|
||||
/// frequent confusion for newcomers.
|
||||
///
|
||||
/// These aliases were been deprecated in 1.20, and removed in 1.24.
|
||||
|
||||
@@ -6,7 +6,6 @@ use rustpython_parser::ast::{self, Expr, Ranged};
|
||||
|
||||
use ruff_diagnostics::{AlwaysAutofixableViolation, Diagnostic, Edit, Fix};
|
||||
use ruff_macros::{derive_message_formats, violation};
|
||||
use ruff_python_ast::prelude::ConversionFlag;
|
||||
use ruff_python_ast::source_code::{Locator, Stylist};
|
||||
|
||||
use crate::autofix::codemods::CodegenStylist;
|
||||
@@ -22,62 +21,36 @@ use crate::registry::AsRule;
|
||||
/// f-strings support dedicated conversion flags for these types, which are
|
||||
/// more succinct and idiomatic.
|
||||
///
|
||||
/// In the case of `str()`, it's also redundant, since `str()` is the default
|
||||
/// conversion.
|
||||
/// Note that, in many cases, calling `str()` within an f-string is
|
||||
/// unnecessary and can be removed entirely, as the value will be converted
|
||||
/// to a string automatically, the notable exception being for classes that
|
||||
/// implement a custom `__format__` method.
|
||||
///
|
||||
/// ## Example
|
||||
/// ```python
|
||||
/// a = "some string"
|
||||
/// f"{str(a)}"
|
||||
/// f"{repr(a)}"
|
||||
/// ```
|
||||
///
|
||||
/// Use instead:
|
||||
/// ```python
|
||||
/// a = "some string"
|
||||
/// f"{a}"
|
||||
/// f"{a!r}"
|
||||
/// ```
|
||||
#[violation]
|
||||
pub struct ExplicitFStringTypeConversion {
|
||||
operation: Operation,
|
||||
}
|
||||
pub struct ExplicitFStringTypeConversion;
|
||||
|
||||
impl AlwaysAutofixableViolation for ExplicitFStringTypeConversion {
|
||||
#[derive_message_formats]
|
||||
fn message(&self) -> String {
|
||||
let ExplicitFStringTypeConversion { operation } = self;
|
||||
match operation {
|
||||
Operation::ConvertCallToConversionFlag => {
|
||||
format!("Use explicit conversion flag")
|
||||
}
|
||||
Operation::RemoveCall => format!("Remove unnecessary `str` conversion"),
|
||||
Operation::RemoveConversionFlag => format!("Remove unnecessary conversion flag"),
|
||||
}
|
||||
format!("Use explicit conversion flag")
|
||||
}
|
||||
|
||||
fn autofix_title(&self) -> String {
|
||||
let ExplicitFStringTypeConversion { operation } = self;
|
||||
match operation {
|
||||
Operation::ConvertCallToConversionFlag => {
|
||||
format!("Replace with conversion flag")
|
||||
}
|
||||
Operation::RemoveCall => format!("Remove `str` call"),
|
||||
Operation::RemoveConversionFlag => format!("Remove conversion flag"),
|
||||
}
|
||||
"Replace with conversion flag".to_string()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Eq)]
|
||||
enum Operation {
|
||||
/// Ex) Convert `f"{repr(bla)}"` to `f"{bla!r}"`
|
||||
ConvertCallToConversionFlag,
|
||||
/// Ex) Convert `f"{bla!s}"` to `f"{bla}"`
|
||||
RemoveConversionFlag,
|
||||
/// Ex) Convert `f"{str(bla)}"` to `f"{bla}"`
|
||||
RemoveCall,
|
||||
}
|
||||
|
||||
/// RUF010
|
||||
pub(crate) fn explicit_f_string_type_conversion(
|
||||
checker: &mut Checker,
|
||||
@@ -96,156 +69,50 @@ pub(crate) fn explicit_f_string_type_conversion(
|
||||
.enumerate()
|
||||
{
|
||||
let ast::ExprFormattedValue {
|
||||
value,
|
||||
conversion,
|
||||
format_spec,
|
||||
range: _,
|
||||
value, conversion, ..
|
||||
} = formatted_value;
|
||||
|
||||
match conversion {
|
||||
ConversionFlag::Ascii | ConversionFlag::Repr => {
|
||||
// Nothing to do.
|
||||
continue;
|
||||
}
|
||||
ConversionFlag::Str => {
|
||||
// Skip if there's a format spec.
|
||||
if format_spec.is_some() {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Remove the conversion flag entirely.
|
||||
// Ex) `f"{bla!s}"`
|
||||
let mut diagnostic = Diagnostic::new(
|
||||
ExplicitFStringTypeConversion {
|
||||
operation: Operation::RemoveConversionFlag,
|
||||
},
|
||||
value.range(),
|
||||
);
|
||||
if checker.patch(diagnostic.kind.rule()) {
|
||||
diagnostic.try_set_fix(|| {
|
||||
remove_conversion_flag(expr, index, checker.locator, checker.stylist)
|
||||
});
|
||||
}
|
||||
checker.diagnostics.push(diagnostic);
|
||||
}
|
||||
ConversionFlag::None => {
|
||||
// Replace with the appropriate conversion flag.
|
||||
let Expr::Call(ast::ExprCall {
|
||||
func,
|
||||
args,
|
||||
keywords,
|
||||
..
|
||||
}) = value.as_ref() else {
|
||||
continue;
|
||||
};
|
||||
|
||||
// Can't be a conversion otherwise.
|
||||
if args.len() != 1 || !keywords.is_empty() {
|
||||
continue;
|
||||
}
|
||||
|
||||
let Expr::Name(ast::ExprName { id, .. }) = func.as_ref() else {
|
||||
continue;
|
||||
};
|
||||
|
||||
if !matches!(id.as_str(), "str" | "repr" | "ascii") {
|
||||
continue;
|
||||
};
|
||||
|
||||
if !checker.semantic().is_builtin(id) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if id == "str" && format_spec.is_none() {
|
||||
// Ex) `f"{str(bla)}"`
|
||||
let mut diagnostic = Diagnostic::new(
|
||||
ExplicitFStringTypeConversion {
|
||||
operation: Operation::RemoveCall,
|
||||
},
|
||||
value.range(),
|
||||
);
|
||||
if checker.patch(diagnostic.kind.rule()) {
|
||||
diagnostic.try_set_fix(|| {
|
||||
remove_conversion_call(expr, index, checker.locator, checker.stylist)
|
||||
});
|
||||
}
|
||||
checker.diagnostics.push(diagnostic);
|
||||
} else {
|
||||
// Ex) `f"{repr(bla)}"`
|
||||
let mut diagnostic = Diagnostic::new(
|
||||
ExplicitFStringTypeConversion {
|
||||
operation: Operation::ConvertCallToConversionFlag,
|
||||
},
|
||||
value.range(),
|
||||
);
|
||||
if checker.patch(diagnostic.kind.rule()) {
|
||||
diagnostic.try_set_fix(|| {
|
||||
convert_call_to_conversion_flag(
|
||||
expr,
|
||||
index,
|
||||
checker.locator,
|
||||
checker.stylist,
|
||||
)
|
||||
});
|
||||
}
|
||||
checker.diagnostics.push(diagnostic);
|
||||
}
|
||||
}
|
||||
// Skip if there's already a conversion flag.
|
||||
if !conversion.is_none() {
|
||||
continue;
|
||||
}
|
||||
|
||||
let Expr::Call(ast::ExprCall {
|
||||
func,
|
||||
args,
|
||||
keywords,
|
||||
..
|
||||
}) = value.as_ref() else {
|
||||
continue;
|
||||
};
|
||||
|
||||
// Can't be a conversion otherwise.
|
||||
if args.len() != 1 || !keywords.is_empty() {
|
||||
continue;
|
||||
}
|
||||
|
||||
let Expr::Name(ast::ExprName { id, .. }) = func.as_ref() else {
|
||||
continue;
|
||||
};
|
||||
|
||||
if !matches!(id.as_str(), "str" | "repr" | "ascii") {
|
||||
continue;
|
||||
};
|
||||
|
||||
if !checker.semantic().is_builtin(id) {
|
||||
continue;
|
||||
}
|
||||
|
||||
let mut diagnostic = Diagnostic::new(ExplicitFStringTypeConversion, value.range());
|
||||
if checker.patch(diagnostic.kind.rule()) {
|
||||
diagnostic.try_set_fix(|| {
|
||||
convert_call_to_conversion_flag(expr, index, checker.locator, checker.stylist)
|
||||
});
|
||||
}
|
||||
checker.diagnostics.push(diagnostic);
|
||||
}
|
||||
}
|
||||
|
||||
/// Generate a [`Fix`] to remove a conversion flag from a formatted expression.
|
||||
fn remove_conversion_flag(
|
||||
expr: &Expr,
|
||||
index: usize,
|
||||
locator: &Locator,
|
||||
stylist: &Stylist,
|
||||
) -> Result<Fix> {
|
||||
// Parenthesize the expression, to support implicit concatenation.
|
||||
let range = expr.range();
|
||||
let content = locator.slice(range);
|
||||
let parenthesized_content = format!("({content})");
|
||||
let mut expression = match_expression(&parenthesized_content)?;
|
||||
|
||||
// Replace the formatted call expression at `index` with a conversion flag.
|
||||
let formatted_string_expression = match_part(index, &mut expression)?;
|
||||
formatted_string_expression.conversion = None;
|
||||
|
||||
// Remove the parentheses (first and last characters).
|
||||
let mut content = expression.codegen_stylist(stylist);
|
||||
content.remove(0);
|
||||
content.pop();
|
||||
|
||||
Ok(Fix::automatic(Edit::range_replacement(content, range)))
|
||||
}
|
||||
|
||||
/// Generate a [`Fix`] to remove a call from a formatted expression.
|
||||
fn remove_conversion_call(
|
||||
expr: &Expr,
|
||||
index: usize,
|
||||
locator: &Locator,
|
||||
stylist: &Stylist,
|
||||
) -> Result<Fix> {
|
||||
// Parenthesize the expression, to support implicit concatenation.
|
||||
let range = expr.range();
|
||||
let content = locator.slice(range);
|
||||
let parenthesized_content = format!("({content})");
|
||||
let mut expression = match_expression(&parenthesized_content)?;
|
||||
|
||||
// Replace the formatted call expression at `index` with a conversion flag.
|
||||
let formatted_string_expression = match_part(index, &mut expression)?;
|
||||
let call = match_call_mut(&mut formatted_string_expression.expression)?;
|
||||
formatted_string_expression.expression = call.args[0].value.clone();
|
||||
|
||||
// Remove the parentheses (first and last characters).
|
||||
let mut content = expression.codegen_stylist(stylist);
|
||||
content.remove(0);
|
||||
content.pop();
|
||||
|
||||
Ok(Fix::automatic(Edit::range_replacement(content, range)))
|
||||
}
|
||||
|
||||
/// Generate a [`Fix`] to replace an explicit type conversion with a conversion flag.
|
||||
fn convert_call_to_conversion_flag(
|
||||
expr: &Expr,
|
||||
|
||||
@@ -142,6 +142,7 @@ enum TypingTarget<'a> {
|
||||
None,
|
||||
Any,
|
||||
Object,
|
||||
ForwardReference,
|
||||
Optional,
|
||||
Union(Vec<&'a Expr>),
|
||||
Literal(Vec<&'a Expr>),
|
||||
@@ -175,6 +176,10 @@ impl<'a> TypingTarget<'a> {
|
||||
value: Constant::None,
|
||||
..
|
||||
}) => Some(TypingTarget::None),
|
||||
Expr::Constant(ast::ExprConstant {
|
||||
value: Constant::Str(_),
|
||||
..
|
||||
}) => Some(TypingTarget::ForwardReference),
|
||||
_ => semantic.resolve_call_path(expr).and_then(|call_path| {
|
||||
if semantic.match_typing_call_path(&call_path, "Any") {
|
||||
Some(TypingTarget::Any)
|
||||
@@ -196,8 +201,8 @@ impl<'a> TypingTarget<'a> {
|
||||
| TypingTarget::Object => true,
|
||||
TypingTarget::Literal(elements) => elements.iter().any(|element| {
|
||||
let Some(new_target) = TypingTarget::try_from_expr(element, semantic) else {
|
||||
return false;
|
||||
};
|
||||
return false;
|
||||
};
|
||||
// Literal can only contain `None`, a literal value, other `Literal`
|
||||
// or an enum value.
|
||||
match new_target {
|
||||
@@ -208,8 +213,8 @@ impl<'a> TypingTarget<'a> {
|
||||
}),
|
||||
TypingTarget::Union(elements) => elements.iter().any(|element| {
|
||||
let Some(new_target) = TypingTarget::try_from_expr(element, semantic) else {
|
||||
return false;
|
||||
};
|
||||
return false;
|
||||
};
|
||||
match new_target {
|
||||
TypingTarget::None => true,
|
||||
_ => new_target.contains_none(semantic),
|
||||
@@ -217,13 +222,15 @@ impl<'a> TypingTarget<'a> {
|
||||
}),
|
||||
TypingTarget::Annotated(element) => {
|
||||
let Some(new_target) = TypingTarget::try_from_expr(element, semantic) else {
|
||||
return false;
|
||||
};
|
||||
return false;
|
||||
};
|
||||
match new_target {
|
||||
TypingTarget::None => true,
|
||||
_ => new_target.contains_none(semantic),
|
||||
}
|
||||
}
|
||||
// TODO(charlie): Add support for forward references (quoted annotations).
|
||||
TypingTarget::ForwardReference => true,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -305,7 +312,7 @@ fn generate_fix(checker: &Checker, conversion_type: ConversionType, expr: &Expr)
|
||||
}
|
||||
}
|
||||
|
||||
/// RUF011
|
||||
/// RUF013
|
||||
pub(crate) fn implicit_optional(checker: &mut Checker, arguments: &Arguments) {
|
||||
for ArgWithDefault {
|
||||
def,
|
||||
|
||||
@@ -312,5 +312,7 @@ RUF013_0.py:186:12: RUF013 [*] PEP 484 prohibits implicit `Optional`
|
||||
186 |-def f(arg: Union[Annotated[int, ...], Union[str, bytes]] = None): # RUF011
|
||||
186 |+def f(arg: Optional[Union[Annotated[int, ...], Union[str, bytes]]] = None): # RUF011
|
||||
187 187 | pass
|
||||
188 188 |
|
||||
189 189 |
|
||||
|
||||
|
||||
|
||||
@@ -1,21 +1,21 @@
|
||||
---
|
||||
source: crates/ruff/src/rules/ruff/mod.rs
|
||||
---
|
||||
RUF010.py:9:4: RUF010 [*] Remove unnecessary `str` conversion
|
||||
RUF010.py:9:4: RUF010 [*] Use explicit conversion flag
|
||||
|
|
||||
9 | f"{str(bla)}, {repr(bla)}, {ascii(bla)}" # RUF010
|
||||
| ^^^^^^^^ RUF010
|
||||
10 |
|
||||
11 | f"{str(d['a'])}, {repr(d['b'])}, {ascii(d['c'])}" # RUF010
|
||||
|
|
||||
= help: Remove `str` call
|
||||
= help: Replace with conversion flag
|
||||
|
||||
ℹ Fix
|
||||
6 6 | pass
|
||||
7 7 |
|
||||
8 8 |
|
||||
9 |-f"{str(bla)}, {repr(bla)}, {ascii(bla)}" # RUF010
|
||||
9 |+f"{bla}, {repr(bla)}, {ascii(bla)}" # RUF010
|
||||
9 |+f"{bla!s}, {repr(bla)}, {ascii(bla)}" # RUF010
|
||||
10 10 |
|
||||
11 11 | f"{str(d['a'])}, {repr(d['b'])}, {ascii(d['c'])}" # RUF010
|
||||
12 12 |
|
||||
@@ -58,7 +58,7 @@ RUF010.py:9:29: RUF010 [*] Use explicit conversion flag
|
||||
11 11 | f"{str(d['a'])}, {repr(d['b'])}, {ascii(d['c'])}" # RUF010
|
||||
12 12 |
|
||||
|
||||
RUF010.py:11:4: RUF010 [*] Remove unnecessary `str` conversion
|
||||
RUF010.py:11:4: RUF010 [*] Use explicit conversion flag
|
||||
|
|
||||
9 | f"{str(bla)}, {repr(bla)}, {ascii(bla)}" # RUF010
|
||||
10 |
|
||||
@@ -67,14 +67,14 @@ RUF010.py:11:4: RUF010 [*] Remove unnecessary `str` conversion
|
||||
12 |
|
||||
13 | f"{(str(bla))}, {(repr(bla))}, {(ascii(bla))}" # RUF010
|
||||
|
|
||||
= help: Remove `str` call
|
||||
= help: Replace with conversion flag
|
||||
|
||||
ℹ Fix
|
||||
8 8 |
|
||||
9 9 | f"{str(bla)}, {repr(bla)}, {ascii(bla)}" # RUF010
|
||||
10 10 |
|
||||
11 |-f"{str(d['a'])}, {repr(d['b'])}, {ascii(d['c'])}" # RUF010
|
||||
11 |+f"{d['a']}, {repr(d['b'])}, {ascii(d['c'])}" # RUF010
|
||||
11 |+f"{d['a']!s}, {repr(d['b'])}, {ascii(d['c'])}" # RUF010
|
||||
12 12 |
|
||||
13 13 | f"{(str(bla))}, {(repr(bla))}, {(ascii(bla))}" # RUF010
|
||||
14 14 |
|
||||
@@ -121,7 +121,7 @@ RUF010.py:11:35: RUF010 [*] Use explicit conversion flag
|
||||
13 13 | f"{(str(bla))}, {(repr(bla))}, {(ascii(bla))}" # RUF010
|
||||
14 14 |
|
||||
|
||||
RUF010.py:13:5: RUF010 [*] Remove unnecessary `str` conversion
|
||||
RUF010.py:13:5: RUF010 [*] Use explicit conversion flag
|
||||
|
|
||||
11 | f"{str(d['a'])}, {repr(d['b'])}, {ascii(d['c'])}" # RUF010
|
||||
12 |
|
||||
@@ -130,14 +130,14 @@ RUF010.py:13:5: RUF010 [*] Remove unnecessary `str` conversion
|
||||
14 |
|
||||
15 | f"{bla!s}, {(repr(bla))}, {(ascii(bla))}" # RUF010
|
||||
|
|
||||
= help: Remove `str` call
|
||||
= help: Replace with conversion flag
|
||||
|
||||
ℹ Fix
|
||||
10 10 |
|
||||
11 11 | f"{str(d['a'])}, {repr(d['b'])}, {ascii(d['c'])}" # RUF010
|
||||
12 12 |
|
||||
13 |-f"{(str(bla))}, {(repr(bla))}, {(ascii(bla))}" # RUF010
|
||||
13 |+f"{bla}, {(repr(bla))}, {(ascii(bla))}" # RUF010
|
||||
13 |+f"{bla!s}, {(repr(bla))}, {(ascii(bla))}" # RUF010
|
||||
14 14 |
|
||||
15 15 | f"{bla!s}, {(repr(bla))}, {(ascii(bla))}" # RUF010
|
||||
16 16 |
|
||||
@@ -184,27 +184,6 @@ RUF010.py:13:34: RUF010 [*] Use explicit conversion flag
|
||||
15 15 | f"{bla!s}, {(repr(bla))}, {(ascii(bla))}" # RUF010
|
||||
16 16 |
|
||||
|
||||
RUF010.py:15:4: RUF010 [*] Remove unnecessary conversion flag
|
||||
|
|
||||
13 | f"{(str(bla))}, {(repr(bla))}, {(ascii(bla))}" # RUF010
|
||||
14 |
|
||||
15 | f"{bla!s}, {(repr(bla))}, {(ascii(bla))}" # RUF010
|
||||
| ^^^ RUF010
|
||||
16 |
|
||||
17 | f"{foo(bla)}" # OK
|
||||
|
|
||||
= help: Remove conversion flag
|
||||
|
||||
ℹ Fix
|
||||
12 12 |
|
||||
13 13 | f"{(str(bla))}, {(repr(bla))}, {(ascii(bla))}" # RUF010
|
||||
14 14 |
|
||||
15 |-f"{bla!s}, {(repr(bla))}, {(ascii(bla))}" # RUF010
|
||||
15 |+f"{bla}, {(repr(bla))}, {(ascii(bla))}" # RUF010
|
||||
16 16 |
|
||||
17 17 | f"{foo(bla)}" # OK
|
||||
18 18 |
|
||||
|
||||
RUF010.py:15:14: RUF010 [*] Use explicit conversion flag
|
||||
|
|
||||
13 | f"{(str(bla))}, {(repr(bla))}, {(ascii(bla))}" # RUF010
|
||||
@@ -247,27 +226,6 @@ RUF010.py:15:29: RUF010 [*] Use explicit conversion flag
|
||||
17 17 | f"{foo(bla)}" # OK
|
||||
18 18 |
|
||||
|
||||
RUF010.py:21:4: RUF010 [*] Remove unnecessary conversion flag
|
||||
|
|
||||
19 | f"{str(bla, 'ascii')}, {str(bla, encoding='cp1255')}" # OK
|
||||
20 |
|
||||
21 | f"{bla!s} {[]!r} {'bar'!a}" # OK
|
||||
| ^^^ RUF010
|
||||
22 |
|
||||
23 | "Not an f-string {str(bla)}, {repr(bla)}, {ascii(bla)}" # OK
|
||||
|
|
||||
= help: Remove conversion flag
|
||||
|
||||
ℹ Fix
|
||||
18 18 |
|
||||
19 19 | f"{str(bla, 'ascii')}, {str(bla, encoding='cp1255')}" # OK
|
||||
20 20 |
|
||||
21 |-f"{bla!s} {[]!r} {'bar'!a}" # OK
|
||||
21 |+f"{bla} {[]!r} {'bar'!a}" # OK
|
||||
22 22 |
|
||||
23 23 | "Not an f-string {str(bla)}, {repr(bla)}, {ascii(bla)}" # OK
|
||||
24 24 |
|
||||
|
||||
RUF010.py:35:20: RUF010 [*] Use explicit conversion flag
|
||||
|
|
||||
33 | f"Member of tuple mismatches type at index {i}. Expected {of_shape_i}. Got "
|
||||
@@ -285,67 +243,5 @@ RUF010.py:35:20: RUF010 [*] Use explicit conversion flag
|
||||
35 |- f" that flows {repr(obj)} of type {type(obj)}.{additional_message}" # RUF010
|
||||
35 |+ f" that flows {obj!r} of type {type(obj)}.{additional_message}" # RUF010
|
||||
36 36 | )
|
||||
37 37 |
|
||||
38 38 |
|
||||
|
||||
RUF010.py:39:4: RUF010 [*] Remove unnecessary `str` conversion
|
||||
|
|
||||
39 | f"{str(bla)}" # RUF010
|
||||
| ^^^^^^^^ RUF010
|
||||
40 |
|
||||
41 | f"{str(bla):20}" # RUF010
|
||||
|
|
||||
= help: Remove `str` call
|
||||
|
||||
ℹ Fix
|
||||
36 36 | )
|
||||
37 37 |
|
||||
38 38 |
|
||||
39 |-f"{str(bla)}" # RUF010
|
||||
39 |+f"{bla}" # RUF010
|
||||
40 40 |
|
||||
41 41 | f"{str(bla):20}" # RUF010
|
||||
42 42 |
|
||||
|
||||
RUF010.py:41:4: RUF010 [*] Use explicit conversion flag
|
||||
|
|
||||
39 | f"{str(bla)}" # RUF010
|
||||
40 |
|
||||
41 | f"{str(bla):20}" # RUF010
|
||||
| ^^^^^^^^ RUF010
|
||||
42 |
|
||||
43 | f"{bla!s}" # RUF010
|
||||
|
|
||||
= help: Replace with conversion flag
|
||||
|
||||
ℹ Fix
|
||||
38 38 |
|
||||
39 39 | f"{str(bla)}" # RUF010
|
||||
40 40 |
|
||||
41 |-f"{str(bla):20}" # RUF010
|
||||
41 |+f"{bla!s:20}" # RUF010
|
||||
42 42 |
|
||||
43 43 | f"{bla!s}" # RUF010
|
||||
44 44 |
|
||||
|
||||
RUF010.py:43:4: RUF010 [*] Remove unnecessary conversion flag
|
||||
|
|
||||
41 | f"{str(bla):20}" # RUF010
|
||||
42 |
|
||||
43 | f"{bla!s}" # RUF010
|
||||
| ^^^ RUF010
|
||||
44 |
|
||||
45 | f"{bla!s:20}" # OK
|
||||
|
|
||||
= help: Remove conversion flag
|
||||
|
||||
ℹ Fix
|
||||
40 40 |
|
||||
41 41 | f"{str(bla):20}" # RUF010
|
||||
42 42 |
|
||||
43 |-f"{bla!s}" # RUF010
|
||||
43 |+f"{bla}" # RUF010
|
||||
44 44 |
|
||||
45 45 | f"{bla!s:20}" # OK
|
||||
|
||||
|
||||
|
||||
@@ -312,5 +312,7 @@ RUF013_0.py:186:12: RUF013 [*] PEP 484 prohibits implicit `Optional`
|
||||
186 |-def f(arg: Union[Annotated[int, ...], Union[str, bytes]] = None): # RUF011
|
||||
186 |+def f(arg: Union[Annotated[int, ...], Union[str, bytes]] | None = None): # RUF011
|
||||
187 187 | pass
|
||||
188 188 |
|
||||
189 189 |
|
||||
|
||||
|
||||
|
||||
@@ -16,8 +16,8 @@ use crate::fs;
|
||||
use crate::line_width::{LineLength, TabSize};
|
||||
use crate::rule_selector::RuleSelector;
|
||||
use crate::rules::{
|
||||
copyright, flake8_annotations, flake8_bandit, flake8_bugbear, flake8_builtins,
|
||||
flake8_comprehensions, flake8_errmsg, flake8_gettext, flake8_implicit_str_concat,
|
||||
flake8_annotations, flake8_bandit, flake8_bugbear, flake8_builtins, flake8_comprehensions,
|
||||
flake8_copyright, flake8_errmsg, flake8_gettext, flake8_implicit_str_concat,
|
||||
flake8_import_conventions, flake8_pytest_style, flake8_quotes, flake8_self,
|
||||
flake8_tidy_imports, flake8_type_checking, flake8_unused_arguments, isort, mccabe, pep8_naming,
|
||||
pycodestyle, pydocstyle, pyflakes, pylint,
|
||||
@@ -75,14 +75,14 @@ pub struct Configuration {
|
||||
pub flake8_bugbear: Option<flake8_bugbear::settings::Options>,
|
||||
pub flake8_builtins: Option<flake8_builtins::settings::Options>,
|
||||
pub flake8_comprehensions: Option<flake8_comprehensions::settings::Options>,
|
||||
pub copyright: Option<copyright::settings::Options>,
|
||||
pub flake8_copyright: Option<flake8_copyright::settings::Options>,
|
||||
pub flake8_errmsg: Option<flake8_errmsg::settings::Options>,
|
||||
pub flake8_gettext: Option<flake8_gettext::settings::Options>,
|
||||
pub flake8_implicit_str_concat: Option<flake8_implicit_str_concat::settings::Options>,
|
||||
pub flake8_import_conventions: Option<flake8_import_conventions::settings::Options>,
|
||||
pub flake8_pytest_style: Option<flake8_pytest_style::settings::Options>,
|
||||
pub flake8_quotes: Option<flake8_quotes::settings::Options>,
|
||||
pub flake8_self: Option<flake8_self::settings::Options>,
|
||||
pub flake8_gettext: Option<flake8_gettext::settings::Options>,
|
||||
pub flake8_tidy_imports: Option<flake8_tidy_imports::options::Options>,
|
||||
pub flake8_type_checking: Option<flake8_type_checking::settings::Options>,
|
||||
pub flake8_unused_arguments: Option<flake8_unused_arguments::settings::Options>,
|
||||
@@ -229,7 +229,7 @@ impl Configuration {
|
||||
flake8_bugbear: options.flake8_bugbear,
|
||||
flake8_builtins: options.flake8_builtins,
|
||||
flake8_comprehensions: options.flake8_comprehensions,
|
||||
copyright: options.copyright,
|
||||
flake8_copyright: options.flake8_copyright,
|
||||
flake8_errmsg: options.flake8_errmsg,
|
||||
flake8_gettext: options.flake8_gettext,
|
||||
flake8_implicit_str_concat: options.flake8_implicit_str_concat,
|
||||
@@ -308,7 +308,7 @@ impl Configuration {
|
||||
flake8_comprehensions: self
|
||||
.flake8_comprehensions
|
||||
.combine(config.flake8_comprehensions),
|
||||
copyright: self.copyright.combine(config.copyright),
|
||||
flake8_copyright: self.flake8_copyright.combine(config.flake8_copyright),
|
||||
flake8_errmsg: self.flake8_errmsg.combine(config.flake8_errmsg),
|
||||
flake8_gettext: self.flake8_gettext.combine(config.flake8_gettext),
|
||||
flake8_implicit_str_concat: self
|
||||
|
||||
@@ -10,8 +10,8 @@ use crate::line_width::{LineLength, TabSize};
|
||||
use crate::registry::Linter;
|
||||
use crate::rule_selector::{prefix_to_selector, RuleSelector};
|
||||
use crate::rules::{
|
||||
copyright, flake8_annotations, flake8_bandit, flake8_bugbear, flake8_builtins,
|
||||
flake8_comprehensions, flake8_errmsg, flake8_gettext, flake8_implicit_str_concat,
|
||||
flake8_annotations, flake8_bandit, flake8_bugbear, flake8_builtins, flake8_comprehensions,
|
||||
flake8_copyright, flake8_errmsg, flake8_gettext, flake8_implicit_str_concat,
|
||||
flake8_import_conventions, flake8_pytest_style, flake8_quotes, flake8_self,
|
||||
flake8_tidy_imports, flake8_type_checking, flake8_unused_arguments, isort, mccabe, pep8_naming,
|
||||
pycodestyle, pydocstyle, pyflakes, pylint,
|
||||
@@ -96,7 +96,7 @@ impl Default for Settings {
|
||||
flake8_bugbear: flake8_bugbear::settings::Settings::default(),
|
||||
flake8_builtins: flake8_builtins::settings::Settings::default(),
|
||||
flake8_comprehensions: flake8_comprehensions::settings::Settings::default(),
|
||||
copyright: copyright::settings::Settings::default(),
|
||||
flake8_copyright: flake8_copyright::settings::Settings::default(),
|
||||
flake8_errmsg: flake8_errmsg::settings::Settings::default(),
|
||||
flake8_implicit_str_concat: flake8_implicit_str_concat::settings::Settings::default(),
|
||||
flake8_import_conventions: flake8_import_conventions::settings::Settings::default(),
|
||||
|
||||
@@ -16,8 +16,8 @@ use ruff_macros::CacheKey;
|
||||
use crate::registry::{Rule, RuleNamespace, RuleSet, INCOMPATIBLE_CODES};
|
||||
use crate::rule_selector::{RuleSelector, Specificity};
|
||||
use crate::rules::{
|
||||
copyright, flake8_annotations, flake8_bandit, flake8_bugbear, flake8_builtins,
|
||||
flake8_comprehensions, flake8_errmsg, flake8_gettext, flake8_implicit_str_concat,
|
||||
flake8_annotations, flake8_bandit, flake8_bugbear, flake8_builtins, flake8_comprehensions,
|
||||
flake8_copyright, flake8_errmsg, flake8_gettext, flake8_implicit_str_concat,
|
||||
flake8_import_conventions, flake8_pytest_style, flake8_quotes, flake8_self,
|
||||
flake8_tidy_imports, flake8_type_checking, flake8_unused_arguments, isort, mccabe, pep8_naming,
|
||||
pycodestyle, pydocstyle, pyflakes, pylint,
|
||||
@@ -112,11 +112,11 @@ pub struct Settings {
|
||||
pub flake8_bugbear: flake8_bugbear::settings::Settings,
|
||||
pub flake8_builtins: flake8_builtins::settings::Settings,
|
||||
pub flake8_comprehensions: flake8_comprehensions::settings::Settings,
|
||||
pub copyright: copyright::settings::Settings,
|
||||
pub flake8_copyright: flake8_copyright::settings::Settings,
|
||||
pub flake8_errmsg: flake8_errmsg::settings::Settings,
|
||||
pub flake8_gettext: flake8_gettext::settings::Settings,
|
||||
pub flake8_implicit_str_concat: flake8_implicit_str_concat::settings::Settings,
|
||||
pub flake8_import_conventions: flake8_import_conventions::settings::Settings,
|
||||
pub flake8_gettext: flake8_gettext::settings::Settings,
|
||||
pub flake8_pytest_style: flake8_pytest_style::settings::Settings,
|
||||
pub flake8_quotes: flake8_quotes::settings::Settings,
|
||||
pub flake8_self: flake8_self::settings::Settings,
|
||||
@@ -210,9 +210,9 @@ impl Settings {
|
||||
.flake8_comprehensions
|
||||
.map(flake8_comprehensions::settings::Settings::from)
|
||||
.unwrap_or_default(),
|
||||
copyright: config
|
||||
.copyright
|
||||
.map(copyright::settings::Settings::try_from)
|
||||
flake8_copyright: config
|
||||
.flake8_copyright
|
||||
.map(flake8_copyright::settings::Settings::try_from)
|
||||
.transpose()?
|
||||
.unwrap_or_default(),
|
||||
flake8_errmsg: config
|
||||
|
||||
@@ -8,8 +8,8 @@ use ruff_macros::ConfigurationOptions;
|
||||
use crate::line_width::{LineLength, TabSize};
|
||||
use crate::rule_selector::RuleSelector;
|
||||
use crate::rules::{
|
||||
copyright, flake8_annotations, flake8_bandit, flake8_bugbear, flake8_builtins,
|
||||
flake8_comprehensions, flake8_errmsg, flake8_gettext, flake8_implicit_str_concat,
|
||||
flake8_annotations, flake8_bandit, flake8_bugbear, flake8_builtins, flake8_comprehensions,
|
||||
flake8_copyright, flake8_errmsg, flake8_gettext, flake8_implicit_str_concat,
|
||||
flake8_import_conventions, flake8_pytest_style, flake8_quotes, flake8_self,
|
||||
flake8_tidy_imports, flake8_type_checking, flake8_unused_arguments, isort, mccabe, pep8_naming,
|
||||
pycodestyle, pydocstyle, pyflakes, pylint,
|
||||
@@ -499,7 +499,7 @@ pub struct Options {
|
||||
pub flake8_comprehensions: Option<flake8_comprehensions::settings::Options>,
|
||||
#[option_group]
|
||||
/// Options for the `copyright` plugin.
|
||||
pub copyright: Option<copyright::settings::Options>,
|
||||
pub flake8_copyright: Option<flake8_copyright::settings::Options>,
|
||||
#[option_group]
|
||||
/// Options for the `flake8-errmsg` plugin.
|
||||
pub flake8_errmsg: Option<flake8_errmsg::settings::Options>,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "ruff_cli"
|
||||
version = "0.0.273"
|
||||
version = "0.0.274"
|
||||
publish = false
|
||||
authors = { workspace = true }
|
||||
edition = { workspace = true }
|
||||
|
||||
@@ -7,6 +7,7 @@ use std::time::Instant;
|
||||
use anyhow::Result;
|
||||
use colored::Colorize;
|
||||
use ignore::Error;
|
||||
use itertools::Itertools;
|
||||
use log::{debug, error, warn};
|
||||
#[cfg(not(target_family = "wasm"))]
|
||||
use rayon::prelude::*;
|
||||
@@ -80,8 +81,10 @@ pub(crate) fn run(
|
||||
// Load the caches.
|
||||
let caches = bool::from(cache).then(|| {
|
||||
package_roots
|
||||
.par_iter()
|
||||
.map(|(package_root, _)| {
|
||||
.values()
|
||||
.flatten()
|
||||
.dedup()
|
||||
.map(|package_root| {
|
||||
let settings = resolver.resolve_all(package_root, pyproject_config);
|
||||
let cache = Cache::open(
|
||||
&settings.cli.cache_dir,
|
||||
@@ -107,9 +110,7 @@ pub(crate) fn run(
|
||||
|
||||
let settings = resolver.resolve_all(path, pyproject_config);
|
||||
let package_root = package.unwrap_or_else(|| path.parent().unwrap_or(path));
|
||||
let cache = caches
|
||||
.as_ref()
|
||||
.map(|caches| caches.get(&package_root).unwrap());
|
||||
let cache = caches.as_ref().and_then(|caches| caches.get(&package_root));
|
||||
|
||||
lint_path(path, package, settings, cache, noqa, autofix).map_err(|e| {
|
||||
(Some(path.to_owned()), {
|
||||
|
||||
@@ -3680,7 +3680,7 @@ impl AnyNodeRef<'_> {
|
||||
|
||||
/// Compares two any node refs by their pointers (referential equality).
|
||||
pub fn ptr_eq(self, other: AnyNodeRef) -> bool {
|
||||
self.as_ptr().eq(&other.as_ptr())
|
||||
self.as_ptr().eq(&other.as_ptr()) && self.kind() == other.kind()
|
||||
}
|
||||
|
||||
/// Returns the node's [`kind`](NodeKind) that has no data associated and is [`Copy`].
|
||||
|
||||
@@ -90,3 +90,10 @@ else:
|
||||
# Regression test for https://github.com/python/cpython/blob/7199584ac8632eab57612f595a7162ab8d2ebbc0/Lib/warnings.py#L513
|
||||
def f(arg1=1, *, kwonlyarg1, kwonlyarg2=2):
|
||||
pass
|
||||
|
||||
|
||||
# Regression test for https://github.com/astral-sh/ruff/issues/5176#issuecomment-1598171989
|
||||
def foo(
|
||||
b=3 + 2 # comment
|
||||
):
|
||||
...
|
||||
|
||||
@@ -63,7 +63,7 @@ pub fn format_and_debug_print(input: &str, cli: &Cli) -> Result<String> {
|
||||
}
|
||||
if cli.print_comments {
|
||||
println!(
|
||||
"{:?}",
|
||||
"{:#?}",
|
||||
formatted.context().comments().debug(SourceCode::new(input))
|
||||
);
|
||||
}
|
||||
|
||||
@@ -627,17 +627,7 @@ fn handle_positional_only_arguments_separator_comment<'a>(
|
||||
};
|
||||
|
||||
let is_last_positional_argument =
|
||||
// If the preceding node is the identifier for the last positional argument (`a`).
|
||||
// ```python
|
||||
// def test(a, /, b): pass
|
||||
// ```
|
||||
are_same_optional(last_argument_or_default, arguments.posonlyargs.last().map(|arg| &arg.def))
|
||||
// If the preceding node is the default for the last positional argument (`10`).
|
||||
// ```python
|
||||
// def test(a=10, /, b): pass
|
||||
// ```
|
||||
|| are_same_optional(last_argument_or_default, arguments
|
||||
.posonlyargs.last().and_then(|arg| arg.default.as_deref()));
|
||||
are_same_optional(last_argument_or_default, arguments.posonlyargs.last());
|
||||
|
||||
if !is_last_positional_argument {
|
||||
return CommentPlacement::Default(comment);
|
||||
|
||||
@@ -19,9 +19,9 @@ expression: comments.debug(test_case.source_code)
|
||||
"trailing": [],
|
||||
},
|
||||
Node {
|
||||
kind: Arg,
|
||||
range: 90..91,
|
||||
source: `b`,
|
||||
kind: ArgWithDefault,
|
||||
range: 90..94,
|
||||
source: `b=20`,
|
||||
}: {
|
||||
"leading": [
|
||||
SourceComment {
|
||||
|
||||
@@ -24,9 +24,9 @@ expression: comments.debug(test_case.source_code)
|
||||
"trailing": [],
|
||||
},
|
||||
Node {
|
||||
kind: ExprConstant,
|
||||
range: 17..19,
|
||||
source: `10`,
|
||||
kind: ArgWithDefault,
|
||||
range: 15..19,
|
||||
source: `a=10`,
|
||||
}: {
|
||||
"leading": [],
|
||||
"dangling": [],
|
||||
@@ -39,9 +39,9 @@ expression: comments.debug(test_case.source_code)
|
||||
],
|
||||
},
|
||||
Node {
|
||||
kind: Arg,
|
||||
range: 173..174,
|
||||
source: `b`,
|
||||
kind: ArgWithDefault,
|
||||
range: 173..177,
|
||||
source: `b=20`,
|
||||
}: {
|
||||
"leading": [
|
||||
SourceComment {
|
||||
|
||||
@@ -24,7 +24,7 @@ expression: comments.debug(test_case.source_code)
|
||||
"trailing": [],
|
||||
},
|
||||
Node {
|
||||
kind: Arg,
|
||||
kind: ArgWithDefault,
|
||||
range: 15..16,
|
||||
source: `a`,
|
||||
}: {
|
||||
@@ -39,7 +39,7 @@ expression: comments.debug(test_case.source_code)
|
||||
],
|
||||
},
|
||||
Node {
|
||||
kind: Arg,
|
||||
kind: ArgWithDefault,
|
||||
range: 166..167,
|
||||
source: `b`,
|
||||
}: {
|
||||
|
||||
@@ -24,7 +24,7 @@ expression: comments.debug(test_case.source_code)
|
||||
"trailing": [],
|
||||
},
|
||||
Node {
|
||||
kind: Arg,
|
||||
kind: ArgWithDefault,
|
||||
range: 15..16,
|
||||
source: `a`,
|
||||
}: {
|
||||
|
||||
@@ -24,7 +24,7 @@ expression: comments.debug(test_case.source_code)
|
||||
"trailing": [],
|
||||
},
|
||||
Node {
|
||||
kind: Arg,
|
||||
kind: ArgWithDefault,
|
||||
range: 15..16,
|
||||
source: `a`,
|
||||
}: {
|
||||
@@ -39,7 +39,7 @@ expression: comments.debug(test_case.source_code)
|
||||
],
|
||||
},
|
||||
Node {
|
||||
kind: Arg,
|
||||
kind: ArgWithDefault,
|
||||
range: 166..167,
|
||||
source: `b`,
|
||||
}: {
|
||||
|
||||
@@ -4,7 +4,7 @@ expression: comments.debug(test_case.source_code)
|
||||
---
|
||||
{
|
||||
Node {
|
||||
kind: Arg,
|
||||
kind: ArgWithDefault,
|
||||
range: 15..16,
|
||||
source: `a`,
|
||||
}: {
|
||||
|
||||
@@ -236,6 +236,13 @@ impl<'ast> PreorderVisitor<'ast> for CommentsVisitor<'ast> {
|
||||
self.finish_node(arg);
|
||||
}
|
||||
|
||||
fn visit_arg_with_default(&mut self, arg_with_default: &'ast ArgWithDefault) {
|
||||
if self.start_node(arg_with_default).is_traverse() {
|
||||
walk_arg_with_default(self, arg_with_default);
|
||||
}
|
||||
self.finish_node(arg_with_default);
|
||||
}
|
||||
|
||||
fn visit_keyword(&mut self, keyword: &'ast Keyword) {
|
||||
if self.start_node(keyword).is_traverse() {
|
||||
walk_keyword(self, keyword);
|
||||
|
||||
@@ -411,10 +411,12 @@ Formatted twice:
|
||||
#[test]
|
||||
fn quick_test() {
|
||||
let src = r#"
|
||||
def test(): ...
|
||||
|
||||
# Comment
|
||||
def with_leading_comment(): ...
|
||||
def foo(
|
||||
b=3
|
||||
+ 2 # comment
|
||||
):
|
||||
...
|
||||
"#;
|
||||
// Tokenize once
|
||||
let mut tokens = Vec::new();
|
||||
@@ -437,10 +439,10 @@ def with_leading_comment(): ...
|
||||
// Use `dbg_write!(f, []) instead of `write!(f, [])` in your formatting code to print some IR
|
||||
// inside of a `Format` implementation
|
||||
// use ruff_formatter::FormatContext;
|
||||
// formatted
|
||||
// dbg!(formatted
|
||||
// .document()
|
||||
// .display(formatted.context().source_code());
|
||||
|
||||
// .display(formatted.context().source_code()));
|
||||
//
|
||||
// dbg!(formatted
|
||||
// .context()
|
||||
// .comments()
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
use rustpython_parser::ast::ArgWithDefault;
|
||||
|
||||
use ruff_formatter::write;
|
||||
use rustpython_parser::ast::ArgWithDefault;
|
||||
|
||||
use crate::prelude::*;
|
||||
use crate::FormatNodeRule;
|
||||
@@ -20,7 +19,7 @@ impl FormatNodeRule<ArgWithDefault> for FormatArgWithDefault {
|
||||
|
||||
if let Some(default) = default {
|
||||
let space = def.annotation.is_some().then_some(space());
|
||||
write!(f, [space, text("="), space, default.format()])?;
|
||||
write!(f, [space, text("="), space, group(&default.format())])?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
|
||||
@@ -34,14 +34,9 @@ impl FormatNodeRule<Arguments> for FormatArguments {
|
||||
let mut last_node: Option<AnyNodeRef> = None;
|
||||
|
||||
for arg_with_default in posonlyargs {
|
||||
joiner.entry(&arg_with_default.into_format());
|
||||
joiner.entry(&arg_with_default.format());
|
||||
|
||||
last_node = Some(
|
||||
arg_with_default
|
||||
.default
|
||||
.as_deref()
|
||||
.map_or_else(|| (&arg_with_default.def).into(), AnyNodeRef::from),
|
||||
);
|
||||
last_node = Some(arg_with_default.into());
|
||||
}
|
||||
|
||||
if !posonlyargs.is_empty() {
|
||||
@@ -49,14 +44,9 @@ impl FormatNodeRule<Arguments> for FormatArguments {
|
||||
}
|
||||
|
||||
for arg_with_default in args {
|
||||
joiner.entry(&arg_with_default.into_format());
|
||||
joiner.entry(&arg_with_default.format());
|
||||
|
||||
last_node = Some(
|
||||
arg_with_default
|
||||
.default
|
||||
.as_deref()
|
||||
.map_or_else(|| (&arg_with_default.def).into(), AnyNodeRef::from),
|
||||
);
|
||||
last_node = Some(arg_with_default.into());
|
||||
}
|
||||
|
||||
// kw only args need either a `*args` ahead of them capturing all var args or a `*`
|
||||
@@ -74,14 +64,9 @@ impl FormatNodeRule<Arguments> for FormatArguments {
|
||||
}
|
||||
|
||||
for arg_with_default in kwonlyargs {
|
||||
joiner.entry(&arg_with_default.into_format());
|
||||
joiner.entry(&arg_with_default.format());
|
||||
|
||||
last_node = Some(
|
||||
arg_with_default
|
||||
.default
|
||||
.as_deref()
|
||||
.map_or_else(|| (&arg_with_default.def).into(), AnyNodeRef::from),
|
||||
);
|
||||
last_node = Some(arg_with_default.into());
|
||||
}
|
||||
|
||||
if let Some(kwarg) = kwarg {
|
||||
|
||||
@@ -96,6 +96,13 @@ else:
|
||||
# Regression test for https://github.com/python/cpython/blob/7199584ac8632eab57612f595a7162ab8d2ebbc0/Lib/warnings.py#L513
|
||||
def f(arg1=1, *, kwonlyarg1, kwonlyarg2=2):
|
||||
pass
|
||||
|
||||
|
||||
# Regression test for https://github.com/astral-sh/ruff/issues/5176#issuecomment-1598171989
|
||||
def foo(
|
||||
b=3 + 2 # comment
|
||||
):
|
||||
...
|
||||
```
|
||||
|
||||
|
||||
@@ -223,6 +230,13 @@ else:
|
||||
# Regression test for https://github.com/python/cpython/blob/7199584ac8632eab57612f595a7162ab8d2ebbc0/Lib/warnings.py#L513
|
||||
def f(arg1=1, *, kwonlyarg1, kwonlyarg2=2):
|
||||
pass
|
||||
|
||||
|
||||
# Regression test for https://github.com/astral-sh/ruff/issues/5176#issuecomment-1598171989
|
||||
def foo(
|
||||
b=3 + 2, # comment
|
||||
):
|
||||
...
|
||||
```
|
||||
|
||||
|
||||
|
||||
@@ -9,8 +9,8 @@ use ruff::line_width::{LineLength, TabSize};
|
||||
use ruff::linter::{check_path, LinterResult};
|
||||
use ruff::registry::AsRule;
|
||||
use ruff::rules::{
|
||||
copyright, flake8_annotations, flake8_bandit, flake8_bugbear, flake8_builtins,
|
||||
flake8_comprehensions, flake8_errmsg, flake8_gettext, flake8_implicit_str_concat,
|
||||
flake8_annotations, flake8_bandit, flake8_bugbear, flake8_builtins, flake8_comprehensions,
|
||||
flake8_copyright, flake8_errmsg, flake8_gettext, flake8_implicit_str_concat,
|
||||
flake8_import_conventions, flake8_pytest_style, flake8_quotes, flake8_self,
|
||||
flake8_tidy_imports, flake8_type_checking, flake8_unused_arguments, isort, mccabe, pep8_naming,
|
||||
pycodestyle, pydocstyle, pyflakes, pylint,
|
||||
@@ -138,11 +138,8 @@ pub fn defaultSettings() -> Result<JsValue, JsValue> {
|
||||
flake8_bugbear: Some(flake8_bugbear::settings::Settings::default().into()),
|
||||
flake8_builtins: Some(flake8_builtins::settings::Settings::default().into()),
|
||||
flake8_comprehensions: Some(flake8_comprehensions::settings::Settings::default().into()),
|
||||
copyright: Some(copyright::settings::Settings::default().into()),
|
||||
flake8_copyright: Some(flake8_copyright::settings::Settings::default().into()),
|
||||
flake8_errmsg: Some(flake8_errmsg::settings::Settings::default().into()),
|
||||
flake8_pytest_style: Some(flake8_pytest_style::settings::Settings::default().into()),
|
||||
flake8_quotes: Some(flake8_quotes::settings::Settings::default().into()),
|
||||
flake8_self: Some(flake8_self::settings::Settings::default().into()),
|
||||
flake8_gettext: Some(flake8_gettext::settings::Settings::default().into()),
|
||||
flake8_implicit_str_concat: Some(
|
||||
flake8_implicit_str_concat::settings::Settings::default().into(),
|
||||
@@ -150,6 +147,9 @@ pub fn defaultSettings() -> Result<JsValue, JsValue> {
|
||||
flake8_import_conventions: Some(
|
||||
flake8_import_conventions::settings::Settings::default().into(),
|
||||
),
|
||||
flake8_pytest_style: Some(flake8_pytest_style::settings::Settings::default().into()),
|
||||
flake8_quotes: Some(flake8_quotes::settings::Settings::default().into()),
|
||||
flake8_self: Some(flake8_self::settings::Settings::default().into()),
|
||||
flake8_tidy_imports: Some(flake8_tidy_imports::settings::Settings::default().into()),
|
||||
flake8_type_checking: Some(flake8_type_checking::settings::Settings::default().into()),
|
||||
flake8_unused_arguments: Some(
|
||||
|
||||
@@ -242,7 +242,7 @@ This tutorial has focused on Ruff's command-line interface, but Ruff can also be
|
||||
```yaml
|
||||
- repo: https://github.com/astral-sh/ruff-pre-commit
|
||||
# Ruff version.
|
||||
rev: v0.0.273
|
||||
rev: v0.0.274
|
||||
hooks:
|
||||
- id: ruff
|
||||
```
|
||||
|
||||
@@ -22,7 +22,7 @@ Ruff can also be used as a [pre-commit](https://pre-commit.com) hook:
|
||||
```yaml
|
||||
- repo: https://github.com/astral-sh/ruff-pre-commit
|
||||
# Ruff version.
|
||||
rev: v0.0.273
|
||||
rev: v0.0.274
|
||||
hooks:
|
||||
- id: ruff
|
||||
```
|
||||
@@ -32,7 +32,7 @@ Or, to enable autofix:
|
||||
```yaml
|
||||
- repo: https://github.com/astral-sh/ruff-pre-commit
|
||||
# Ruff version.
|
||||
rev: v0.0.273
|
||||
rev: v0.0.274
|
||||
hooks:
|
||||
- id: ruff
|
||||
args: [ --fix, --exit-non-zero-on-fix ]
|
||||
|
||||
@@ -17,6 +17,7 @@ if [ ! -d corpus/ruff_fix_validity ]; then
|
||||
if [[ $REPLY =~ ^[Yy]$ ]]; then
|
||||
curl -L 'https://zenodo.org/record/3628784/files/python-corpus.tar.gz?download=1' | tar xz
|
||||
fi
|
||||
curl -L 'https://github.com/python/cpython/archive/refs/tags/v3.12.0b2.tar.gz' | tar xz
|
||||
cp -r "../../../crates/ruff/resources/test" .
|
||||
cd -
|
||||
cargo fuzz cmin -s none ruff_fix_validity
|
||||
|
||||
@@ -6,9 +6,7 @@ SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )
|
||||
cd "$SCRIPT_DIR"
|
||||
|
||||
cd corpus/ruff_fix_validity
|
||||
if [[ $REPLY =~ ^[Yy]$ ]]; then
|
||||
curl -L 'https://zenodo.org/record/3628784/files/python-corpus.tar.gz?download=1' | tar xz
|
||||
fi
|
||||
curl -L 'https://github.com/python/cpython/archive/refs/tags/v3.12.0b2.tar.gz' | tar xz
|
||||
cp -r "../../../crates/ruff/resources/test" .
|
||||
cd -
|
||||
cargo fuzz cmin -s none ruff_fix_validity
|
||||
|
||||
@@ -5,7 +5,7 @@ build-backend = "maturin"
|
||||
|
||||
[project]
|
||||
name = "ruff"
|
||||
version = "0.0.273"
|
||||
version = "0.0.274"
|
||||
description = "An extremely fast Python linter, written in Rust."
|
||||
authors = [{ name = "Charlie Marsh", email = "charlie.r.marsh@gmail.com" }]
|
||||
maintainers = [{ name = "Charlie Marsh", email = "charlie.r.marsh@gmail.com" }]
|
||||
|
||||
80
ruff.schema.json
generated
80
ruff.schema.json
generated
@@ -32,17 +32,6 @@
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"copyright": {
|
||||
"description": "Options for the `copyright` plugin.",
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/CopyrightOptions"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"dummy-variable-rgx": {
|
||||
"description": "A regular expression used to identify \"dummy\" variables, or those which should be ignored when enforcing (e.g.) unused-variable rules. The default expression matches `_`, `__`, and `_var`, but not `_var_`.",
|
||||
"type": [
|
||||
@@ -209,6 +198,17 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
"flake8-copyright": {
|
||||
"description": "Options for the `copyright` plugin.",
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/Flake8CopyrightOptions"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"flake8-errmsg": {
|
||||
"description": "Options for the `flake8-errmsg` plugin.",
|
||||
"anyOf": [
|
||||
@@ -631,35 +631,6 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
"CopyrightOptions": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"author": {
|
||||
"description": "Author to enforce within the copyright notice. If provided, the author must be present immediately following the copyright notice.",
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"min-file-size": {
|
||||
"description": "A minimum file size (in bytes) required for a copyright notice to be enforced. By default, all files are validated.",
|
||||
"type": [
|
||||
"integer",
|
||||
"null"
|
||||
],
|
||||
"format": "uint",
|
||||
"minimum": 0.0
|
||||
},
|
||||
"notice-rgx": {
|
||||
"description": "The regular expression used to match the copyright notice, compiled with the [`regex`](https://docs.rs/regex/latest/regex/) crate.\n\nDefaults to `(?i)Copyright\\s+(\\(C\\)\\s+)?\\d{4}(-\\d{4})*`, which matches the following: - `Copyright 2023` - `Copyright (C) 2023` - `Copyright 2021-2023` - `Copyright (C) 2021-2023`",
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
"Flake8AnnotationsOptions": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
@@ -779,6 +750,35 @@
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
"Flake8CopyrightOptions": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"author": {
|
||||
"description": "Author to enforce within the copyright notice. If provided, the author must be present immediately following the copyright notice.",
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"min-file-size": {
|
||||
"description": "A minimum file size (in bytes) required for a copyright notice to be enforced. By default, all files are validated.",
|
||||
"type": [
|
||||
"integer",
|
||||
"null"
|
||||
],
|
||||
"format": "uint",
|
||||
"minimum": 0.0
|
||||
},
|
||||
"notice-rgx": {
|
||||
"description": "The regular expression used to match the copyright notice, compiled with the [`regex`](https://docs.rs/regex/latest/regex/) crate.\n\nDefaults to `(?i)Copyright\\s+(\\(C\\)\\s+)?\\d{4}(-\\d{4})*`, which matches the following: - `Copyright 2023` - `Copyright (C) 2023` - `Copyright 2021-2023` - `Copyright (C) 2021-2023`",
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
"Flake8ErrMsgOptions": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
|
||||
Reference in New Issue
Block a user