Compare commits
114 Commits
brent/docu
...
cjm/callab
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0fc9e5e0e9 | ||
|
|
7f7fb50a43 | ||
|
|
0b6bd9a735 | ||
|
|
c790aa7474 | ||
|
|
298e2dcb4e | ||
|
|
44256deae3 | ||
|
|
06a02fc46e | ||
|
|
2897d498fd | ||
|
|
4e3dd58815 | ||
|
|
26c847c229 | ||
|
|
2614be36cc | ||
|
|
a914071640 | ||
|
|
483f34207b | ||
|
|
42185b643b | ||
|
|
94b4dd86c0 | ||
|
|
dfcdbcffec | ||
|
|
f8a5d04296 | ||
|
|
cba45acd86 | ||
|
|
1dd3cf0e58 | ||
|
|
d9429754b9 | ||
|
|
7f4893d200 | ||
|
|
88eb5eba22 | ||
|
|
63c75d85d0 | ||
|
|
358185b5e2 | ||
|
|
019db2a22e | ||
|
|
ccb03d3b23 | ||
|
|
da31e138b4 | ||
|
|
7e2ea8bd69 | ||
|
|
1f34f43745 | ||
|
|
649c7bce58 | ||
|
|
92894d3712 | ||
|
|
5a8a9500b9 | ||
|
|
49ca97a20e | ||
|
|
d223f64af1 | ||
|
|
a4a3aff8d6 | ||
|
|
bdaf8e5812 | ||
|
|
e583cb7682 | ||
|
|
86271d605d | ||
|
|
8655598901 | ||
|
|
b9ecab1f24 | ||
|
|
3c811c19d4 | ||
|
|
ddcd76c544 | ||
|
|
8871fddaf9 | ||
|
|
8069064aca | ||
|
|
068eb1f500 | ||
|
|
e906526578 | ||
|
|
25a6690cdb | ||
|
|
99ec0be478 | ||
|
|
c94fbe20a2 | ||
|
|
690310cea3 | ||
|
|
e476624ef2 | ||
|
|
2fd7a7d944 | ||
|
|
2950af4fd9 | ||
|
|
73acf0a926 | ||
|
|
c85f102e70 | ||
|
|
4bcca58c3a | ||
|
|
c6a4e1c8ad | ||
|
|
f624bfdf63 | ||
|
|
bfde3e41a7 | ||
|
|
a892be3124 | ||
|
|
b1ede8885b | ||
|
|
4f7ad7bbc9 | ||
|
|
9a3786179d | ||
|
|
f82b3f1eff | ||
|
|
f23ae75b5d | ||
|
|
f29200c789 | ||
|
|
72e0c32a99 | ||
|
|
81fc51e197 | ||
|
|
b3e4855230 | ||
|
|
c56d5cc24b | ||
|
|
22c7fc4516 | ||
|
|
ecb9c1301b | ||
|
|
c60560f39d | ||
|
|
61381522e4 | ||
|
|
d47e9a60df | ||
|
|
a372e63b2c | ||
|
|
b84a35f22f | ||
|
|
657685f731 | ||
|
|
056258c767 | ||
|
|
db488e3cf7 | ||
|
|
c74eb12db4 | ||
|
|
c0dc6cfa61 | ||
|
|
8c7e20abd6 | ||
|
|
3384392747 | ||
|
|
54a4f2ec58 | ||
|
|
b314119835 | ||
|
|
1e33d25d1c | ||
|
|
b90cdfc2f7 | ||
|
|
94aca37ca8 | ||
|
|
75e9d66d4b | ||
|
|
3bcca62472 | ||
|
|
85e6143e07 | ||
|
|
77ce24a5bf | ||
|
|
db5834dfd7 | ||
|
|
2e46c8de06 | ||
|
|
d3fd988337 | ||
|
|
a0f64bd0ae | ||
|
|
beb2956a14 | ||
|
|
58c67fd4cd | ||
|
|
a303b7a8aa | ||
|
|
30452586ad | ||
|
|
7bbf839325 | ||
|
|
957304ec15 | ||
|
|
d88120b187 | ||
|
|
2b949b3e67 | ||
|
|
2c6267436f | ||
|
|
fedc75463b | ||
|
|
9950c126fe | ||
|
|
b7fb6797b4 | ||
|
|
fc2f17508b | ||
|
|
20ecb561bb | ||
|
|
3b509e9015 | ||
|
|
998b20f078 | ||
|
|
544dafa66e |
1
.github/mypy-primer-ty.toml
vendored
1
.github/mypy-primer-ty.toml
vendored
@@ -4,6 +4,5 @@
|
||||
# Enable off-by-default rules.
|
||||
[rules]
|
||||
possibly-unresolved-reference = "warn"
|
||||
possibly-missing-import = "warn"
|
||||
unused-ignore-comment = "warn"
|
||||
division-by-zero = "warn"
|
||||
|
||||
2
.github/workflows/ty-ecosystem-analyzer.yaml
vendored
2
.github/workflows/ty-ecosystem-analyzer.yaml
vendored
@@ -67,7 +67,7 @@ jobs:
|
||||
|
||||
cd ..
|
||||
|
||||
uv tool install "git+https://github.com/astral-sh/ecosystem-analyzer@2e1816eac09c90140b1ba51d19afc5f59da460f5"
|
||||
uv tool install "git+https://github.com/astral-sh/ecosystem-analyzer@55df3c868f3fa9ab34cff0498dd6106722aac205"
|
||||
|
||||
ecosystem-analyzer \
|
||||
--repository ruff \
|
||||
|
||||
2
.github/workflows/ty-ecosystem-report.yaml
vendored
2
.github/workflows/ty-ecosystem-report.yaml
vendored
@@ -52,7 +52,7 @@ jobs:
|
||||
|
||||
cd ..
|
||||
|
||||
uv tool install "git+https://github.com/astral-sh/ecosystem-analyzer@2e1816eac09c90140b1ba51d19afc5f59da460f5"
|
||||
uv tool install "git+https://github.com/astral-sh/ecosystem-analyzer@55df3c868f3fa9ab34cff0498dd6106722aac205"
|
||||
|
||||
ecosystem-analyzer \
|
||||
--verbose \
|
||||
|
||||
49
CHANGELOG.md
49
CHANGELOG.md
@@ -1,54 +1,5 @@
|
||||
# Changelog
|
||||
|
||||
## 0.14.10
|
||||
|
||||
Released on 2025-12-18.
|
||||
|
||||
### Preview features
|
||||
|
||||
- [formatter] Fluent formatting of method chains ([#21369](https://github.com/astral-sh/ruff/pull/21369))
|
||||
- [formatter] Keep lambda parameters on one line and parenthesize the body if it expands ([#21385](https://github.com/astral-sh/ruff/pull/21385))
|
||||
- \[`flake8-implicit-str-concat`\] New rule to prevent implicit string concatenation in collections (`ISC004`) ([#21972](https://github.com/astral-sh/ruff/pull/21972))
|
||||
- \[`flake8-use-pathlib`\] Make fixes unsafe when types change in compound statements (`PTH104`, `PTH105`, `PTH109`, `PTH115`) ([#22009](https://github.com/astral-sh/ruff/pull/22009))
|
||||
- \[`refurb`\] Extend support for `Path.open` (`FURB101`, `FURB103`) ([#21080](https://github.com/astral-sh/ruff/pull/21080))
|
||||
|
||||
### Bug fixes
|
||||
|
||||
- \[`pyupgrade`\] Fix parsing named Unicode escape sequences (`UP032`) ([#21901](https://github.com/astral-sh/ruff/pull/21901))
|
||||
|
||||
### Rule changes
|
||||
|
||||
- \[`eradicate`\] Ignore `ruff:disable` and `ruff:enable` comments in `ERA001` ([#22038](https://github.com/astral-sh/ruff/pull/22038))
|
||||
- \[`flake8-pytest-style`\] Allow `match` and `check` keyword arguments without an expected exception type (`PT010`) ([#21964](https://github.com/astral-sh/ruff/pull/21964))
|
||||
- [syntax-errors] Annotated name cannot be global ([#20868](https://github.com/astral-sh/ruff/pull/20868))
|
||||
|
||||
### Documentation
|
||||
|
||||
- Add `uv` and `ty` to the Ruff README ([#21996](https://github.com/astral-sh/ruff/pull/21996))
|
||||
- Document known lambda formatting deviations from Black ([#21954](https://github.com/astral-sh/ruff/pull/21954))
|
||||
- Update `setup.md` ([#22024](https://github.com/astral-sh/ruff/pull/22024))
|
||||
- \[`flake8-bandit`\] Fix broken link (`S704`) ([#22039](https://github.com/astral-sh/ruff/pull/22039))
|
||||
|
||||
### Other changes
|
||||
|
||||
- Fix playground Share button showing "Copied!" before clipboard copy completes ([#21942](https://github.com/astral-sh/ruff/pull/21942))
|
||||
|
||||
### Contributors
|
||||
|
||||
- [@dylwil3](https://github.com/dylwil3)
|
||||
- [@charliecloudberry](https://github.com/charliecloudberry)
|
||||
- [@charliermarsh](https://github.com/charliermarsh)
|
||||
- [@chirizxc](https://github.com/chirizxc)
|
||||
- [@ntBre](https://github.com/ntBre)
|
||||
- [@zanieb](https://github.com/zanieb)
|
||||
- [@amyreese](https://github.com/amyreese)
|
||||
- [@hauntsaninja](https://github.com/hauntsaninja)
|
||||
- [@11happy](https://github.com/11happy)
|
||||
- [@mahiro72](https://github.com/mahiro72)
|
||||
- [@MichaReiser](https://github.com/MichaReiser)
|
||||
- [@phongddo](https://github.com/phongddo)
|
||||
- [@PeterJCLaw](https://github.com/PeterJCLaw)
|
||||
|
||||
## 0.14.9
|
||||
|
||||
Released on 2025-12-11.
|
||||
|
||||
29
Cargo.lock
generated
29
Cargo.lock
generated
@@ -1004,6 +1004,27 @@ dependencies = [
|
||||
"crypto-common",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "dir-test"
|
||||
version = "0.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "62c013fe825864f3e4593f36426c1fa7a74f5603f13ca8d1af7a990c1cd94a79"
|
||||
dependencies = [
|
||||
"dir-test-macros",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "dir-test-macros"
|
||||
version = "0.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d42f54d7b4a6bc2400fe5b338e35d1a335787585375322f49c5d5fe7b243da7e"
|
||||
dependencies = [
|
||||
"glob",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "dirs"
|
||||
version = "6.0.0"
|
||||
@@ -2887,7 +2908,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "ruff"
|
||||
version = "0.14.10"
|
||||
version = "0.14.9"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"argfile",
|
||||
@@ -3145,7 +3166,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "ruff_linter"
|
||||
version = "0.14.10"
|
||||
version = "0.14.9"
|
||||
dependencies = [
|
||||
"aho-corasick",
|
||||
"anyhow",
|
||||
@@ -3504,7 +3525,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "ruff_wasm"
|
||||
version = "0.14.10"
|
||||
version = "0.14.9"
|
||||
dependencies = [
|
||||
"console_error_panic_hook",
|
||||
"console_log",
|
||||
@@ -4492,7 +4513,7 @@ dependencies = [
|
||||
"camino",
|
||||
"colored 3.0.0",
|
||||
"compact_str",
|
||||
"datatest-stable",
|
||||
"dir-test",
|
||||
"drop_bomb",
|
||||
"get-size2",
|
||||
"glob",
|
||||
|
||||
@@ -82,6 +82,7 @@ criterion = { version = "0.7.0", default-features = false }
|
||||
crossbeam = { version = "0.8.4" }
|
||||
dashmap = { version = "6.0.1" }
|
||||
datatest-stable = { version = "0.3.3" }
|
||||
dir-test = { version = "0.4.0" }
|
||||
dunce = { version = "1.0.5" }
|
||||
drop_bomb = { version = "0.1.5" }
|
||||
etcetera = { version = "0.11.0" }
|
||||
|
||||
13
README.md
13
README.md
@@ -57,11 +57,8 @@ Ruff is extremely actively developed and used in major open-source projects like
|
||||
|
||||
...and [many more](#whos-using-ruff).
|
||||
|
||||
Ruff is backed by [Astral](https://astral.sh), the creators of
|
||||
[uv](https://github.com/astral-sh/uv) and [ty](https://github.com/astral-sh/ty).
|
||||
|
||||
Read the [launch post](https://astral.sh/blog/announcing-astral-the-company-behind-ruff), or the
|
||||
original [project announcement](https://notes.crmarsh.com/python-tooling-could-be-much-much-faster).
|
||||
Ruff is backed by [Astral](https://astral.sh). Read the [launch post](https://astral.sh/blog/announcing-astral-the-company-behind-ruff),
|
||||
or the original [project announcement](https://notes.crmarsh.com/python-tooling-could-be-much-much-faster).
|
||||
|
||||
## Testimonials
|
||||
|
||||
@@ -150,8 +147,8 @@ curl -LsSf https://astral.sh/ruff/install.sh | sh
|
||||
powershell -c "irm https://astral.sh/ruff/install.ps1 | iex"
|
||||
|
||||
# For a specific version.
|
||||
curl -LsSf https://astral.sh/ruff/0.14.10/install.sh | sh
|
||||
powershell -c "irm https://astral.sh/ruff/0.14.10/install.ps1 | iex"
|
||||
curl -LsSf https://astral.sh/ruff/0.14.9/install.sh | sh
|
||||
powershell -c "irm https://astral.sh/ruff/0.14.9/install.ps1 | iex"
|
||||
```
|
||||
|
||||
You can also install Ruff via [Homebrew](https://formulae.brew.sh/formula/ruff), [Conda](https://anaconda.org/conda-forge/ruff),
|
||||
@@ -184,7 +181,7 @@ Ruff can also be used as a [pre-commit](https://pre-commit.com/) hook via [`ruff
|
||||
```yaml
|
||||
- repo: https://github.com/astral-sh/ruff-pre-commit
|
||||
# Ruff version.
|
||||
rev: v0.14.10
|
||||
rev: v0.14.9
|
||||
hooks:
|
||||
# Run the linter.
|
||||
- id: ruff-check
|
||||
|
||||
@@ -4,7 +4,6 @@ extend-exclude = [
|
||||
"crates/ty_vendored/vendor/**/*",
|
||||
"**/resources/**/*",
|
||||
"**/snapshots/**/*",
|
||||
"crates/ruff_linter/src/rules/flake8_implicit_str_concat/rules/collection_literal.rs",
|
||||
# Completion tests tend to have a lot of incomplete
|
||||
# words naturally. It's annoying to have to make all
|
||||
# of them actually words. So just ignore typos here.
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "ruff"
|
||||
version = "0.14.10"
|
||||
version = "0.14.9"
|
||||
publish = true
|
||||
authors = { workspace = true }
|
||||
edition = { workspace = true }
|
||||
|
||||
@@ -2,7 +2,6 @@ use std::fmt::Write as _;
|
||||
use std::io::{self, BufWriter, Write};
|
||||
|
||||
use anyhow::Result;
|
||||
use ruff_diagnostics::Applicability;
|
||||
use serde::ser::SerializeSeq;
|
||||
use serde::{Serialize, Serializer};
|
||||
use strum::IntoEnumIterator;
|
||||
@@ -22,7 +21,6 @@ struct Explanation<'a> {
|
||||
message_formats: &'a [&'a str],
|
||||
fix: String,
|
||||
fix_availability: FixAvailability,
|
||||
fix_safety: Applicability,
|
||||
#[expect(clippy::struct_field_names)]
|
||||
explanation: Option<&'a str>,
|
||||
preview: bool,
|
||||
@@ -43,7 +41,6 @@ impl<'a> Explanation<'a> {
|
||||
message_formats: rule.message_formats(),
|
||||
fix,
|
||||
fix_availability: rule.fixable(),
|
||||
fix_safety: rule.applicability(),
|
||||
explanation: rule.explanation(),
|
||||
preview: rule.is_preview(),
|
||||
status: rule.group(),
|
||||
|
||||
@@ -23,7 +23,6 @@ exit_code: 0
|
||||
],
|
||||
"fix": "Fix is sometimes available.",
|
||||
"fix_availability": "Sometimes",
|
||||
"fix_safety": "unsafe",
|
||||
"explanation": "## What it does\nChecks for unused imports.\n\n## Why is this bad?\nUnused imports add a performance overhead at runtime, and risk creating\nimport cycles. They also increase the cognitive load of reading the code.\n\nIf an import statement is used to check for the availability or existence\nof a module, consider using `importlib.util.find_spec` instead.\n\nIf an import statement is used to re-export a symbol as part of a module's\npublic interface, consider using a \"redundant\" import alias, which\ninstructs Ruff (and other tools) to respect the re-export, and avoid\nmarking it as unused, as in:\n\n```python\nfrom module import member as member\n```\n\nAlternatively, you can use `__all__` to declare a symbol as part of the module's\ninterface, as in:\n\n```python\n# __init__.py\nimport some_module\n\n__all__ = [\"some_module\"]\n```\n\n## Preview\nWhen [preview] is enabled (and certain simplifying assumptions\nare met), we analyze all import statements for a given module\nwhen determining whether an import is used, rather than simply\nthe last of these statements. This can result in both different and\nmore import statements being marked as unused.\n\nFor example, if a module consists of\n\n```python\nimport a\nimport a.b\n```\n\nthen both statements are marked as unused under [preview], whereas\nonly the second is marked as unused under stable behavior.\n\nAs another example, if a module consists of\n\n```python\nimport a.b\nimport a\n\na.b.foo()\n```\n\nthen a diagnostic will only be emitted for the first line under [preview],\nwhereas a diagnostic would only be emitted for the second line under\nstable behavior.\n\nNote that this behavior is somewhat subjective and is designed\nto conform to the developer's intuition rather than Python's actual\nexecution. To wit, the statement `import a.b` automatically executes\n`import a`, so in some sense `import a` is _always_ redundant\nin the presence of `import a.b`.\n\n\n## Fix safety\n\nFixes to remove unused imports are safe, except in `__init__.py` files.\n\nApplying fixes to `__init__.py` files is currently in preview. The fix offered depends on the\ntype of the unused import. Ruff will suggest a safe fix to export first-party imports with\neither a redundant alias or, if already present in the file, an `__all__` entry. If multiple\n`__all__` declarations are present, Ruff will not offer a fix. Ruff will suggest an unsafe fix\nto remove third-party and standard library imports -- the fix is unsafe because the module's\ninterface changes.\n\nSee [this FAQ section](https://docs.astral.sh/ruff/faq/#how-does-ruff-determine-which-of-my-imports-are-first-party-third-party-etc)\nfor more details on how Ruff\ndetermines whether an import is first or third-party.\n\n## Example\n\n```python\nimport numpy as np # unused import\n\n\ndef area(radius):\n return 3.14 * radius**2\n```\n\nUse instead:\n\n```python\ndef area(radius):\n return 3.14 * radius**2\n```\n\nTo check the availability of a module, use `importlib.util.find_spec`:\n\n```python\nfrom importlib.util import find_spec\n\nif find_spec(\"numpy\") is not None:\n print(\"numpy is installed\")\nelse:\n print(\"numpy is not installed\")\n```\n\n## Options\n- `lint.ignore-init-module-imports`\n- `lint.pyflakes.allowed-unused-imports`\n\n## References\n- [Python documentation: `import`](https://docs.python.org/3/reference/simple_stmts.html#the-import-statement)\n- [Python documentation: `importlib.util.find_spec`](https://docs.python.org/3/library/importlib.html#importlib.util.find_spec)\n- [Typing documentation: interface conventions](https://typing.python.org/en/latest/spec/distributing.html#library-interface-public-and-private-symbols)\n\n[preview]: https://docs.astral.sh/ruff/preview/\n",
|
||||
"preview": false,
|
||||
"status": {
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
use glob::PatternError;
|
||||
use ruff_notebook::{Notebook, NotebookError};
|
||||
use rustc_hash::FxHashMap;
|
||||
use std::panic::RefUnwindSafe;
|
||||
use std::sync::{Arc, Mutex};
|
||||
|
||||
@@ -21,44 +20,18 @@ use super::walk_directory::WalkDirectoryBuilder;
|
||||
///
|
||||
/// ## Warning
|
||||
/// Don't use this system for production code. It's intended for testing only.
|
||||
#[derive(Debug)]
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct TestSystem {
|
||||
inner: Arc<dyn WritableSystem + RefUnwindSafe + Send + Sync>,
|
||||
/// Environment variable overrides. If a key is present here, it takes precedence
|
||||
/// over the inner system's environment variables.
|
||||
env_overrides: Arc<Mutex<FxHashMap<String, Option<String>>>>,
|
||||
}
|
||||
|
||||
impl Clone for TestSystem {
|
||||
fn clone(&self) -> Self {
|
||||
Self {
|
||||
inner: self.inner.clone(),
|
||||
env_overrides: self.env_overrides.clone(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl TestSystem {
|
||||
pub fn new(inner: impl WritableSystem + RefUnwindSafe + Send + Sync + 'static) -> Self {
|
||||
Self {
|
||||
inner: Arc::new(inner),
|
||||
env_overrides: Arc::new(Mutex::new(FxHashMap::default())),
|
||||
}
|
||||
}
|
||||
|
||||
/// Sets an environment variable override. This takes precedence over the inner system.
|
||||
pub fn set_env_var(&self, name: impl Into<String>, value: impl Into<String>) {
|
||||
self.env_overrides
|
||||
.lock()
|
||||
.unwrap()
|
||||
.insert(name.into(), Some(value.into()));
|
||||
}
|
||||
|
||||
/// Removes an environment variable override, making it appear as not set.
|
||||
pub fn remove_env_var(&self, name: impl Into<String>) {
|
||||
self.env_overrides.lock().unwrap().insert(name.into(), None);
|
||||
}
|
||||
|
||||
/// Returns the [`InMemorySystem`].
|
||||
///
|
||||
/// ## Panics
|
||||
@@ -174,18 +147,6 @@ impl System for TestSystem {
|
||||
self.system().case_sensitivity()
|
||||
}
|
||||
|
||||
fn env_var(&self, name: &str) -> std::result::Result<String, std::env::VarError> {
|
||||
// Check overrides first
|
||||
if let Some(override_value) = self.env_overrides.lock().unwrap().get(name) {
|
||||
return match override_value {
|
||||
Some(value) => Ok(value.clone()),
|
||||
None => Err(std::env::VarError::NotPresent),
|
||||
};
|
||||
}
|
||||
// Fall back to inner system
|
||||
self.system().env_var(name)
|
||||
}
|
||||
|
||||
fn dyn_clone(&self) -> Box<dyn System> {
|
||||
Box::new(self.clone())
|
||||
}
|
||||
@@ -195,7 +156,6 @@ impl Default for TestSystem {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
inner: Arc::new(InMemorySystem::default()),
|
||||
env_overrides: Arc::new(Mutex::new(FxHashMap::default())),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "ruff_linter"
|
||||
version = "0.14.10"
|
||||
version = "0.14.9"
|
||||
publish = false
|
||||
authors = { workspace = true }
|
||||
edition = { workspace = true }
|
||||
|
||||
@@ -1,66 +0,0 @@
|
||||
facts = (
|
||||
"Lobsters have blue blood.",
|
||||
"The liver is the only human organ that can fully regenerate itself.",
|
||||
"Clarinets are made almost entirely out of wood from the mpingo tree."
|
||||
"In 1971, astronaut Alan Shepard played golf on the moon.",
|
||||
)
|
||||
|
||||
facts = [
|
||||
"Lobsters have blue blood.",
|
||||
"The liver is the only human organ that can fully regenerate itself.",
|
||||
"Clarinets are made almost entirely out of wood from the mpingo tree."
|
||||
"In 1971, astronaut Alan Shepard played golf on the moon.",
|
||||
]
|
||||
|
||||
facts = {
|
||||
"Lobsters have blue blood.",
|
||||
"The liver is the only human organ that can fully regenerate itself.",
|
||||
"Clarinets are made almost entirely out of wood from the mpingo tree."
|
||||
"In 1971, astronaut Alan Shepard played golf on the moon.",
|
||||
}
|
||||
|
||||
facts = {
|
||||
(
|
||||
"Clarinets are made almost entirely out of wood from the mpingo tree."
|
||||
"In 1971, astronaut Alan Shepard played golf on the moon."
|
||||
),
|
||||
}
|
||||
|
||||
facts = (
|
||||
"Octopuses have three hearts."
|
||||
# Missing comma here.
|
||||
"Honey never spoils.",
|
||||
)
|
||||
|
||||
facts = [
|
||||
"Octopuses have three hearts."
|
||||
# Missing comma here.
|
||||
"Honey never spoils.",
|
||||
]
|
||||
|
||||
facts = {
|
||||
"Octopuses have three hearts."
|
||||
# Missing comma here.
|
||||
"Honey never spoils.",
|
||||
}
|
||||
|
||||
facts = (
|
||||
(
|
||||
"Clarinets are made almost entirely out of wood from the mpingo tree."
|
||||
"In 1971, astronaut Alan Shepard played golf on the moon."
|
||||
),
|
||||
)
|
||||
|
||||
facts = [
|
||||
(
|
||||
"Clarinets are made almost entirely out of wood from the mpingo tree."
|
||||
"In 1971, astronaut Alan Shepard played golf on the moon."
|
||||
),
|
||||
]
|
||||
|
||||
facts = (
|
||||
"Lobsters have blue blood.\n"
|
||||
"The liver is the only human organ that can fully regenerate itself.\n"
|
||||
"Clarinets are made almost entirely out of wood from the mpingo tree.\n"
|
||||
"In 1971, astronaut Alan Shepard played golf on the moon.\n"
|
||||
)
|
||||
@@ -9,15 +9,3 @@ def test_ok():
|
||||
def test_error():
|
||||
with pytest.raises(UnicodeError):
|
||||
pass
|
||||
|
||||
def test_match_only():
|
||||
with pytest.raises(match="some error message"):
|
||||
pass
|
||||
|
||||
def test_check_only():
|
||||
with pytest.raises(check=lambda e: True):
|
||||
pass
|
||||
|
||||
def test_match_and_check():
|
||||
with pytest.raises(match="some error message", check=lambda e: True):
|
||||
pass
|
||||
|
||||
@@ -136,38 +136,4 @@ os.chmod("pth1_file", 0o700, None, True, 1, *[1], **{"x": 1}, foo=1)
|
||||
os.rename("pth1_file", "pth1_file1", None, None, 1, *[1], **{"x": 1}, foo=1)
|
||||
os.replace("pth1_file1", "pth1_file", None, None, 1, *[1], **{"x": 1}, foo=1)
|
||||
|
||||
os.path.samefile("pth1_file", "pth1_link", 1, *[1], **{"x": 1}, foo=1)
|
||||
|
||||
# See: https://github.com/astral-sh/ruff/issues/21794
|
||||
import sys
|
||||
|
||||
if os.rename("pth1.py", "pth1.py.bak"):
|
||||
print("rename: truthy")
|
||||
else:
|
||||
print("rename: falsey")
|
||||
|
||||
if os.replace("pth1.py.bak", "pth1.py"):
|
||||
print("replace: truthy")
|
||||
else:
|
||||
print("replace: falsey")
|
||||
|
||||
try:
|
||||
for _ in os.getcwd():
|
||||
print("getcwd: iterable")
|
||||
break
|
||||
except TypeError as e:
|
||||
print("getcwd: not iterable")
|
||||
|
||||
try:
|
||||
for _ in os.getcwdb():
|
||||
print("getcwdb: iterable")
|
||||
break
|
||||
except TypeError as e:
|
||||
print("getcwdb: not iterable")
|
||||
|
||||
try:
|
||||
for _ in os.readlink(sys.executable):
|
||||
print("readlink: iterable")
|
||||
break
|
||||
except TypeError as e:
|
||||
print("readlink: not iterable")
|
||||
os.path.samefile("pth1_file", "pth1_link", 1, *[1], **{"x": 1}, foo=1)
|
||||
@@ -132,6 +132,7 @@ async def c():
|
||||
# Non-errors
|
||||
###
|
||||
|
||||
# False-negative: RustPython doesn't parse the `\N{snowman}`.
|
||||
"\N{snowman} {}".format(a)
|
||||
|
||||
"{".format(a)
|
||||
@@ -275,6 +276,3 @@ if __name__ == "__main__":
|
||||
number = 0
|
||||
string = "{}".format(number := number + 1)
|
||||
print(string)
|
||||
|
||||
# Unicode escape
|
||||
"\N{angle}AOB = {angle}°".format(angle=180)
|
||||
|
||||
@@ -138,6 +138,5 @@ with open("file.txt", encoding="utf-8") as f:
|
||||
with open("file.txt", encoding="utf-8") as f:
|
||||
contents = process_contents(f.read())
|
||||
|
||||
with open("file1.txt", encoding="utf-8") as f:
|
||||
with open("file.txt", encoding="utf-8") as f:
|
||||
contents: str = process_contents(f.read())
|
||||
|
||||
@@ -1,8 +0,0 @@
|
||||
|
||||
from pathlib import Path
|
||||
|
||||
with Path("file.txt").open() as f:
|
||||
contents = f.read()
|
||||
|
||||
with Path("file.txt").open("r") as f:
|
||||
contents = f.read()
|
||||
@@ -1,26 +0,0 @@
|
||||
from pathlib import Path
|
||||
|
||||
with Path("file.txt").open("w") as f:
|
||||
f.write("test")
|
||||
|
||||
with Path("file.txt").open("wb") as f:
|
||||
f.write(b"test")
|
||||
|
||||
with Path("file.txt").open(mode="w") as f:
|
||||
f.write("test")
|
||||
|
||||
with Path("file.txt").open("w", encoding="utf8") as f:
|
||||
f.write("test")
|
||||
|
||||
with Path("file.txt").open("w", errors="ignore") as f:
|
||||
f.write("test")
|
||||
|
||||
with Path(foo()).open("w") as f:
|
||||
f.write("test")
|
||||
|
||||
p = Path("file.txt")
|
||||
with p.open("w") as f:
|
||||
f.write("test")
|
||||
|
||||
with Path("foo", "bar", "baz").open("w") as f:
|
||||
f.write("test")
|
||||
@@ -86,26 +86,3 @@ def f():
|
||||
# Multiple codes but none are used
|
||||
# ruff: disable[E741, F401, F841]
|
||||
print("hello")
|
||||
|
||||
|
||||
def f():
|
||||
# Unknown rule codes
|
||||
# ruff: disable[YF829]
|
||||
# ruff: disable[F841, RQW320]
|
||||
value = 0
|
||||
# ruff: enable[F841, RQW320]
|
||||
# ruff: enable[YF829]
|
||||
|
||||
|
||||
def f():
|
||||
# External rule codes should be ignored
|
||||
# ruff: disable[TK421]
|
||||
print("hello")
|
||||
# ruff: enable[TK421]
|
||||
|
||||
|
||||
def f():
|
||||
# Empty or missing rule codes
|
||||
# ruff: disable
|
||||
# ruff: disable[]
|
||||
print("hello")
|
||||
|
||||
@@ -1,38 +0,0 @@
|
||||
a: int = 1
|
||||
def f1():
|
||||
global a
|
||||
a: str = "foo" # error
|
||||
|
||||
b: int = 1
|
||||
def outer():
|
||||
def inner():
|
||||
global b
|
||||
b: str = "nested" # error
|
||||
|
||||
c: int = 1
|
||||
def f2():
|
||||
global c
|
||||
c: list[str] = [] # error
|
||||
|
||||
d: int = 1
|
||||
def f3():
|
||||
global d
|
||||
d: str # error
|
||||
|
||||
e: int = 1
|
||||
def f4():
|
||||
e: str = "happy" # okay
|
||||
|
||||
global f
|
||||
f: int = 1 # okay
|
||||
|
||||
g: int = 1
|
||||
global g # error
|
||||
|
||||
class C:
|
||||
x: str
|
||||
global x # error
|
||||
|
||||
class D:
|
||||
global x # error
|
||||
x: str
|
||||
@@ -214,13 +214,6 @@ pub(crate) fn expression(expr: &Expr, checker: &Checker) {
|
||||
range: _,
|
||||
node_index: _,
|
||||
}) => {
|
||||
if checker.is_rule_enabled(Rule::ImplicitStringConcatenationInCollectionLiteral) {
|
||||
flake8_implicit_str_concat::rules::implicit_string_concatenation_in_collection_literal(
|
||||
checker,
|
||||
expr,
|
||||
elts,
|
||||
);
|
||||
}
|
||||
if ctx.is_store() {
|
||||
let check_too_many_expressions =
|
||||
checker.is_rule_enabled(Rule::ExpressionsInStarAssignment);
|
||||
@@ -1336,13 +1329,6 @@ pub(crate) fn expression(expr: &Expr, checker: &Checker) {
|
||||
}
|
||||
}
|
||||
Expr::Set(set) => {
|
||||
if checker.is_rule_enabled(Rule::ImplicitStringConcatenationInCollectionLiteral) {
|
||||
flake8_implicit_str_concat::rules::implicit_string_concatenation_in_collection_literal(
|
||||
checker,
|
||||
expr,
|
||||
&set.elts,
|
||||
);
|
||||
}
|
||||
if checker.is_rule_enabled(Rule::DuplicateValue) {
|
||||
flake8_bugbear::rules::duplicate_value(checker, set);
|
||||
}
|
||||
|
||||
@@ -454,7 +454,6 @@ pub fn code_to_rule(linter: Linter, code: &str) -> Option<(RuleGroup, Rule)> {
|
||||
(Flake8ImplicitStrConcat, "001") => rules::flake8_implicit_str_concat::rules::SingleLineImplicitStringConcatenation,
|
||||
(Flake8ImplicitStrConcat, "002") => rules::flake8_implicit_str_concat::rules::MultiLineImplicitStringConcatenation,
|
||||
(Flake8ImplicitStrConcat, "003") => rules::flake8_implicit_str_concat::rules::ExplicitStringConcatenation,
|
||||
(Flake8ImplicitStrConcat, "004") => rules::flake8_implicit_str_concat::rules::ImplicitStringConcatenationInCollectionLiteral,
|
||||
|
||||
// flake8-print
|
||||
(Flake8Print, "1") => rules::flake8_print::rules::Print,
|
||||
@@ -1064,8 +1063,6 @@ pub fn code_to_rule(linter: Linter, code: &str) -> Option<(RuleGroup, Rule)> {
|
||||
(Ruff, "100") => rules::ruff::rules::UnusedNOQA,
|
||||
(Ruff, "101") => rules::ruff::rules::RedirectedNOQA,
|
||||
(Ruff, "102") => rules::ruff::rules::InvalidRuleCode,
|
||||
(Ruff, "103") => rules::ruff::rules::InvalidSuppressionComment,
|
||||
(Ruff, "104") => rules::ruff::rules::UnmatchedSuppressionComment,
|
||||
|
||||
(Ruff, "200") => rules::ruff::rules::InvalidPyprojectToml,
|
||||
#[cfg(any(feature = "test-rules", test))]
|
||||
|
||||
@@ -1001,7 +1001,6 @@ mod tests {
|
||||
#[test_case(Path::new("write_to_debug.py"), PythonVersion::PY310)]
|
||||
#[test_case(Path::new("invalid_expression.py"), PythonVersion::PY312)]
|
||||
#[test_case(Path::new("global_parameter.py"), PythonVersion::PY310)]
|
||||
#[test_case(Path::new("annotated_global.py"), PythonVersion::PY314)]
|
||||
fn test_semantic_errors(path: &Path, python_version: PythonVersion) -> Result<()> {
|
||||
let snapshot = format!(
|
||||
"semantic_syntax_error_{}_{}",
|
||||
|
||||
@@ -35,7 +35,7 @@ use crate::{FixAvailability, Violation};
|
||||
/// fab_auth_manager_app = FabAuthManager().get_fastapi_app()
|
||||
/// ```
|
||||
#[derive(ViolationMetadata)]
|
||||
#[violation_metadata(stable_since = "0.13.0", safety = "unsafe")]
|
||||
#[violation_metadata(stable_since = "0.13.0")]
|
||||
pub(crate) struct Airflow3MovedToProvider<'a> {
|
||||
deprecated: QualifiedName<'a>,
|
||||
replacement: ProviderReplacement,
|
||||
|
||||
@@ -41,7 +41,7 @@ use ruff_text_size::TextRange;
|
||||
/// yesterday = today - timedelta(days=1)
|
||||
/// ```
|
||||
#[derive(ViolationMetadata)]
|
||||
#[violation_metadata(stable_since = "0.13.0", safety = "unsafe")]
|
||||
#[violation_metadata(stable_since = "0.13.0")]
|
||||
pub(crate) struct Airflow3Removal {
|
||||
deprecated: String,
|
||||
replacement: Replacement,
|
||||
|
||||
@@ -51,7 +51,7 @@ use ruff_text_size::TextRange;
|
||||
/// )
|
||||
/// ```
|
||||
#[derive(ViolationMetadata)]
|
||||
#[violation_metadata(stable_since = "0.13.0", safety = "unsafe")]
|
||||
#[violation_metadata(stable_since = "0.13.0")]
|
||||
pub(crate) struct Airflow3SuggestedToMoveToProvider<'a> {
|
||||
deprecated: QualifiedName<'a>,
|
||||
replacement: ProviderReplacement,
|
||||
|
||||
@@ -37,7 +37,7 @@ use ruff_text_size::TextRange;
|
||||
/// Asset(uri="test://test/")
|
||||
/// ```
|
||||
#[derive(ViolationMetadata)]
|
||||
#[violation_metadata(stable_since = "0.13.0", safety = "unsafe")]
|
||||
#[violation_metadata(stable_since = "0.13.0")]
|
||||
pub(crate) struct Airflow3SuggestedUpdate {
|
||||
deprecated: String,
|
||||
replacement: Replacement,
|
||||
|
||||
@@ -22,7 +22,6 @@ static ALLOWLIST_REGEX: LazyLock<Regex> = LazyLock::new(|| {
|
||||
# Case-sensitive
|
||||
pyright
|
||||
| pyrefly
|
||||
| ruff\s*:\s*(disable|enable)
|
||||
| mypy:
|
||||
| type:\s*ignore
|
||||
| SPDX-License-Identifier:
|
||||
@@ -149,8 +148,6 @@ mod tests {
|
||||
assert!(!comment_contains_code("# 123", &[]));
|
||||
assert!(!comment_contains_code("# 123.1", &[]));
|
||||
assert!(!comment_contains_code("# 1, 2, 3", &[]));
|
||||
assert!(!comment_contains_code("# ruff: disable[E501]", &[]));
|
||||
assert!(!comment_contains_code("#ruff:enable[E501, F84]", &[]));
|
||||
assert!(!comment_contains_code(
|
||||
"# pylint: disable=redefined-outer-name",
|
||||
&[]
|
||||
|
||||
@@ -30,7 +30,7 @@ use crate::rules::eradicate::detection::comment_contains_code;
|
||||
///
|
||||
/// [#4845]: https://github.com/astral-sh/ruff/issues/4845
|
||||
#[derive(ViolationMetadata)]
|
||||
#[violation_metadata(stable_since = "v0.0.145", safety = "display-only")]
|
||||
#[violation_metadata(stable_since = "v0.0.145")]
|
||||
pub(crate) struct CommentedOutCode;
|
||||
|
||||
impl Violation for CommentedOutCode {
|
||||
|
||||
@@ -79,7 +79,7 @@ use ruff_python_ast::PythonVersion;
|
||||
/// [typing-annotated]: https://docs.python.org/3/library/typing.html#typing.Annotated
|
||||
/// [typing-extensions]: https://typing-extensions.readthedocs.io/en/stable/
|
||||
#[derive(ViolationMetadata)]
|
||||
#[violation_metadata(stable_since = "0.8.0", safety = "unsafe")]
|
||||
#[violation_metadata(stable_since = "0.8.0")]
|
||||
pub(crate) struct FastApiNonAnnotatedDependency {
|
||||
py_version: PythonVersion,
|
||||
}
|
||||
|
||||
@@ -59,7 +59,7 @@ use crate::{AlwaysFixableViolation, Fix};
|
||||
/// return item
|
||||
/// ```
|
||||
#[derive(ViolationMetadata)]
|
||||
#[violation_metadata(stable_since = "0.8.0", safety = "unsafe")]
|
||||
#[violation_metadata(stable_since = "0.8.0")]
|
||||
pub(crate) struct FastApiRedundantResponseModel;
|
||||
|
||||
impl AlwaysFixableViolation for FastApiRedundantResponseModel {
|
||||
|
||||
@@ -64,7 +64,7 @@ use crate::{FixAvailability, Violation};
|
||||
/// This rule's fix is marked as unsafe, as modifying a function signature can
|
||||
/// change the behavior of the code.
|
||||
#[derive(ViolationMetadata)]
|
||||
#[violation_metadata(stable_since = "0.10.0", safety = "unsafe")]
|
||||
#[violation_metadata(stable_since = "0.10.0")]
|
||||
pub(crate) struct FastApiUnusedPathParameter {
|
||||
arg_name: String,
|
||||
function_name: String,
|
||||
|
||||
@@ -241,7 +241,7 @@ impl Violation for MissingTypeCls {
|
||||
///
|
||||
/// - `lint.typing-extensions`
|
||||
#[derive(ViolationMetadata)]
|
||||
#[violation_metadata(stable_since = "v0.0.105", safety = "unsafe")]
|
||||
#[violation_metadata(stable_since = "v0.0.105")]
|
||||
pub(crate) struct MissingReturnTypeUndocumentedPublicFunction {
|
||||
name: String,
|
||||
annotation: Option<String>,
|
||||
@@ -295,7 +295,7 @@ impl Violation for MissingReturnTypeUndocumentedPublicFunction {
|
||||
///
|
||||
/// - `lint.typing-extensions`
|
||||
#[derive(ViolationMetadata)]
|
||||
#[violation_metadata(stable_since = "v0.0.105", safety = "unsafe")]
|
||||
#[violation_metadata(stable_since = "v0.0.105")]
|
||||
pub(crate) struct MissingReturnTypePrivateFunction {
|
||||
name: String,
|
||||
annotation: Option<String>,
|
||||
@@ -352,7 +352,7 @@ impl Violation for MissingReturnTypePrivateFunction {
|
||||
/// self.x = x
|
||||
/// ```
|
||||
#[derive(ViolationMetadata)]
|
||||
#[violation_metadata(stable_since = "v0.0.105", safety = "unsafe")]
|
||||
#[violation_metadata(stable_since = "v0.0.105")]
|
||||
pub(crate) struct MissingReturnTypeSpecialMethod {
|
||||
name: String,
|
||||
annotation: Option<String>,
|
||||
@@ -400,7 +400,7 @@ impl Violation for MissingReturnTypeSpecialMethod {
|
||||
/// return 1
|
||||
/// ```
|
||||
#[derive(ViolationMetadata)]
|
||||
#[violation_metadata(stable_since = "v0.0.105", safety = "unsafe")]
|
||||
#[violation_metadata(stable_since = "v0.0.105")]
|
||||
pub(crate) struct MissingReturnTypeStaticMethod {
|
||||
name: String,
|
||||
annotation: Option<String>,
|
||||
@@ -448,7 +448,7 @@ impl Violation for MissingReturnTypeStaticMethod {
|
||||
/// return 1
|
||||
/// ```
|
||||
#[derive(ViolationMetadata)]
|
||||
#[violation_metadata(stable_since = "v0.0.105", safety = "unsafe")]
|
||||
#[violation_metadata(stable_since = "v0.0.105")]
|
||||
pub(crate) struct MissingReturnTypeClassMethod {
|
||||
name: String,
|
||||
annotation: Option<String>,
|
||||
|
||||
@@ -49,7 +49,7 @@ use crate::{AlwaysFixableViolation, Edit, Fix};
|
||||
/// )
|
||||
/// ```
|
||||
#[derive(ViolationMetadata)]
|
||||
#[violation_metadata(stable_since = "0.5.0", safety = "unsafe")]
|
||||
#[violation_metadata(stable_since = "0.5.0")]
|
||||
pub(crate) struct AsyncZeroSleep {
|
||||
module: AsyncModule,
|
||||
}
|
||||
|
||||
@@ -70,7 +70,7 @@ fn is_open_call(func: &Expr, semantic: &SemanticModel) -> bool {
|
||||
}
|
||||
|
||||
/// Returns `true` if an expression resolves to a call to `pathlib.Path.open`.
|
||||
pub(crate) fn is_open_call_from_pathlib(func: &Expr, semantic: &SemanticModel) -> bool {
|
||||
fn is_open_call_from_pathlib(func: &Expr, semantic: &SemanticModel) -> bool {
|
||||
let Expr::Attribute(ast::ExprAttribute { attr, value, .. }) = func else {
|
||||
return false;
|
||||
};
|
||||
|
||||
@@ -39,7 +39,7 @@ use crate::{Edit, Fix, FixAvailability, Violation};
|
||||
///
|
||||
/// This fix is marked as unsafe as it changes program behavior.
|
||||
#[derive(ViolationMetadata)]
|
||||
#[violation_metadata(stable_since = "0.13.0", safety = "unsafe")]
|
||||
#[violation_metadata(stable_since = "0.13.0")]
|
||||
pub(crate) struct LongSleepNotForever {
|
||||
module: AsyncModule,
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@ mod async_zero_sleep;
|
||||
mod blocking_http_call;
|
||||
mod blocking_http_call_httpx;
|
||||
mod blocking_input;
|
||||
pub(crate) mod blocking_open_call;
|
||||
mod blocking_open_call;
|
||||
mod blocking_path_methods;
|
||||
mod blocking_process_invocation;
|
||||
mod blocking_sleep;
|
||||
|
||||
@@ -38,7 +38,7 @@ use crate::{Edit, Fix, FixAvailability, Violation};
|
||||
/// This rule's fix is marked as unsafe, as adding an `await` to a function
|
||||
/// call changes its semantics and runtime behavior.
|
||||
#[derive(ViolationMetadata)]
|
||||
#[violation_metadata(stable_since = "0.5.0", safety = "unsafe")]
|
||||
#[violation_metadata(stable_since = "0.5.0")]
|
||||
pub(crate) struct TrioSyncCall {
|
||||
method_name: MethodName,
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@ use crate::{checkers::ast::Checker, settings::LinterSettings};
|
||||
/// Checks for non-literal strings being passed to [`markupsafe.Markup`][markupsafe-markup].
|
||||
///
|
||||
/// ## Why is this bad?
|
||||
/// [`markupsafe.Markup`][markupsafe-markup] does not perform any escaping, so passing dynamic
|
||||
/// [`markupsafe.Markup`] does not perform any escaping, so passing dynamic
|
||||
/// content, like f-strings, variables or interpolated strings will potentially
|
||||
/// lead to XSS vulnerabilities.
|
||||
///
|
||||
|
||||
@@ -35,7 +35,7 @@ use crate::{AlwaysFixableViolation, Edit, Fix};
|
||||
/// ## References
|
||||
/// - [Python documentation: `assert`](https://docs.python.org/3/reference/simple_stmts.html#the-assert-statement)
|
||||
#[derive(ViolationMetadata)]
|
||||
#[violation_metadata(stable_since = "v0.0.67", safety = "unsafe")]
|
||||
#[violation_metadata(stable_since = "v0.0.67")]
|
||||
pub(crate) struct AssertFalse;
|
||||
|
||||
impl AlwaysFixableViolation for AssertFalse {
|
||||
|
||||
@@ -48,7 +48,7 @@ use crate::{AlwaysFixableViolation, Edit, Fix};
|
||||
/// ## References
|
||||
/// - [Python documentation: `getattr`](https://docs.python.org/3/library/functions.html#getattr)
|
||||
#[derive(ViolationMetadata)]
|
||||
#[violation_metadata(stable_since = "v0.0.110", safety = "unsafe")]
|
||||
#[violation_metadata(stable_since = "v0.0.110")]
|
||||
pub(crate) struct GetAttrWithConstant;
|
||||
|
||||
impl AlwaysFixableViolation for GetAttrWithConstant {
|
||||
|
||||
@@ -43,7 +43,7 @@ use crate::{AlwaysFixableViolation, Applicability, Fix};
|
||||
/// - [Python documentation: `map`](https://docs.python.org/3/library/functions.html#map)
|
||||
/// - [What’s New in Python 3.14](https://docs.python.org/dev/whatsnew/3.14.html)
|
||||
#[derive(ViolationMetadata)]
|
||||
#[violation_metadata(preview_since = "0.13.2", safety = "unsafe")]
|
||||
#[violation_metadata(preview_since = "0.13.2")]
|
||||
pub(crate) struct MapWithoutExplicitStrict;
|
||||
|
||||
impl AlwaysFixableViolation for MapWithoutExplicitStrict {
|
||||
|
||||
@@ -79,7 +79,7 @@ use crate::{Edit, Fix, FixAvailability, Violation};
|
||||
/// ## References
|
||||
/// - [Python documentation: Default Argument Values](https://docs.python.org/3/tutorial/controlflow.html#default-argument-values)
|
||||
#[derive(ViolationMetadata)]
|
||||
#[violation_metadata(stable_since = "v0.0.92", safety = "unsafe")]
|
||||
#[violation_metadata(stable_since = "v0.0.92")]
|
||||
pub(crate) struct MutableArgumentDefault;
|
||||
|
||||
impl Violation for MutableArgumentDefault {
|
||||
|
||||
@@ -41,7 +41,7 @@ use crate::{checkers::ast::Checker, fix::edits::add_argument};
|
||||
/// ## References
|
||||
/// - [Python documentation: `warnings.warn`](https://docs.python.org/3/library/warnings.html#warnings.warn)
|
||||
#[derive(ViolationMetadata)]
|
||||
#[violation_metadata(stable_since = "v0.0.257", safety = "unsafe")]
|
||||
#[violation_metadata(stable_since = "v0.0.257")]
|
||||
pub(crate) struct NoExplicitStacklevel;
|
||||
|
||||
impl AlwaysFixableViolation for NoExplicitStacklevel {
|
||||
|
||||
@@ -49,7 +49,7 @@ use crate::{AlwaysFixableViolation, Edit, Fix};
|
||||
/// ## References
|
||||
/// - [Python documentation: `setattr`](https://docs.python.org/3/library/functions.html#setattr)
|
||||
#[derive(ViolationMetadata)]
|
||||
#[violation_metadata(stable_since = "v0.0.111", safety = "unsafe")]
|
||||
#[violation_metadata(stable_since = "v0.0.111")]
|
||||
pub(crate) struct SetAttrWithConstant;
|
||||
|
||||
impl AlwaysFixableViolation for SetAttrWithConstant {
|
||||
|
||||
@@ -67,7 +67,7 @@ use crate::{Edit, Fix, FixAvailability, Violation};
|
||||
/// - [Python documentation: `__getattr__`](https://docs.python.org/3/reference/datamodel.html#object.__getattr__)
|
||||
/// - [Python documentation: `__call__`](https://docs.python.org/3/reference/datamodel.html#object.__call__)
|
||||
#[derive(ViolationMetadata)]
|
||||
#[violation_metadata(stable_since = "v0.0.106", safety = "unsafe")]
|
||||
#[violation_metadata(stable_since = "v0.0.106")]
|
||||
pub(crate) struct UnreliableCallableCheck;
|
||||
|
||||
impl Violation for UnreliableCallableCheck {
|
||||
|
||||
@@ -35,7 +35,7 @@ use crate::{Edit, Fix, FixAvailability, Violation};
|
||||
/// ## References
|
||||
/// - [PEP 8: Naming Conventions](https://peps.python.org/pep-0008/#naming-conventions)
|
||||
#[derive(ViolationMetadata)]
|
||||
#[violation_metadata(stable_since = "v0.0.84", safety = "unsafe")]
|
||||
#[violation_metadata(stable_since = "v0.0.84")]
|
||||
pub(crate) struct UnusedLoopControlVariable {
|
||||
/// The name of the loop control variable.
|
||||
name: String,
|
||||
|
||||
@@ -39,7 +39,7 @@ use crate::{AlwaysFixableViolation, Applicability, Fix};
|
||||
/// ## References
|
||||
/// - [Python documentation: `zip`](https://docs.python.org/3/library/functions.html#zip)
|
||||
#[derive(ViolationMetadata)]
|
||||
#[violation_metadata(stable_since = "v0.0.167", safety = "unsafe")]
|
||||
#[violation_metadata(stable_since = "v0.0.167")]
|
||||
pub(crate) struct ZipWithoutExplicitStrict;
|
||||
|
||||
impl AlwaysFixableViolation for ZipWithoutExplicitStrict {
|
||||
|
||||
@@ -42,7 +42,7 @@ use crate::rules::flake8_comprehensions::fixes;
|
||||
/// The fix is marked as safe for `list()` cases, as removing `list()` around
|
||||
/// `sorted()` does not change the behavior.
|
||||
#[derive(ViolationMetadata)]
|
||||
#[violation_metadata(stable_since = "v0.0.73", safety = "unsafe")]
|
||||
#[violation_metadata(stable_since = "v0.0.73")]
|
||||
pub(crate) struct UnnecessaryCallAroundSorted {
|
||||
func: UnnecessaryFunction,
|
||||
}
|
||||
|
||||
@@ -40,7 +40,7 @@ use crate::{AlwaysFixableViolation, Edit, Fix};
|
||||
/// ## Options
|
||||
/// - `lint.flake8-comprehensions.allow-dict-calls-with-keyword-arguments`
|
||||
#[derive(ViolationMetadata)]
|
||||
#[violation_metadata(stable_since = "v0.0.61", safety = "unsafe")]
|
||||
#[violation_metadata(stable_since = "v0.0.61")]
|
||||
pub(crate) struct UnnecessaryCollectionCall {
|
||||
kind: Collection,
|
||||
}
|
||||
|
||||
@@ -57,7 +57,7 @@ use crate::rules::flake8_comprehensions::fixes;
|
||||
///
|
||||
/// Additionally, this fix may drop comments when rewriting the comprehension.
|
||||
#[derive(ViolationMetadata)]
|
||||
#[violation_metadata(stable_since = "v0.0.73", safety = "unsafe")]
|
||||
#[violation_metadata(stable_since = "v0.0.73")]
|
||||
pub(crate) struct UnnecessaryComprehension {
|
||||
kind: ComprehensionKind,
|
||||
}
|
||||
|
||||
@@ -67,7 +67,7 @@ use crate::{Edit, Fix, Violation};
|
||||
///
|
||||
/// [preview]: https://docs.astral.sh/ruff/preview/
|
||||
#[derive(ViolationMetadata)]
|
||||
#[violation_metadata(stable_since = "v0.0.262", safety = "unsafe")]
|
||||
#[violation_metadata(stable_since = "v0.0.262")]
|
||||
pub(crate) struct UnnecessaryComprehensionInCall {
|
||||
comprehension_kind: ComprehensionKind,
|
||||
}
|
||||
|
||||
@@ -49,7 +49,7 @@ use crate::{Edit, Fix, FixAvailability, Violation};
|
||||
/// ## References
|
||||
/// - [Python documentation: `dict.fromkeys`](https://docs.python.org/3/library/stdtypes.html#dict.fromkeys)
|
||||
#[derive(ViolationMetadata)]
|
||||
#[violation_metadata(stable_since = "0.10.0", safety = "unsafe")]
|
||||
#[violation_metadata(stable_since = "0.10.0")]
|
||||
pub(crate) struct UnnecessaryDictComprehensionForIterable {
|
||||
is_value_none_literal: bool,
|
||||
}
|
||||
|
||||
@@ -48,7 +48,7 @@ use crate::rules::flake8_comprehensions::fixes;
|
||||
/// This rule's fix is marked as unsafe, as it may occasionally drop comments
|
||||
/// when rewriting the call. In most cases, though, comments will be preserved.
|
||||
#[derive(ViolationMetadata)]
|
||||
#[violation_metadata(stable_since = "v0.0.70", safety = "unsafe")]
|
||||
#[violation_metadata(stable_since = "v0.0.70")]
|
||||
pub(crate) struct UnnecessaryDoubleCastOrProcess {
|
||||
inner: String,
|
||||
outer: String,
|
||||
|
||||
@@ -32,7 +32,7 @@ use crate::rules::flake8_comprehensions::helpers;
|
||||
/// This rule's fix is marked as unsafe, as it may occasionally drop comments
|
||||
/// when rewriting the call. In most cases, though, comments will be preserved.
|
||||
#[derive(ViolationMetadata)]
|
||||
#[violation_metadata(stable_since = "v0.0.61", safety = "unsafe")]
|
||||
#[violation_metadata(stable_since = "v0.0.61")]
|
||||
pub(crate) struct UnnecessaryGeneratorDict;
|
||||
|
||||
impl AlwaysFixableViolation for UnnecessaryGeneratorDict {
|
||||
|
||||
@@ -42,7 +42,7 @@ use crate::rules::flake8_comprehensions::helpers;
|
||||
/// This rule's fix is marked as unsafe, as it may occasionally drop comments
|
||||
/// when rewriting the call. In most cases, though, comments will be preserved.
|
||||
#[derive(ViolationMetadata)]
|
||||
#[violation_metadata(stable_since = "v0.0.61", safety = "unsafe")]
|
||||
#[violation_metadata(stable_since = "v0.0.61")]
|
||||
pub(crate) struct UnnecessaryGeneratorList {
|
||||
short_circuit: bool,
|
||||
}
|
||||
|
||||
@@ -43,7 +43,7 @@ use crate::rules::flake8_comprehensions::helpers;
|
||||
/// This rule's fix is marked as unsafe, as it may occasionally drop comments
|
||||
/// when rewriting the call. In most cases, though, comments will be preserved.
|
||||
#[derive(ViolationMetadata)]
|
||||
#[violation_metadata(stable_since = "v0.0.61", safety = "unsafe")]
|
||||
#[violation_metadata(stable_since = "v0.0.61")]
|
||||
pub(crate) struct UnnecessaryGeneratorSet {
|
||||
short_circuit: bool,
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@ use crate::rules::flake8_comprehensions::helpers;
|
||||
/// This rule's fix is marked as unsafe, as it may occasionally drop comments
|
||||
/// when rewriting the call. In most cases, though, comments will be preserved.
|
||||
#[derive(ViolationMetadata)]
|
||||
#[violation_metadata(stable_since = "v0.0.73", safety = "unsafe")]
|
||||
#[violation_metadata(stable_since = "v0.0.73")]
|
||||
pub(crate) struct UnnecessaryListCall;
|
||||
|
||||
impl AlwaysFixableViolation for UnnecessaryListCall {
|
||||
|
||||
@@ -29,7 +29,7 @@ use crate::rules::flake8_comprehensions::helpers;
|
||||
/// This rule's fix is marked as unsafe, as it may occasionally drop comments
|
||||
/// when rewriting the call. In most cases, though, comments will be preserved.
|
||||
#[derive(ViolationMetadata)]
|
||||
#[violation_metadata(stable_since = "v0.0.58", safety = "unsafe")]
|
||||
#[violation_metadata(stable_since = "v0.0.58")]
|
||||
pub(crate) struct UnnecessaryListComprehensionDict;
|
||||
|
||||
impl AlwaysFixableViolation for UnnecessaryListComprehensionDict {
|
||||
|
||||
@@ -31,7 +31,7 @@ use crate::rules::flake8_comprehensions::helpers;
|
||||
/// This rule's fix is marked as unsafe, as it may occasionally drop comments
|
||||
/// when rewriting the call. In most cases, though, comments will be preserved.
|
||||
#[derive(ViolationMetadata)]
|
||||
#[violation_metadata(stable_since = "v0.0.58", safety = "unsafe")]
|
||||
#[violation_metadata(stable_since = "v0.0.58")]
|
||||
pub(crate) struct UnnecessaryListComprehensionSet;
|
||||
|
||||
impl AlwaysFixableViolation for UnnecessaryListComprehensionSet {
|
||||
|
||||
@@ -33,7 +33,7 @@ use crate::rules::flake8_comprehensions::helpers;
|
||||
/// This rule's fix is marked as unsafe, as it may occasionally drop comments
|
||||
/// when rewriting the call. In most cases, though, comments will be preserved.
|
||||
#[derive(ViolationMetadata)]
|
||||
#[violation_metadata(stable_since = "v0.0.61", safety = "unsafe")]
|
||||
#[violation_metadata(stable_since = "v0.0.61")]
|
||||
pub(crate) struct UnnecessaryLiteralDict {
|
||||
obj_type: LiteralKind,
|
||||
}
|
||||
|
||||
@@ -34,7 +34,7 @@ use crate::rules::flake8_comprehensions::helpers;
|
||||
/// This rule's fix is marked as unsafe, as it may occasionally drop comments
|
||||
/// when rewriting the call. In most cases, though, comments will be preserved.
|
||||
#[derive(ViolationMetadata)]
|
||||
#[violation_metadata(stable_since = "v0.0.61", safety = "unsafe")]
|
||||
#[violation_metadata(stable_since = "v0.0.61")]
|
||||
pub(crate) struct UnnecessaryLiteralSet {
|
||||
kind: UnnecessaryLiteral,
|
||||
}
|
||||
|
||||
@@ -35,7 +35,7 @@ use crate::rules::flake8_comprehensions::helpers;
|
||||
/// This rule's fix is marked as unsafe, as it may occasionally drop comments
|
||||
/// when rewriting the call. In most cases, though, comments will be preserved.
|
||||
#[derive(ViolationMetadata)]
|
||||
#[violation_metadata(stable_since = "v0.0.262", safety = "unsafe")]
|
||||
#[violation_metadata(stable_since = "v0.0.262")]
|
||||
pub(crate) struct UnnecessaryLiteralWithinDictCall {
|
||||
kind: DictKind,
|
||||
}
|
||||
|
||||
@@ -35,7 +35,7 @@ use crate::rules::flake8_comprehensions::helpers;
|
||||
/// This rule's fix is marked as unsafe, as it may occasionally drop comments
|
||||
/// when rewriting the call. In most cases, though, comments will be preserved.
|
||||
#[derive(ViolationMetadata)]
|
||||
#[violation_metadata(stable_since = "v0.0.66", safety = "unsafe")]
|
||||
#[violation_metadata(stable_since = "v0.0.66")]
|
||||
pub(crate) struct UnnecessaryLiteralWithinListCall {
|
||||
kind: LiteralKind,
|
||||
}
|
||||
|
||||
@@ -48,7 +48,7 @@ use crate::rules::flake8_comprehensions::helpers;
|
||||
///
|
||||
/// [preview]: https://docs.astral.sh/ruff/preview/
|
||||
#[derive(ViolationMetadata)]
|
||||
#[violation_metadata(stable_since = "v0.0.66", safety = "unsafe")]
|
||||
#[violation_metadata(stable_since = "v0.0.66")]
|
||||
pub(crate) struct UnnecessaryLiteralWithinTupleCall {
|
||||
literal_kind: TupleLiteralKind,
|
||||
}
|
||||
|
||||
@@ -44,7 +44,7 @@ use crate::{FixAvailability, Violation};
|
||||
/// This rule's fix is marked as unsafe, as it may occasionally drop comments
|
||||
/// when rewriting the call. In most cases, though, comments will be preserved.
|
||||
#[derive(ViolationMetadata)]
|
||||
#[violation_metadata(stable_since = "v0.0.74", safety = "unsafe")]
|
||||
#[violation_metadata(stable_since = "v0.0.74")]
|
||||
pub(crate) struct UnnecessaryMap {
|
||||
object_type: ObjectType,
|
||||
}
|
||||
|
||||
@@ -48,7 +48,7 @@ use crate::{Edit, Fix, FixAvailability, Violation};
|
||||
/// RuntimeError: 'Some value' is incorrect
|
||||
/// ```
|
||||
#[derive(ViolationMetadata)]
|
||||
#[violation_metadata(stable_since = "v0.0.183", safety = "unsafe")]
|
||||
#[violation_metadata(stable_since = "v0.0.183")]
|
||||
pub(crate) struct RawStringInException;
|
||||
|
||||
impl Violation for RawStringInException {
|
||||
@@ -104,7 +104,7 @@ impl Violation for RawStringInException {
|
||||
/// RuntimeError: 'Some value' is incorrect
|
||||
/// ```
|
||||
#[derive(ViolationMetadata)]
|
||||
#[violation_metadata(stable_since = "v0.0.183", safety = "unsafe")]
|
||||
#[violation_metadata(stable_since = "v0.0.183")]
|
||||
pub(crate) struct FStringInException;
|
||||
|
||||
impl Violation for FStringInException {
|
||||
@@ -161,7 +161,7 @@ impl Violation for FStringInException {
|
||||
/// RuntimeError: 'Some value' is incorrect
|
||||
/// ```
|
||||
#[derive(ViolationMetadata)]
|
||||
#[violation_metadata(stable_since = "v0.0.183", safety = "unsafe")]
|
||||
#[violation_metadata(stable_since = "v0.0.183")]
|
||||
pub(crate) struct DotFormatInException;
|
||||
|
||||
impl Violation for DotFormatInException {
|
||||
|
||||
@@ -49,7 +49,7 @@ use crate::{AlwaysFixableViolation, Fix};
|
||||
/// ## Options
|
||||
/// - `target-version`
|
||||
#[derive(ViolationMetadata)]
|
||||
#[violation_metadata(stable_since = "v0.0.271", safety = "unsafe")]
|
||||
#[violation_metadata(stable_since = "v0.0.271")]
|
||||
pub(crate) struct FutureRequiredTypeAnnotation {
|
||||
reason: Reason,
|
||||
}
|
||||
|
||||
@@ -68,7 +68,7 @@ use crate::{AlwaysFixableViolation, Fix};
|
||||
/// ## Options
|
||||
/// - `target-version`
|
||||
#[derive(ViolationMetadata)]
|
||||
#[violation_metadata(stable_since = "v0.0.269", safety = "unsafe")]
|
||||
#[violation_metadata(stable_since = "v0.0.269")]
|
||||
pub(crate) struct FutureRewritableTypeAnnotation {
|
||||
name: String,
|
||||
}
|
||||
|
||||
@@ -32,10 +32,6 @@ mod tests {
|
||||
Path::new("ISC_syntax_error_2.py")
|
||||
)]
|
||||
#[test_case(Rule::ExplicitStringConcatenation, Path::new("ISC.py"))]
|
||||
#[test_case(
|
||||
Rule::ImplicitStringConcatenationInCollectionLiteral,
|
||||
Path::new("ISC004.py")
|
||||
)]
|
||||
fn rules(rule_code: Rule, path: &Path) -> Result<()> {
|
||||
let snapshot = format!("{}_{}", rule_code.noqa_code(), path.to_string_lossy());
|
||||
let diagnostics = test_path(
|
||||
|
||||
@@ -1,103 +0,0 @@
|
||||
use ruff_macros::{ViolationMetadata, derive_message_formats};
|
||||
use ruff_python_ast::token::parenthesized_range;
|
||||
use ruff_python_ast::{Expr, StringLike};
|
||||
use ruff_text_size::Ranged;
|
||||
|
||||
use crate::checkers::ast::Checker;
|
||||
use crate::{Edit, Fix, FixAvailability, Violation};
|
||||
|
||||
/// ## What it does
|
||||
/// Checks for implicitly concatenated strings inside list, tuple, and set literals.
|
||||
///
|
||||
/// ## Why is this bad?
|
||||
/// In collection literals, implicit string concatenation is often the result of
|
||||
/// a missing comma between elements, which can silently merge items together.
|
||||
///
|
||||
/// ## Example
|
||||
/// ```python
|
||||
/// facts = (
|
||||
/// "Lobsters have blue blood.",
|
||||
/// "The liver is the only human organ that can fully regenerate itself.",
|
||||
/// "Clarinets are made almost entirely out of wood from the mpingo tree."
|
||||
/// "In 1971, astronaut Alan Shepard played golf on the moon.",
|
||||
/// )
|
||||
/// ```
|
||||
///
|
||||
/// Instead, you likely intended:
|
||||
/// ```python
|
||||
/// facts = (
|
||||
/// "Lobsters have blue blood.",
|
||||
/// "The liver is the only human organ that can fully regenerate itself.",
|
||||
/// "Clarinets are made almost entirely out of wood from the mpingo tree.",
|
||||
/// "In 1971, astronaut Alan Shepard played golf on the moon.",
|
||||
/// )
|
||||
/// ```
|
||||
///
|
||||
/// If the concatenation is intentional, wrap it in parentheses to make it
|
||||
/// explicit:
|
||||
/// ```python
|
||||
/// facts = (
|
||||
/// "Lobsters have blue blood.",
|
||||
/// "The liver is the only human organ that can fully regenerate itself.",
|
||||
/// (
|
||||
/// "Clarinets are made almost entirely out of wood from the mpingo tree."
|
||||
/// "In 1971, astronaut Alan Shepard played golf on the moon."
|
||||
/// ),
|
||||
/// )
|
||||
/// ```
|
||||
///
|
||||
/// ## Fix safety
|
||||
/// The fix is safe in that it does not change the semantics of your code.
|
||||
/// However, the issue is that you may often want to change semantics
|
||||
/// by adding a missing comma.
|
||||
#[derive(ViolationMetadata)]
|
||||
#[violation_metadata(preview_since = "0.14.10", safety = "unsafe")]
|
||||
pub(crate) struct ImplicitStringConcatenationInCollectionLiteral;
|
||||
|
||||
impl Violation for ImplicitStringConcatenationInCollectionLiteral {
|
||||
const FIX_AVAILABILITY: FixAvailability = FixAvailability::Always;
|
||||
|
||||
#[derive_message_formats]
|
||||
fn message(&self) -> String {
|
||||
"Unparenthesized implicit string concatenation in collection".to_string()
|
||||
}
|
||||
|
||||
fn fix_title(&self) -> Option<String> {
|
||||
Some("Wrap implicitly concatenated strings in parentheses".to_string())
|
||||
}
|
||||
}
|
||||
|
||||
/// ISC004
|
||||
pub(crate) fn implicit_string_concatenation_in_collection_literal(
|
||||
checker: &Checker,
|
||||
expr: &Expr,
|
||||
elements: &[Expr],
|
||||
) {
|
||||
for element in elements {
|
||||
let Ok(string_like) = StringLike::try_from(element) else {
|
||||
continue;
|
||||
};
|
||||
if !string_like.is_implicit_concatenated() {
|
||||
continue;
|
||||
}
|
||||
if parenthesized_range(
|
||||
string_like.as_expression_ref(),
|
||||
expr.into(),
|
||||
checker.tokens(),
|
||||
)
|
||||
.is_some()
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
let mut diagnostic = checker.report_diagnostic(
|
||||
ImplicitStringConcatenationInCollectionLiteral,
|
||||
string_like.range(),
|
||||
);
|
||||
diagnostic.help("Did you forget a comma?");
|
||||
diagnostic.set_fix(Fix::unsafe_edits(
|
||||
Edit::insertion("(".to_string(), string_like.range().start()),
|
||||
[Edit::insertion(")".to_string(), string_like.range().end())],
|
||||
));
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,5 @@
|
||||
pub(crate) use collection_literal::*;
|
||||
pub(crate) use explicit::*;
|
||||
pub(crate) use implicit::*;
|
||||
|
||||
mod collection_literal;
|
||||
mod explicit;
|
||||
mod implicit;
|
||||
|
||||
@@ -1,149 +0,0 @@
|
||||
---
|
||||
source: crates/ruff_linter/src/rules/flake8_implicit_str_concat/mod.rs
|
||||
---
|
||||
ISC004 [*] Unparenthesized implicit string concatenation in collection
|
||||
--> ISC004.py:4:5
|
||||
|
|
||||
2 | "Lobsters have blue blood.",
|
||||
3 | "The liver is the only human organ that can fully regenerate itself.",
|
||||
4 | / "Clarinets are made almost entirely out of wood from the mpingo tree."
|
||||
5 | | "In 1971, astronaut Alan Shepard played golf on the moon.",
|
||||
| |______________________________________________________________^
|
||||
6 | )
|
||||
|
|
||||
help: Wrap implicitly concatenated strings in parentheses
|
||||
help: Did you forget a comma?
|
||||
1 | facts = (
|
||||
2 | "Lobsters have blue blood.",
|
||||
3 | "The liver is the only human organ that can fully regenerate itself.",
|
||||
- "Clarinets are made almost entirely out of wood from the mpingo tree."
|
||||
- "In 1971, astronaut Alan Shepard played golf on the moon.",
|
||||
4 + ("Clarinets are made almost entirely out of wood from the mpingo tree."
|
||||
5 + "In 1971, astronaut Alan Shepard played golf on the moon."),
|
||||
6 | )
|
||||
7 |
|
||||
8 | facts = [
|
||||
note: This is an unsafe fix and may change runtime behavior
|
||||
|
||||
ISC004 [*] Unparenthesized implicit string concatenation in collection
|
||||
--> ISC004.py:11:5
|
||||
|
|
||||
9 | "Lobsters have blue blood.",
|
||||
10 | "The liver is the only human organ that can fully regenerate itself.",
|
||||
11 | / "Clarinets are made almost entirely out of wood from the mpingo tree."
|
||||
12 | | "In 1971, astronaut Alan Shepard played golf on the moon.",
|
||||
| |______________________________________________________________^
|
||||
13 | ]
|
||||
|
|
||||
help: Wrap implicitly concatenated strings in parentheses
|
||||
help: Did you forget a comma?
|
||||
8 | facts = [
|
||||
9 | "Lobsters have blue blood.",
|
||||
10 | "The liver is the only human organ that can fully regenerate itself.",
|
||||
- "Clarinets are made almost entirely out of wood from the mpingo tree."
|
||||
- "In 1971, astronaut Alan Shepard played golf on the moon.",
|
||||
11 + ("Clarinets are made almost entirely out of wood from the mpingo tree."
|
||||
12 + "In 1971, astronaut Alan Shepard played golf on the moon."),
|
||||
13 | ]
|
||||
14 |
|
||||
15 | facts = {
|
||||
note: This is an unsafe fix and may change runtime behavior
|
||||
|
||||
ISC004 [*] Unparenthesized implicit string concatenation in collection
|
||||
--> ISC004.py:18:5
|
||||
|
|
||||
16 | "Lobsters have blue blood.",
|
||||
17 | "The liver is the only human organ that can fully regenerate itself.",
|
||||
18 | / "Clarinets are made almost entirely out of wood from the mpingo tree."
|
||||
19 | | "In 1971, astronaut Alan Shepard played golf on the moon.",
|
||||
| |______________________________________________________________^
|
||||
20 | }
|
||||
|
|
||||
help: Wrap implicitly concatenated strings in parentheses
|
||||
help: Did you forget a comma?
|
||||
15 | facts = {
|
||||
16 | "Lobsters have blue blood.",
|
||||
17 | "The liver is the only human organ that can fully regenerate itself.",
|
||||
- "Clarinets are made almost entirely out of wood from the mpingo tree."
|
||||
- "In 1971, astronaut Alan Shepard played golf on the moon.",
|
||||
18 + ("Clarinets are made almost entirely out of wood from the mpingo tree."
|
||||
19 + "In 1971, astronaut Alan Shepard played golf on the moon."),
|
||||
20 | }
|
||||
21 |
|
||||
22 | facts = {
|
||||
note: This is an unsafe fix and may change runtime behavior
|
||||
|
||||
ISC004 [*] Unparenthesized implicit string concatenation in collection
|
||||
--> ISC004.py:30:5
|
||||
|
|
||||
29 | facts = (
|
||||
30 | / "Octopuses have three hearts."
|
||||
31 | | # Missing comma here.
|
||||
32 | | "Honey never spoils.",
|
||||
| |_________________________^
|
||||
33 | )
|
||||
|
|
||||
help: Wrap implicitly concatenated strings in parentheses
|
||||
help: Did you forget a comma?
|
||||
27 | }
|
||||
28 |
|
||||
29 | facts = (
|
||||
- "Octopuses have three hearts."
|
||||
30 + ("Octopuses have three hearts."
|
||||
31 | # Missing comma here.
|
||||
- "Honey never spoils.",
|
||||
32 + "Honey never spoils."),
|
||||
33 | )
|
||||
34 |
|
||||
35 | facts = [
|
||||
note: This is an unsafe fix and may change runtime behavior
|
||||
|
||||
ISC004 [*] Unparenthesized implicit string concatenation in collection
|
||||
--> ISC004.py:36:5
|
||||
|
|
||||
35 | facts = [
|
||||
36 | / "Octopuses have three hearts."
|
||||
37 | | # Missing comma here.
|
||||
38 | | "Honey never spoils.",
|
||||
| |_________________________^
|
||||
39 | ]
|
||||
|
|
||||
help: Wrap implicitly concatenated strings in parentheses
|
||||
help: Did you forget a comma?
|
||||
33 | )
|
||||
34 |
|
||||
35 | facts = [
|
||||
- "Octopuses have three hearts."
|
||||
36 + ("Octopuses have three hearts."
|
||||
37 | # Missing comma here.
|
||||
- "Honey never spoils.",
|
||||
38 + "Honey never spoils."),
|
||||
39 | ]
|
||||
40 |
|
||||
41 | facts = {
|
||||
note: This is an unsafe fix and may change runtime behavior
|
||||
|
||||
ISC004 [*] Unparenthesized implicit string concatenation in collection
|
||||
--> ISC004.py:42:5
|
||||
|
|
||||
41 | facts = {
|
||||
42 | / "Octopuses have three hearts."
|
||||
43 | | # Missing comma here.
|
||||
44 | | "Honey never spoils.",
|
||||
| |_________________________^
|
||||
45 | }
|
||||
|
|
||||
help: Wrap implicitly concatenated strings in parentheses
|
||||
help: Did you forget a comma?
|
||||
39 | ]
|
||||
40 |
|
||||
41 | facts = {
|
||||
- "Octopuses have three hearts."
|
||||
42 + ("Octopuses have three hearts."
|
||||
43 | # Missing comma here.
|
||||
- "Honey never spoils.",
|
||||
44 + "Honey never spoils."),
|
||||
45 | }
|
||||
46 |
|
||||
47 | facts = (
|
||||
note: This is an unsafe fix and may change runtime behavior
|
||||
@@ -35,7 +35,7 @@ use crate::renamer::Renamer;
|
||||
/// - `lint.flake8-import-conventions.aliases`
|
||||
/// - `lint.flake8-import-conventions.extend-aliases`
|
||||
#[derive(ViolationMetadata)]
|
||||
#[violation_metadata(stable_since = "v0.0.166", safety = "unsafe")]
|
||||
#[violation_metadata(stable_since = "v0.0.166")]
|
||||
pub(crate) struct UnconventionalImportAlias {
|
||||
name: String,
|
||||
asname: String,
|
||||
|
||||
@@ -42,7 +42,7 @@ use crate::{Edit, Fix, FixAvailability, Violation};
|
||||
///
|
||||
/// [Logger Objects]: https://docs.python.org/3/library/logging.html#logger-objects
|
||||
#[derive(ViolationMetadata)]
|
||||
#[violation_metadata(stable_since = "v0.2.0", safety = "unsafe")]
|
||||
#[violation_metadata(stable_since = "v0.2.0")]
|
||||
pub(crate) struct DirectLoggerInstantiation;
|
||||
|
||||
impl Violation for DirectLoggerInstantiation {
|
||||
|
||||
@@ -44,7 +44,7 @@ use crate::{Fix, FixAvailability, Violation};
|
||||
/// ## Fix safety
|
||||
/// The fix is always marked as unsafe, as it changes runtime behavior.
|
||||
#[derive(ViolationMetadata)]
|
||||
#[violation_metadata(stable_since = "0.12.0", safety = "unsafe")]
|
||||
#[violation_metadata(stable_since = "0.12.0")]
|
||||
pub(crate) struct ExcInfoOutsideExceptHandler;
|
||||
|
||||
impl Violation for ExcInfoOutsideExceptHandler {
|
||||
|
||||
@@ -45,7 +45,7 @@ use crate::{Edit, Fix, FixAvailability, Violation};
|
||||
///
|
||||
/// [logging documentation]: https://docs.python.org/3/library/logging.html#logger-objects
|
||||
#[derive(ViolationMetadata)]
|
||||
#[violation_metadata(stable_since = "v0.2.0", safety = "unsafe")]
|
||||
#[violation_metadata(stable_since = "v0.2.0")]
|
||||
pub(crate) struct InvalidGetLoggerArgument;
|
||||
|
||||
impl Violation for InvalidGetLoggerArgument {
|
||||
|
||||
@@ -44,7 +44,7 @@ use crate::{Edit, Fix, FixAvailability, Violation};
|
||||
///
|
||||
/// [The documentation]: https://docs.python.org/3/library/logging.html#logging.exception
|
||||
#[derive(ViolationMetadata)]
|
||||
#[violation_metadata(preview_since = "0.9.5", safety = "unsafe")]
|
||||
#[violation_metadata(preview_since = "0.9.5")]
|
||||
pub(crate) struct LogExceptionOutsideExceptHandler;
|
||||
|
||||
impl Violation for LogExceptionOutsideExceptHandler {
|
||||
|
||||
@@ -35,7 +35,7 @@ use crate::{AlwaysFixableViolation, Fix};
|
||||
/// This fix is always marked as unsafe since we cannot know
|
||||
/// for certain which assignment was intended.
|
||||
#[derive(ViolationMetadata)]
|
||||
#[violation_metadata(stable_since = "v0.0.208", safety = "unsafe")]
|
||||
#[violation_metadata(stable_since = "v0.0.208")]
|
||||
pub(crate) struct DuplicateClassFieldDefinition {
|
||||
name: String,
|
||||
}
|
||||
|
||||
@@ -49,7 +49,7 @@ use crate::{Edit, Fix};
|
||||
/// - [Python documentation: `str.startswith`](https://docs.python.org/3/library/stdtypes.html#str.startswith)
|
||||
/// - [Python documentation: `str.endswith`](https://docs.python.org/3/library/stdtypes.html#str.endswith)
|
||||
#[derive(ViolationMetadata)]
|
||||
#[violation_metadata(stable_since = "v0.0.243", safety = "unsafe")]
|
||||
#[violation_metadata(stable_since = "v0.0.243")]
|
||||
pub(crate) struct MultipleStartsEndsWith {
|
||||
attr: String,
|
||||
}
|
||||
|
||||
@@ -70,7 +70,7 @@ use crate::{Applicability, Edit, Fix, FixAvailability, Violation};
|
||||
/// - [Python documentation: Dictionary displays](https://docs.python.org/3/reference/expressions.html#dictionary-displays)
|
||||
/// - [Python documentation: Calls](https://docs.python.org/3/reference/expressions.html#calls)
|
||||
#[derive(ViolationMetadata)]
|
||||
#[violation_metadata(stable_since = "v0.0.231", safety = "unsafe")]
|
||||
#[violation_metadata(stable_since = "v0.0.231")]
|
||||
pub(crate) struct UnnecessaryDictKwargs;
|
||||
|
||||
impl Violation for UnnecessaryDictKwargs {
|
||||
|
||||
@@ -57,7 +57,7 @@ use crate::{Edit, Fix};
|
||||
/// ## References
|
||||
/// - [Python documentation: The `pass` statement](https://docs.python.org/3/reference/simple_stmts.html#the-pass-statement)
|
||||
#[derive(ViolationMetadata)]
|
||||
#[violation_metadata(stable_since = "v0.0.208", safety = "unsafe")]
|
||||
#[violation_metadata(stable_since = "v0.0.208")]
|
||||
pub(crate) struct UnnecessaryPlaceholder {
|
||||
kind: Placeholder,
|
||||
}
|
||||
|
||||
@@ -48,7 +48,7 @@ use crate::{Fix, FixAvailability, Violation};
|
||||
/// This rule's fix is marked as unsafe, as it will remove `print` statements
|
||||
/// that are used beyond debugging purposes.
|
||||
#[derive(ViolationMetadata)]
|
||||
#[violation_metadata(stable_since = "v0.0.57", safety = "unsafe")]
|
||||
#[violation_metadata(stable_since = "v0.0.57")]
|
||||
pub(crate) struct Print;
|
||||
|
||||
impl Violation for Print {
|
||||
@@ -98,7 +98,7 @@ impl Violation for Print {
|
||||
/// This rule's fix is marked as unsafe, as it will remove `pprint` statements
|
||||
/// that are used beyond debugging purposes.
|
||||
#[derive(ViolationMetadata)]
|
||||
#[violation_metadata(stable_since = "v0.0.57", safety = "unsafe")]
|
||||
#[violation_metadata(stable_since = "v0.0.57")]
|
||||
pub(crate) struct PPrint;
|
||||
|
||||
impl Violation for PPrint {
|
||||
|
||||
@@ -89,7 +89,7 @@ use crate::{Applicability, Edit, Fix, FixAvailability, Violation};
|
||||
/// [typing_TypeVar]: https://docs.python.org/3/library/typing.html#typing.TypeVar
|
||||
/// [typing_extensions]: https://typing-extensions.readthedocs.io/en/latest/
|
||||
#[derive(ViolationMetadata)]
|
||||
#[violation_metadata(stable_since = "v0.0.283", safety = "unsafe")]
|
||||
#[violation_metadata(stable_since = "v0.0.283")]
|
||||
pub(crate) struct CustomTypeVarForSelf {
|
||||
typevar_name: String,
|
||||
}
|
||||
|
||||
@@ -27,7 +27,7 @@ use crate::{AlwaysFixableViolation, Edit, Fix};
|
||||
/// def func(param: int) -> str: ...
|
||||
/// ```
|
||||
#[derive(ViolationMetadata)]
|
||||
#[violation_metadata(stable_since = "v0.0.253", safety = "unsafe")]
|
||||
#[violation_metadata(stable_since = "v0.0.253")]
|
||||
pub(crate) struct DocstringInStub;
|
||||
|
||||
impl AlwaysFixableViolation for DocstringInStub {
|
||||
|
||||
@@ -40,7 +40,7 @@ use crate::{AlwaysFixableViolation, Applicability, Edit, Fix};
|
||||
/// ## References
|
||||
/// - [Python documentation: `typing.Literal`](https://docs.python.org/3/library/typing.html#typing.Literal)
|
||||
#[derive(ViolationMetadata)]
|
||||
#[violation_metadata(stable_since = "0.6.0", safety = "unsafe")]
|
||||
#[violation_metadata(stable_since = "0.6.0")]
|
||||
pub(crate) struct DuplicateLiteralMember {
|
||||
duplicate_name: String,
|
||||
}
|
||||
|
||||
@@ -37,7 +37,7 @@ use crate::{Applicability, Edit, Fix, FixAvailability, Violation};
|
||||
/// ## References
|
||||
/// - [Python documentation: `typing.Union`](https://docs.python.org/3/library/typing.html#typing.Union)
|
||||
#[derive(ViolationMetadata)]
|
||||
#[violation_metadata(stable_since = "v0.0.262", safety = "unsafe")]
|
||||
#[violation_metadata(stable_since = "v0.0.262")]
|
||||
pub(crate) struct DuplicateUnionMember {
|
||||
duplicate_name: String,
|
||||
}
|
||||
|
||||
@@ -84,7 +84,7 @@ use crate::{Fix, FixAvailability, Violation};
|
||||
/// [1]: https://github.com/python/cpython/issues/106102
|
||||
/// [MRO]: https://docs.python.org/3/glossary.html#term-method-resolution-order
|
||||
#[derive(ViolationMetadata)]
|
||||
#[violation_metadata(stable_since = "0.13.0", safety = "unsafe")]
|
||||
#[violation_metadata(stable_since = "0.13.0")]
|
||||
pub(crate) struct GenericNotLastBaseClass;
|
||||
|
||||
impl Violation for GenericNotLastBaseClass {
|
||||
|
||||
@@ -113,7 +113,7 @@ use ruff_text_size::Ranged;
|
||||
///
|
||||
/// [PEP 673]: https://peps.python.org/pep-0673/#valid-locations-for-self
|
||||
#[derive(ViolationMetadata)]
|
||||
#[violation_metadata(stable_since = "v0.0.271", safety = "display-only")]
|
||||
#[violation_metadata(stable_since = "v0.0.271")]
|
||||
pub(crate) struct NonSelfReturnType {
|
||||
class_name: String,
|
||||
method_name: String,
|
||||
|
||||
@@ -49,7 +49,7 @@ use crate::{Applicability, Edit, Fix, FixAvailability, Violation};
|
||||
/// ## References
|
||||
/// - [Typing documentation: Legal parameters for `Literal` at type check time](https://typing.python.org/en/latest/spec/literal.html#legal-parameters-for-literal-at-type-check-time)
|
||||
#[derive(ViolationMetadata)]
|
||||
#[violation_metadata(stable_since = "0.13.0", safety = "unsafe")]
|
||||
#[violation_metadata(stable_since = "0.13.0")]
|
||||
pub(crate) struct RedundantNoneLiteral {
|
||||
union_kind: UnionKind,
|
||||
}
|
||||
|
||||
@@ -53,7 +53,7 @@ use super::generate_union_fix;
|
||||
///
|
||||
/// [typing specification]: https://typing.python.org/en/latest/spec/special-types.html#special-cases-for-float-and-complex
|
||||
#[derive(ViolationMetadata)]
|
||||
#[violation_metadata(stable_since = "v0.0.279", safety = "unsafe")]
|
||||
#[violation_metadata(stable_since = "v0.0.279")]
|
||||
pub(crate) struct RedundantNumericUnion {
|
||||
redundancy: Redundancy,
|
||||
}
|
||||
|
||||
@@ -40,7 +40,7 @@ use crate::{Applicability, Fix, FixAvailability, Violation};
|
||||
/// `import foo as foo` alias, or are imported via a `*` import. As such, the
|
||||
/// fix is marked as safe in more cases for `.pyi` files.
|
||||
#[derive(ViolationMetadata)]
|
||||
#[violation_metadata(stable_since = "v0.0.271", safety = "unsafe")]
|
||||
#[violation_metadata(stable_since = "v0.0.271")]
|
||||
pub(crate) struct UnaliasedCollectionsAbcSetImport;
|
||||
|
||||
impl Violation for UnaliasedCollectionsAbcSetImport {
|
||||
|
||||
@@ -47,7 +47,7 @@ use crate::{Edit, Fix, FixAvailability, Violation};
|
||||
/// ## References
|
||||
/// - [Python documentation: `typing.Literal`](https://docs.python.org/3/library/typing.html#typing.Literal)
|
||||
#[derive(ViolationMetadata)]
|
||||
#[violation_metadata(stable_since = "v0.0.278", safety = "unsafe")]
|
||||
#[violation_metadata(stable_since = "v0.0.278")]
|
||||
pub(crate) struct UnnecessaryLiteralUnion {
|
||||
members: Vec<String>,
|
||||
}
|
||||
|
||||
@@ -32,7 +32,7 @@ use crate::{Applicability, Edit, Fix, FixAvailability, Violation};
|
||||
/// Note that while the fix may flatten nested unions into a single top-level union,
|
||||
/// the semantics of the annotation will remain unchanged.
|
||||
#[derive(ViolationMetadata)]
|
||||
#[violation_metadata(stable_since = "v0.0.283", safety = "unsafe")]
|
||||
#[violation_metadata(stable_since = "v0.0.283")]
|
||||
pub(crate) struct UnnecessaryTypeUnion {
|
||||
members: Vec<Name>,
|
||||
union_kind: UnionKind,
|
||||
|
||||
@@ -30,7 +30,7 @@ use crate::{Fix, FixAvailability, Violation};
|
||||
/// The fix is always marked as unsafe, as it would break your code if the type
|
||||
/// variable is imported by another module.
|
||||
#[derive(ViolationMetadata)]
|
||||
#[violation_metadata(stable_since = "v0.0.281", safety = "unsafe")]
|
||||
#[violation_metadata(stable_since = "v0.0.281")]
|
||||
pub(crate) struct UnusedPrivateTypeVar {
|
||||
type_var_like_name: String,
|
||||
type_var_like_kind: String,
|
||||
|
||||
@@ -61,7 +61,7 @@ use super::unittest_assert::UnittestAssert;
|
||||
/// assert not something_else
|
||||
/// ```
|
||||
#[derive(ViolationMetadata)]
|
||||
#[violation_metadata(stable_since = "v0.0.208", safety = "unsafe")]
|
||||
#[violation_metadata(stable_since = "v0.0.208")]
|
||||
pub(crate) struct PytestCompositeAssertion;
|
||||
|
||||
impl Violation for PytestCompositeAssertion {
|
||||
@@ -191,7 +191,7 @@ impl Violation for PytestAssertAlwaysFalse {
|
||||
/// ## References
|
||||
/// - [`pytest` documentation: Assertion introspection details](https://docs.pytest.org/en/7.1.x/how-to/assert.html#assertion-introspection-details)
|
||||
#[derive(ViolationMetadata)]
|
||||
#[violation_metadata(stable_since = "v0.0.208", safety = "unsafe")]
|
||||
#[violation_metadata(stable_since = "v0.0.208")]
|
||||
pub(crate) struct PytestUnittestAssertion {
|
||||
assertion: String,
|
||||
}
|
||||
@@ -346,7 +346,7 @@ pub(crate) fn unittest_assertion(
|
||||
/// ## References
|
||||
/// - [`pytest` documentation: Assertions about expected exceptions](https://docs.pytest.org/en/latest/how-to/assert.html#assertions-about-expected-exceptions)
|
||||
#[derive(ViolationMetadata)]
|
||||
#[violation_metadata(stable_since = "v0.0.285", safety = "unsafe")]
|
||||
#[violation_metadata(stable_since = "v0.0.285")]
|
||||
pub(crate) struct PytestUnittestRaisesAssertion {
|
||||
assertion: String,
|
||||
}
|
||||
|
||||
@@ -80,7 +80,7 @@ use crate::rules::flake8_pytest_style::helpers::{
|
||||
/// ## References
|
||||
/// - [`pytest` documentation: API Reference: Fixtures](https://docs.pytest.org/en/latest/reference/reference.html#fixtures-api)
|
||||
#[derive(ViolationMetadata)]
|
||||
#[violation_metadata(stable_since = "v0.0.208", safety = "unsafe")]
|
||||
#[violation_metadata(stable_since = "v0.0.208")]
|
||||
pub(crate) struct PytestFixtureIncorrectParenthesesStyle {
|
||||
expected: Parentheses,
|
||||
actual: Parentheses,
|
||||
@@ -174,7 +174,7 @@ impl Violation for PytestFixturePositionalArgs {
|
||||
/// ## References
|
||||
/// - [`pytest` documentation: `@pytest.fixture` functions](https://docs.pytest.org/en/latest/reference/reference.html#pytest-fixture)
|
||||
#[derive(ViolationMetadata)]
|
||||
#[violation_metadata(stable_since = "v0.0.208", safety = "unsafe")]
|
||||
#[violation_metadata(stable_since = "v0.0.208")]
|
||||
pub(crate) struct PytestExtraneousScopeFunction;
|
||||
|
||||
impl AlwaysFixableViolation for PytestExtraneousScopeFunction {
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user