mirror of https://github.com/astral-sh/ruff
parent
59155ce9f6
commit
2729f3d207
18
README.md
18
README.md
|
|
@ -1739,6 +1739,24 @@ allowed-confusables = ["−", "ρ", "∗"]
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
#### [`builtins`](#builtins)
|
||||||
|
|
||||||
|
A list of builtins to treat as defined references, in addition to the
|
||||||
|
system builtins.
|
||||||
|
|
||||||
|
**Default value**: `[]`
|
||||||
|
|
||||||
|
**Type**: `Vec<String>`
|
||||||
|
|
||||||
|
**Example usage**:
|
||||||
|
|
||||||
|
```toml
|
||||||
|
[tool.ruff]
|
||||||
|
builtins = ["_"]
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
#### [`cache-dir`](#cache-dir)
|
#### [`cache-dir`](#cache-dir)
|
||||||
|
|
||||||
A path to the cache directory.
|
A path to the cache directory.
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,19 @@
|
||||||
|
[flake8]
|
||||||
|
# Ignore style and complexity
|
||||||
|
# E: style errors
|
||||||
|
# W: style warnings
|
||||||
|
# C: complexity
|
||||||
|
# D: docstring warnings (unused pydocstyle extension)
|
||||||
|
# F841: local variable assigned but never used
|
||||||
|
ignore = E, C, W, D, F841
|
||||||
|
builtins = c, get_config
|
||||||
|
exclude =
|
||||||
|
.cache,
|
||||||
|
.github,
|
||||||
|
docs,
|
||||||
|
jupyterhub/alembic*,
|
||||||
|
onbuild,
|
||||||
|
scripts,
|
||||||
|
share,
|
||||||
|
tools,
|
||||||
|
setup.py
|
||||||
|
|
@ -99,6 +99,9 @@ pub fn convert(
|
||||||
if let Some(value) = value {
|
if let Some(value) = value {
|
||||||
match key.as_str() {
|
match key.as_str() {
|
||||||
// flake8
|
// flake8
|
||||||
|
"builtins" => {
|
||||||
|
options.builtins = Some(parser::parse_strings(value.as_ref()));
|
||||||
|
}
|
||||||
"max-line-length" | "max_line_length" => match value.clone().parse::<usize>() {
|
"max-line-length" | "max_line_length" => match value.clone().parse::<usize>() {
|
||||||
Ok(line_length) => options.line_length = Some(line_length),
|
Ok(line_length) => options.line_length = Some(line_length),
|
||||||
Err(e) => eprintln!("Unable to parse '{key}' property: {e}"),
|
Err(e) => eprintln!("Unable to parse '{key}' property: {e}"),
|
||||||
|
|
@ -362,6 +365,7 @@ mod tests {
|
||||||
)?;
|
)?;
|
||||||
let expected = Pyproject::new(Options {
|
let expected = Pyproject::new(Options {
|
||||||
allowed_confusables: None,
|
allowed_confusables: None,
|
||||||
|
builtins: None,
|
||||||
cache_dir: None,
|
cache_dir: None,
|
||||||
dummy_variable_rgx: None,
|
dummy_variable_rgx: None,
|
||||||
exclude: None,
|
exclude: None,
|
||||||
|
|
@ -425,6 +429,7 @@ mod tests {
|
||||||
)?;
|
)?;
|
||||||
let expected = Pyproject::new(Options {
|
let expected = Pyproject::new(Options {
|
||||||
allowed_confusables: None,
|
allowed_confusables: None,
|
||||||
|
builtins: None,
|
||||||
cache_dir: None,
|
cache_dir: None,
|
||||||
dummy_variable_rgx: None,
|
dummy_variable_rgx: None,
|
||||||
exclude: None,
|
exclude: None,
|
||||||
|
|
@ -488,6 +493,7 @@ mod tests {
|
||||||
)?;
|
)?;
|
||||||
let expected = Pyproject::new(Options {
|
let expected = Pyproject::new(Options {
|
||||||
allowed_confusables: None,
|
allowed_confusables: None,
|
||||||
|
builtins: None,
|
||||||
cache_dir: None,
|
cache_dir: None,
|
||||||
dummy_variable_rgx: None,
|
dummy_variable_rgx: None,
|
||||||
exclude: None,
|
exclude: None,
|
||||||
|
|
@ -551,6 +557,7 @@ mod tests {
|
||||||
)?;
|
)?;
|
||||||
let expected = Pyproject::new(Options {
|
let expected = Pyproject::new(Options {
|
||||||
allowed_confusables: None,
|
allowed_confusables: None,
|
||||||
|
builtins: None,
|
||||||
cache_dir: None,
|
cache_dir: None,
|
||||||
dummy_variable_rgx: None,
|
dummy_variable_rgx: None,
|
||||||
exclude: None,
|
exclude: None,
|
||||||
|
|
@ -614,6 +621,7 @@ mod tests {
|
||||||
)?;
|
)?;
|
||||||
let expected = Pyproject::new(Options {
|
let expected = Pyproject::new(Options {
|
||||||
allowed_confusables: None,
|
allowed_confusables: None,
|
||||||
|
builtins: None,
|
||||||
cache_dir: None,
|
cache_dir: None,
|
||||||
dummy_variable_rgx: None,
|
dummy_variable_rgx: None,
|
||||||
exclude: None,
|
exclude: None,
|
||||||
|
|
@ -685,6 +693,7 @@ mod tests {
|
||||||
)?;
|
)?;
|
||||||
let expected = Pyproject::new(Options {
|
let expected = Pyproject::new(Options {
|
||||||
allowed_confusables: None,
|
allowed_confusables: None,
|
||||||
|
builtins: None,
|
||||||
cache_dir: None,
|
cache_dir: None,
|
||||||
dummy_variable_rgx: None,
|
dummy_variable_rgx: None,
|
||||||
exclude: None,
|
exclude: None,
|
||||||
|
|
@ -751,6 +760,7 @@ mod tests {
|
||||||
)?;
|
)?;
|
||||||
let expected = Pyproject::new(Options {
|
let expected = Pyproject::new(Options {
|
||||||
allowed_confusables: None,
|
allowed_confusables: None,
|
||||||
|
builtins: None,
|
||||||
cache_dir: None,
|
cache_dir: None,
|
||||||
dummy_variable_rgx: None,
|
dummy_variable_rgx: None,
|
||||||
exclude: None,
|
exclude: None,
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
_("Translations")
|
||||||
|
|
@ -15,6 +15,16 @@
|
||||||
"minLength": 1
|
"minLength": 1
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"builtins": {
|
||||||
|
"description": "A list of builtins to treat as defined references, in addition to the system builtins.",
|
||||||
|
"type": [
|
||||||
|
"array",
|
||||||
|
"null"
|
||||||
|
],
|
||||||
|
"items": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
"cache-dir": {
|
"cache-dir": {
|
||||||
"description": "A path to the cache directory.\n\nBy default, Ruff stores cache results in a `.ruff_cache` directory in the current project root.\n\nHowever, Ruff will also respect the `RUFF_CACHE_DIR` environment variable, which takes precedence over that default.\n\nThis setting will override even the `RUFF_CACHE_DIR` environment variable, if set.",
|
"description": "A path to the cache directory.\n\nBy default, Ruff stores cache results in a `.ruff_cache` directory in the current project root.\n\nHowever, Ruff will also respect the `RUFF_CACHE_DIR` environment variable, which takes precedence over that default.\n\nThis setting will override even the `RUFF_CACHE_DIR` environment variable, if set.",
|
||||||
"type": [
|
"type": [
|
||||||
|
|
|
||||||
|
|
@ -3291,7 +3291,12 @@ impl<'a> Checker<'a> {
|
||||||
fn bind_builtins(&mut self) {
|
fn bind_builtins(&mut self) {
|
||||||
let scope = &mut self.scopes[*(self.scope_stack.last().expect("No current scope found"))];
|
let scope = &mut self.scopes[*(self.scope_stack.last().expect("No current scope found"))];
|
||||||
|
|
||||||
for builtin in BUILTINS.iter().chain(MAGIC_GLOBALS.iter()) {
|
for builtin in BUILTINS
|
||||||
|
.iter()
|
||||||
|
.chain(MAGIC_GLOBALS.iter())
|
||||||
|
.copied()
|
||||||
|
.chain(self.settings.builtins.iter().map(String::as_str))
|
||||||
|
{
|
||||||
let index = self.bindings.len();
|
let index = self.bindings.len();
|
||||||
self.bindings.push(Binding {
|
self.bindings.push(Binding {
|
||||||
kind: BindingKind::Builtin,
|
kind: BindingKind::Builtin,
|
||||||
|
|
|
||||||
|
|
@ -140,6 +140,29 @@ mod tests {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn default_builtins() -> Result<()> {
|
||||||
|
let diagnostics = test_path(
|
||||||
|
Path::new("./resources/test/fixtures/pyflakes/builtins.py"),
|
||||||
|
&settings::Settings::for_rules(vec![RuleCode::F821]),
|
||||||
|
)?;
|
||||||
|
insta::assert_yaml_snapshot!(diagnostics);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn extra_builtins() -> Result<()> {
|
||||||
|
let diagnostics = test_path(
|
||||||
|
Path::new("./resources/test/fixtures/pyflakes/builtins.py"),
|
||||||
|
&settings::Settings {
|
||||||
|
builtins: vec!["_".to_string()],
|
||||||
|
..settings::Settings::for_rules(vec![RuleCode::F821])
|
||||||
|
},
|
||||||
|
)?;
|
||||||
|
insta::assert_yaml_snapshot!(diagnostics);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn future_annotations() -> Result<()> {
|
fn future_annotations() -> Result<()> {
|
||||||
let diagnostics = test_path(
|
let diagnostics = test_path(
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,15 @@
|
||||||
|
---
|
||||||
|
source: src/pyflakes/mod.rs
|
||||||
|
expression: diagnostics
|
||||||
|
---
|
||||||
|
- kind:
|
||||||
|
UndefinedName: _
|
||||||
|
location:
|
||||||
|
row: 1
|
||||||
|
column: 0
|
||||||
|
end_location:
|
||||||
|
row: 1
|
||||||
|
column: 1
|
||||||
|
fix: ~
|
||||||
|
parent: ~
|
||||||
|
|
||||||
|
|
@ -0,0 +1,6 @@
|
||||||
|
---
|
||||||
|
source: src/pyflakes/mod.rs
|
||||||
|
expression: diagnostics
|
||||||
|
---
|
||||||
|
[]
|
||||||
|
|
||||||
|
|
@ -28,6 +28,7 @@ use crate::{
|
||||||
#[derive(Debug, Default)]
|
#[derive(Debug, Default)]
|
||||||
pub struct Configuration {
|
pub struct Configuration {
|
||||||
pub allowed_confusables: Option<Vec<char>>,
|
pub allowed_confusables: Option<Vec<char>>,
|
||||||
|
pub builtins: Option<Vec<String>>,
|
||||||
pub cache_dir: Option<PathBuf>,
|
pub cache_dir: Option<PathBuf>,
|
||||||
pub dummy_variable_rgx: Option<Regex>,
|
pub dummy_variable_rgx: Option<Regex>,
|
||||||
pub exclude: Option<Vec<FilePattern>>,
|
pub exclude: Option<Vec<FilePattern>>,
|
||||||
|
|
@ -80,6 +81,7 @@ impl Configuration {
|
||||||
pub fn from_options(options: Options, project_root: &Path) -> Result<Self> {
|
pub fn from_options(options: Options, project_root: &Path) -> Result<Self> {
|
||||||
Ok(Configuration {
|
Ok(Configuration {
|
||||||
allowed_confusables: options.allowed_confusables,
|
allowed_confusables: options.allowed_confusables,
|
||||||
|
builtins: options.builtins,
|
||||||
cache_dir: options
|
cache_dir: options
|
||||||
.cache_dir
|
.cache_dir
|
||||||
.map(|dir| {
|
.map(|dir| {
|
||||||
|
|
@ -177,6 +179,7 @@ impl Configuration {
|
||||||
pub fn combine(self, config: Configuration) -> Self {
|
pub fn combine(self, config: Configuration) -> Self {
|
||||||
Self {
|
Self {
|
||||||
allowed_confusables: self.allowed_confusables.or(config.allowed_confusables),
|
allowed_confusables: self.allowed_confusables.or(config.allowed_confusables),
|
||||||
|
builtins: self.builtins.or(config.builtins),
|
||||||
cache_dir: self.cache_dir.or(config.cache_dir),
|
cache_dir: self.cache_dir.or(config.cache_dir),
|
||||||
dummy_variable_rgx: self.dummy_variable_rgx.or(config.dummy_variable_rgx),
|
dummy_variable_rgx: self.dummy_variable_rgx.or(config.dummy_variable_rgx),
|
||||||
exclude: self.exclude.or(config.exclude),
|
exclude: self.exclude.or(config.exclude),
|
||||||
|
|
|
||||||
|
|
@ -40,6 +40,7 @@ const CARGO_PKG_VERSION: &str = env!("CARGO_PKG_VERSION");
|
||||||
#[allow(clippy::struct_excessive_bools)]
|
#[allow(clippy::struct_excessive_bools)]
|
||||||
pub struct Settings {
|
pub struct Settings {
|
||||||
pub allowed_confusables: FxHashSet<char>,
|
pub allowed_confusables: FxHashSet<char>,
|
||||||
|
pub builtins: Vec<String>,
|
||||||
pub cache_dir: PathBuf,
|
pub cache_dir: PathBuf,
|
||||||
pub dummy_variable_rgx: Regex,
|
pub dummy_variable_rgx: Regex,
|
||||||
pub enabled: FxHashSet<RuleCode>,
|
pub enabled: FxHashSet<RuleCode>,
|
||||||
|
|
@ -113,6 +114,7 @@ impl Settings {
|
||||||
.allowed_confusables
|
.allowed_confusables
|
||||||
.map(FxHashSet::from_iter)
|
.map(FxHashSet::from_iter)
|
||||||
.unwrap_or_default(),
|
.unwrap_or_default(),
|
||||||
|
builtins: config.builtins.unwrap_or_default(),
|
||||||
cache_dir: config.cache_dir.unwrap_or_else(|| cache_dir(project_root)),
|
cache_dir: config.cache_dir.unwrap_or_else(|| cache_dir(project_root)),
|
||||||
dummy_variable_rgx: config
|
dummy_variable_rgx: config
|
||||||
.dummy_variable_rgx
|
.dummy_variable_rgx
|
||||||
|
|
@ -216,6 +218,7 @@ impl Settings {
|
||||||
pub fn for_rule(rule_code: RuleCode) -> Self {
|
pub fn for_rule(rule_code: RuleCode) -> Self {
|
||||||
Self {
|
Self {
|
||||||
allowed_confusables: FxHashSet::from_iter([]),
|
allowed_confusables: FxHashSet::from_iter([]),
|
||||||
|
builtins: vec![],
|
||||||
cache_dir: cache_dir(path_dedot::CWD.as_path()),
|
cache_dir: cache_dir(path_dedot::CWD.as_path()),
|
||||||
dummy_variable_rgx: Regex::new("^(_+|(_+[a-zA-Z0-9_]*[a-zA-Z0-9]+?))$").unwrap(),
|
dummy_variable_rgx: Regex::new("^(_+|(_+[a-zA-Z0-9_]*[a-zA-Z0-9]+?))$").unwrap(),
|
||||||
enabled: FxHashSet::from_iter([rule_code.clone()]),
|
enabled: FxHashSet::from_iter([rule_code.clone()]),
|
||||||
|
|
@ -258,6 +261,7 @@ impl Settings {
|
||||||
pub fn for_rules(rule_codes: Vec<RuleCode>) -> Self {
|
pub fn for_rules(rule_codes: Vec<RuleCode>) -> Self {
|
||||||
Self {
|
Self {
|
||||||
allowed_confusables: FxHashSet::from_iter([]),
|
allowed_confusables: FxHashSet::from_iter([]),
|
||||||
|
builtins: vec![],
|
||||||
cache_dir: cache_dir(path_dedot::CWD.as_path()),
|
cache_dir: cache_dir(path_dedot::CWD.as_path()),
|
||||||
dummy_variable_rgx: Regex::new("^(_+|(_+[a-zA-Z0-9_]*[a-zA-Z0-9]+?))$").unwrap(),
|
dummy_variable_rgx: Regex::new("^(_+|(_+[a-zA-Z0-9_]*[a-zA-Z0-9]+?))$").unwrap(),
|
||||||
enabled: FxHashSet::from_iter(rule_codes.clone()),
|
enabled: FxHashSet::from_iter(rule_codes.clone()),
|
||||||
|
|
|
||||||
|
|
@ -30,6 +30,16 @@ pub struct Options {
|
||||||
/// A list of allowed "confusable" Unicode characters to ignore when
|
/// A list of allowed "confusable" Unicode characters to ignore when
|
||||||
/// enforcing `RUF001`, `RUF002`, and `RUF003`.
|
/// enforcing `RUF001`, `RUF002`, and `RUF003`.
|
||||||
pub allowed_confusables: Option<Vec<char>>,
|
pub allowed_confusables: Option<Vec<char>>,
|
||||||
|
#[option(
|
||||||
|
default = r#"[]"#,
|
||||||
|
value_type = "Vec<String>",
|
||||||
|
example = r#"
|
||||||
|
builtins = ["_"]
|
||||||
|
"#
|
||||||
|
)]
|
||||||
|
/// A list of builtins to treat as defined references, in addition to the
|
||||||
|
/// system builtins.
|
||||||
|
pub builtins: Option<Vec<String>>,
|
||||||
#[option(
|
#[option(
|
||||||
default = ".ruff_cache",
|
default = ".ruff_cache",
|
||||||
value_type = "PathBuf",
|
value_type = "PathBuf",
|
||||||
|
|
|
||||||
|
|
@ -164,6 +164,7 @@ mod tests {
|
||||||
Some(Tools {
|
Some(Tools {
|
||||||
ruff: Some(Options {
|
ruff: Some(Options {
|
||||||
allowed_confusables: None,
|
allowed_confusables: None,
|
||||||
|
builtins: None,
|
||||||
cache_dir: None,
|
cache_dir: None,
|
||||||
dummy_variable_rgx: None,
|
dummy_variable_rgx: None,
|
||||||
exclude: None,
|
exclude: None,
|
||||||
|
|
@ -221,6 +222,7 @@ line-length = 79
|
||||||
Some(Tools {
|
Some(Tools {
|
||||||
ruff: Some(Options {
|
ruff: Some(Options {
|
||||||
allowed_confusables: None,
|
allowed_confusables: None,
|
||||||
|
builtins: None,
|
||||||
dummy_variable_rgx: None,
|
dummy_variable_rgx: None,
|
||||||
exclude: None,
|
exclude: None,
|
||||||
extend: None,
|
extend: None,
|
||||||
|
|
@ -278,6 +280,7 @@ exclude = ["foo.py"]
|
||||||
Some(Tools {
|
Some(Tools {
|
||||||
ruff: Some(Options {
|
ruff: Some(Options {
|
||||||
allowed_confusables: None,
|
allowed_confusables: None,
|
||||||
|
builtins: None,
|
||||||
cache_dir: None,
|
cache_dir: None,
|
||||||
dummy_variable_rgx: None,
|
dummy_variable_rgx: None,
|
||||||
exclude: Some(vec!["foo.py".to_string()]),
|
exclude: Some(vec!["foo.py".to_string()]),
|
||||||
|
|
@ -335,6 +338,7 @@ select = ["E501"]
|
||||||
Some(Tools {
|
Some(Tools {
|
||||||
ruff: Some(Options {
|
ruff: Some(Options {
|
||||||
allowed_confusables: None,
|
allowed_confusables: None,
|
||||||
|
builtins: None,
|
||||||
cache_dir: None,
|
cache_dir: None,
|
||||||
dummy_variable_rgx: None,
|
dummy_variable_rgx: None,
|
||||||
exclude: None,
|
exclude: None,
|
||||||
|
|
@ -393,6 +397,7 @@ ignore = ["E501"]
|
||||||
Some(Tools {
|
Some(Tools {
|
||||||
ruff: Some(Options {
|
ruff: Some(Options {
|
||||||
allowed_confusables: None,
|
allowed_confusables: None,
|
||||||
|
builtins: None,
|
||||||
cache_dir: None,
|
cache_dir: None,
|
||||||
dummy_variable_rgx: None,
|
dummy_variable_rgx: None,
|
||||||
exclude: None,
|
exclude: None,
|
||||||
|
|
@ -485,6 +490,7 @@ other-attribute = 1
|
||||||
config,
|
config,
|
||||||
Options {
|
Options {
|
||||||
allowed_confusables: Some(vec!['−', 'ρ', '∗']),
|
allowed_confusables: Some(vec!['−', 'ρ', '∗']),
|
||||||
|
builtins: None,
|
||||||
line_length: Some(88),
|
line_length: Some(88),
|
||||||
fix: None,
|
fix: None,
|
||||||
fix_only: None,
|
fix_only: None,
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue