mirror of
https://github.com/astral-sh/ruff.git
synced 2025-09-26 11:59:10 +00:00
--show-settings
displays active settings in a far more readable format (#9464)
<!-- Thank you for contributing to Ruff! To help us out with reviewing, please consider the following: - Does this pull request include a summary of the change? (See below.) - Does this pull request include a descriptive title? - Does this pull request include references to any relevant issues? --> ## Summary Fixes #8334. `Display` has been implemented for `ruff_workspace::Settings`, which gives a much nicer and more readable output to `--show-settings`. Internally, a `display_settings` utility macro has been implemented to reduce the boilerplate of the display code. ### Work to be done - [x] A lot of formatting for `Vec<_>` and `HashSet<_>` types have been stubbed out, using `Debug` as a fallback. There should be a way to add generic formatting support for these types as a modifier in `display_settings`. - [x] Several complex types were also stubbed out and need proper `Display` implementations rather than falling back on `Debug`. - [x] An open question needs to be answered: how important is it that the output be valid TOML? Some types in settings, such as a hash-map from a glob pattern to a multi-variant enum, will be hard to rework into valid _and_ readable TOML. - [x] Tests need to be implemented. ## Test Plan Tests consist of a snapshot test for the default `--show-settings` output and a doctest for `display_settings!`.
This commit is contained in:
parent
fee64b52ba
commit
7504bf347b
39 changed files with 1455 additions and 43 deletions
|
@ -35,7 +35,7 @@ pub(crate) fn show_settings(
|
||||||
if let Some(settings_path) = pyproject_config.path.as_ref() {
|
if let Some(settings_path) = pyproject_config.path.as_ref() {
|
||||||
writeln!(writer, "Settings path: {settings_path:?}")?;
|
writeln!(writer, "Settings path: {settings_path:?}")?;
|
||||||
}
|
}
|
||||||
writeln!(writer, "{settings:#?}")?;
|
write!(writer, "{settings}")?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
29
crates/ruff_cli/tests/show_settings.rs
Normal file
29
crates/ruff_cli/tests/show_settings.rs
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
use insta_cmd::{assert_cmd_snapshot, get_cargo_bin};
|
||||||
|
use std::path::Path;
|
||||||
|
use std::process::Command;
|
||||||
|
|
||||||
|
const BIN_NAME: &str = "ruff";
|
||||||
|
|
||||||
|
#[cfg(not(target_os = "windows"))]
|
||||||
|
const TEST_FILTERS: &[(&str, &str)] = &[
|
||||||
|
("\"[^\\*\"]*/pyproject.toml", "\"[BASEPATH]/pyproject.toml"),
|
||||||
|
("\".*/crates", "\"[BASEPATH]/crates"),
|
||||||
|
("\".*/\\.ruff_cache", "\"[BASEPATH]/.ruff_cache"),
|
||||||
|
("\".*/ruff\"", "\"[BASEPATH]\""),
|
||||||
|
];
|
||||||
|
#[cfg(target_os = "windows")]
|
||||||
|
const TEST_FILTERS: &[(&str, &str)] = &[
|
||||||
|
(r#""[^\*"]*\\pyproject.toml"#, "\"[BASEPATH]/pyproject.toml"),
|
||||||
|
(r#"".*\\crates"#, "\"[BASEPATH]/crates"),
|
||||||
|
(r#"".*\\\.ruff_cache"#, "\"[BASEPATH]/.ruff_cache"),
|
||||||
|
(r#"".*\\ruff""#, "\"[BASEPATH]\""),
|
||||||
|
(r#"\\+(\w\w|\s|")"#, "/$1"),
|
||||||
|
];
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn display_default_settings() {
|
||||||
|
insta::with_settings!({ filters => TEST_FILTERS.to_vec() }, {
|
||||||
|
assert_cmd_snapshot!(Command::new(get_cargo_bin(BIN_NAME))
|
||||||
|
.args(["check", "--show-settings", "unformatted.py"]).current_dir(Path::new("./resources/test/fixtures")));
|
||||||
|
});
|
||||||
|
}
|
|
@ -0,0 +1,368 @@
|
||||||
|
---
|
||||||
|
source: crates/ruff_cli/tests/show_settings.rs
|
||||||
|
info:
|
||||||
|
program: ruff
|
||||||
|
args:
|
||||||
|
- check
|
||||||
|
- "--show-settings"
|
||||||
|
- unformatted.py
|
||||||
|
---
|
||||||
|
success: true
|
||||||
|
exit_code: 0
|
||||||
|
----- stdout -----
|
||||||
|
Resolved settings for: "[BASEPATH]/crates/ruff_cli/resources/test/fixtures/unformatted.py"
|
||||||
|
Settings path: "[BASEPATH]/pyproject.toml"
|
||||||
|
|
||||||
|
# General Settings
|
||||||
|
cache_dir = "[BASEPATH]/.ruff_cache"
|
||||||
|
fix = false
|
||||||
|
fix_only = false
|
||||||
|
output_format = text
|
||||||
|
show_fixes = false
|
||||||
|
show_source = false
|
||||||
|
unsafe_fixes = hint
|
||||||
|
|
||||||
|
# File Resolver Settings
|
||||||
|
file_resolver.exclude = [
|
||||||
|
".bzr",
|
||||||
|
".direnv",
|
||||||
|
".eggs",
|
||||||
|
".git",
|
||||||
|
".git-rewrite",
|
||||||
|
".hg",
|
||||||
|
".ipynb_checkpoints",
|
||||||
|
".mypy_cache",
|
||||||
|
".nox",
|
||||||
|
".pants.d",
|
||||||
|
".pyenv",
|
||||||
|
".pytest_cache",
|
||||||
|
".pytype",
|
||||||
|
".ruff_cache",
|
||||||
|
".svn",
|
||||||
|
".tox",
|
||||||
|
".venv",
|
||||||
|
".vscode",
|
||||||
|
"__pypackages__",
|
||||||
|
"_build",
|
||||||
|
"buck-out",
|
||||||
|
"build",
|
||||||
|
"dist",
|
||||||
|
"node_modules",
|
||||||
|
"site-packages",
|
||||||
|
"venv",
|
||||||
|
]
|
||||||
|
file_resolver.extend_exclude = [
|
||||||
|
"crates/ruff_linter/resources/",
|
||||||
|
"crates/ruff_python_formatter/resources/",
|
||||||
|
]
|
||||||
|
file_resolver.force_exclude = false
|
||||||
|
file_resolver.include = [
|
||||||
|
"*.py",
|
||||||
|
"*.pyi",
|
||||||
|
"**/pyproject.toml",
|
||||||
|
]
|
||||||
|
file_resolver.extend_include = []
|
||||||
|
file_resolver.respect_gitignore = true
|
||||||
|
file_resolver.project_root = "[BASEPATH]"
|
||||||
|
|
||||||
|
# Linter Settings
|
||||||
|
linter.exclude = []
|
||||||
|
linter.project_root = "[BASEPATH]"
|
||||||
|
linter.rules.enabled = [
|
||||||
|
MultipleImportsOnOneLine,
|
||||||
|
ModuleImportNotAtTopOfFile,
|
||||||
|
MultipleStatementsOnOneLineColon,
|
||||||
|
MultipleStatementsOnOneLineSemicolon,
|
||||||
|
UselessSemicolon,
|
||||||
|
NoneComparison,
|
||||||
|
TrueFalseComparison,
|
||||||
|
NotInTest,
|
||||||
|
NotIsTest,
|
||||||
|
TypeComparison,
|
||||||
|
BareExcept,
|
||||||
|
LambdaAssignment,
|
||||||
|
AmbiguousVariableName,
|
||||||
|
AmbiguousClassName,
|
||||||
|
AmbiguousFunctionName,
|
||||||
|
IOError,
|
||||||
|
SyntaxError,
|
||||||
|
UnusedImport,
|
||||||
|
ImportShadowedByLoopVar,
|
||||||
|
UndefinedLocalWithImportStar,
|
||||||
|
LateFutureImport,
|
||||||
|
UndefinedLocalWithImportStarUsage,
|
||||||
|
UndefinedLocalWithNestedImportStarUsage,
|
||||||
|
FutureFeatureNotDefined,
|
||||||
|
PercentFormatInvalidFormat,
|
||||||
|
PercentFormatExpectedMapping,
|
||||||
|
PercentFormatExpectedSequence,
|
||||||
|
PercentFormatExtraNamedArguments,
|
||||||
|
PercentFormatMissingArgument,
|
||||||
|
PercentFormatMixedPositionalAndNamed,
|
||||||
|
PercentFormatPositionalCountMismatch,
|
||||||
|
PercentFormatStarRequiresSequence,
|
||||||
|
PercentFormatUnsupportedFormatCharacter,
|
||||||
|
StringDotFormatInvalidFormat,
|
||||||
|
StringDotFormatExtraNamedArguments,
|
||||||
|
StringDotFormatExtraPositionalArguments,
|
||||||
|
StringDotFormatMissingArguments,
|
||||||
|
StringDotFormatMixingAutomatic,
|
||||||
|
FStringMissingPlaceholders,
|
||||||
|
MultiValueRepeatedKeyLiteral,
|
||||||
|
MultiValueRepeatedKeyVariable,
|
||||||
|
ExpressionsInStarAssignment,
|
||||||
|
MultipleStarredExpressions,
|
||||||
|
AssertTuple,
|
||||||
|
IsLiteral,
|
||||||
|
InvalidPrintSyntax,
|
||||||
|
IfTuple,
|
||||||
|
BreakOutsideLoop,
|
||||||
|
ContinueOutsideLoop,
|
||||||
|
YieldOutsideFunction,
|
||||||
|
ReturnOutsideFunction,
|
||||||
|
DefaultExceptNotLast,
|
||||||
|
ForwardAnnotationSyntaxError,
|
||||||
|
RedefinedWhileUnused,
|
||||||
|
UndefinedName,
|
||||||
|
UndefinedExport,
|
||||||
|
UndefinedLocal,
|
||||||
|
UnusedVariable,
|
||||||
|
UnusedAnnotation,
|
||||||
|
RaiseNotImplemented,
|
||||||
|
]
|
||||||
|
linter.rules.should_fix = [
|
||||||
|
MultipleImportsOnOneLine,
|
||||||
|
ModuleImportNotAtTopOfFile,
|
||||||
|
MultipleStatementsOnOneLineColon,
|
||||||
|
MultipleStatementsOnOneLineSemicolon,
|
||||||
|
UselessSemicolon,
|
||||||
|
NoneComparison,
|
||||||
|
TrueFalseComparison,
|
||||||
|
NotInTest,
|
||||||
|
NotIsTest,
|
||||||
|
TypeComparison,
|
||||||
|
BareExcept,
|
||||||
|
LambdaAssignment,
|
||||||
|
AmbiguousVariableName,
|
||||||
|
AmbiguousClassName,
|
||||||
|
AmbiguousFunctionName,
|
||||||
|
IOError,
|
||||||
|
SyntaxError,
|
||||||
|
UnusedImport,
|
||||||
|
ImportShadowedByLoopVar,
|
||||||
|
UndefinedLocalWithImportStar,
|
||||||
|
LateFutureImport,
|
||||||
|
UndefinedLocalWithImportStarUsage,
|
||||||
|
UndefinedLocalWithNestedImportStarUsage,
|
||||||
|
FutureFeatureNotDefined,
|
||||||
|
PercentFormatInvalidFormat,
|
||||||
|
PercentFormatExpectedMapping,
|
||||||
|
PercentFormatExpectedSequence,
|
||||||
|
PercentFormatExtraNamedArguments,
|
||||||
|
PercentFormatMissingArgument,
|
||||||
|
PercentFormatMixedPositionalAndNamed,
|
||||||
|
PercentFormatPositionalCountMismatch,
|
||||||
|
PercentFormatStarRequiresSequence,
|
||||||
|
PercentFormatUnsupportedFormatCharacter,
|
||||||
|
StringDotFormatInvalidFormat,
|
||||||
|
StringDotFormatExtraNamedArguments,
|
||||||
|
StringDotFormatExtraPositionalArguments,
|
||||||
|
StringDotFormatMissingArguments,
|
||||||
|
StringDotFormatMixingAutomatic,
|
||||||
|
FStringMissingPlaceholders,
|
||||||
|
MultiValueRepeatedKeyLiteral,
|
||||||
|
MultiValueRepeatedKeyVariable,
|
||||||
|
ExpressionsInStarAssignment,
|
||||||
|
MultipleStarredExpressions,
|
||||||
|
AssertTuple,
|
||||||
|
IsLiteral,
|
||||||
|
InvalidPrintSyntax,
|
||||||
|
IfTuple,
|
||||||
|
BreakOutsideLoop,
|
||||||
|
ContinueOutsideLoop,
|
||||||
|
YieldOutsideFunction,
|
||||||
|
ReturnOutsideFunction,
|
||||||
|
DefaultExceptNotLast,
|
||||||
|
ForwardAnnotationSyntaxError,
|
||||||
|
RedefinedWhileUnused,
|
||||||
|
UndefinedName,
|
||||||
|
UndefinedExport,
|
||||||
|
UndefinedLocal,
|
||||||
|
UnusedVariable,
|
||||||
|
UnusedAnnotation,
|
||||||
|
RaiseNotImplemented,
|
||||||
|
]
|
||||||
|
linter.per_file_ignores = {}
|
||||||
|
linter.safety_table.forced_safe = []
|
||||||
|
linter.safety_table.forced_unsafe = []
|
||||||
|
linter.target_version = Py37
|
||||||
|
linter.preview = disabled
|
||||||
|
linter.explicit_preview_rules = false
|
||||||
|
linter.extension.mapping = {}
|
||||||
|
linter.allowed_confusables = []
|
||||||
|
linter.builtins = []
|
||||||
|
linter.dummy_variable_rgx = ^(_+|(_+[a-zA-Z0-9_]*[a-zA-Z0-9]+?))$
|
||||||
|
linter.external = []
|
||||||
|
linter.ignore_init_module_imports = false
|
||||||
|
linter.logger_objects = []
|
||||||
|
linter.namespace_packages = []
|
||||||
|
linter.src = ["[BASEPATH]"]
|
||||||
|
linter.tab_size = 4
|
||||||
|
linter.line_length = 88
|
||||||
|
linter.task_tags = [
|
||||||
|
TODO,
|
||||||
|
FIXME,
|
||||||
|
XXX,
|
||||||
|
]
|
||||||
|
linter.typing_modules = []
|
||||||
|
|
||||||
|
# Linter Plugins
|
||||||
|
linter.flake8_annotations.mypy_init_return = false
|
||||||
|
linter.flake8_annotations.suppress_dummy_args = false
|
||||||
|
linter.flake8_annotations.suppress_none_returning = false
|
||||||
|
linter.flake8_annotations.allow_star_arg_any = false
|
||||||
|
linter.flake8_annotations.ignore_fully_untyped = false
|
||||||
|
linter.flake8_bandit.hardcoded_tmp_directory = [
|
||||||
|
/tmp,
|
||||||
|
/var/tmp,
|
||||||
|
/dev/shm,
|
||||||
|
]
|
||||||
|
linter.flake8_bandit.check_typed_exception = false
|
||||||
|
linter.flake8_bugbear.extend_immutable_calls = []
|
||||||
|
linter.flake8_builtins.builtins_ignorelist = []
|
||||||
|
linter.flake8_comprehensions.allow_dict_calls_with_keyword_arguments = false
|
||||||
|
linter.flake8_copyright.notice_rgx = (?i)Copyright\s+(\(C\)\s+)?\d{4}(-\d{4})*
|
||||||
|
linter.flake8_copyright.author = none
|
||||||
|
linter.flake8_copyright.min_file_size = 0
|
||||||
|
linter.flake8_errmsg.max_string_length = 0
|
||||||
|
linter.flake8_gettext.functions_names = [
|
||||||
|
_,
|
||||||
|
gettext,
|
||||||
|
ngettext,
|
||||||
|
]
|
||||||
|
linter.flake8_implicit_str_concat.allow_multiline = true
|
||||||
|
linter.flake8_import_conventions.aliases = {"matplotlib": "mpl", "matplotlib.pyplot": "plt", "pandas": "pd", "seaborn": "sns", "tensorflow": "tf", "networkx": "nx", "plotly.express": "px", "polars": "pl", "numpy": "np", "panel": "pn", "pyarrow": "pa", "altair": "alt", "tkinter": "tk", "holoviews": "hv"}
|
||||||
|
linter.flake8_import_conventions.banned_aliases = {}
|
||||||
|
linter.flake8_import_conventions.banned_from = []
|
||||||
|
linter.flake8_pytest_style.fixture_parentheses = true
|
||||||
|
linter.flake8_pytest_style.parametrize_names_type = tuple
|
||||||
|
linter.flake8_pytest_style.parametrize_values_type = list
|
||||||
|
linter.flake8_pytest_style.parametrize_values_row_type = tuple
|
||||||
|
linter.flake8_pytest_style.raises_require_match_for = [
|
||||||
|
BaseException,
|
||||||
|
Exception,
|
||||||
|
ValueError,
|
||||||
|
OSError,
|
||||||
|
IOError,
|
||||||
|
EnvironmentError,
|
||||||
|
socket.error,
|
||||||
|
]
|
||||||
|
linter.flake8_pytest_style.raises_extend_require_match_for = []
|
||||||
|
linter.flake8_pytest_style.mark_parentheses = true
|
||||||
|
linter.flake8_quotes.inline_quotes = double
|
||||||
|
linter.flake8_quotes.multiline_quotes = double
|
||||||
|
linter.flake8_quotes.docstring_quotes = double
|
||||||
|
linter.flake8_quotes.avoid_escape = true
|
||||||
|
linter.flake8_self.ignore_names = [
|
||||||
|
_make,
|
||||||
|
_asdict,
|
||||||
|
_replace,
|
||||||
|
_fields,
|
||||||
|
_field_defaults,
|
||||||
|
_name_,
|
||||||
|
_value_,
|
||||||
|
]
|
||||||
|
linter.flake8_tidy_imports.ban_relative_imports = "parents"
|
||||||
|
linter.flake8_tidy_imports.banned_api = {}
|
||||||
|
linter.flake8_tidy_imports.banned_module_level_imports = []
|
||||||
|
linter.flake8_type_checking.strict = false
|
||||||
|
linter.flake8_type_checking.exempt_modules = [
|
||||||
|
typing,
|
||||||
|
typing_extensions,
|
||||||
|
]
|
||||||
|
linter.flake8_type_checking.runtime_required_base_classes = []
|
||||||
|
linter.flake8_type_checking.runtime_required_decorators = []
|
||||||
|
linter.flake8_type_checking.quote_annotations = false
|
||||||
|
linter.flake8_unused_arguments.ignore_variadic_names = false
|
||||||
|
linter.isort.required_imports = []
|
||||||
|
linter.isort.combine_as_imports = false
|
||||||
|
linter.isort.force_single_line = false
|
||||||
|
linter.isort.force_sort_within_sections = false
|
||||||
|
linter.isort.detect_same_package = true
|
||||||
|
linter.isort.case_sensitive = false
|
||||||
|
linter.isort.force_wrap_aliases = false
|
||||||
|
linter.isort.force_to_top = []
|
||||||
|
linter.isort.known_modules = {}
|
||||||
|
linter.isort.order_by_type = true
|
||||||
|
linter.isort.relative_imports_order = furthest_to_closest
|
||||||
|
linter.isort.single_line_exclusions = []
|
||||||
|
linter.isort.split_on_trailing_comma = true
|
||||||
|
linter.isort.classes = []
|
||||||
|
linter.isort.constants = []
|
||||||
|
linter.isort.variables = []
|
||||||
|
linter.isort.no_lines_before = []
|
||||||
|
linter.isort.lines_after_imports = -1
|
||||||
|
linter.isort.lines_between_types = 0
|
||||||
|
linter.isort.forced_separate = []
|
||||||
|
linter.isort.section_order = [
|
||||||
|
known { type = future },
|
||||||
|
known { type = standard_library },
|
||||||
|
known { type = third_party },
|
||||||
|
known { type = first_party },
|
||||||
|
known { type = local_folder },
|
||||||
|
]
|
||||||
|
linter.isort.no_sections = false
|
||||||
|
linter.isort.from_first = false
|
||||||
|
linter.isort.length_sort = false
|
||||||
|
linter.isort.length_sort_straight = false
|
||||||
|
linter.mccabe.max_complexity = 10
|
||||||
|
linter.pep8_naming.ignore_names = [
|
||||||
|
setUp,
|
||||||
|
tearDown,
|
||||||
|
setUpClass,
|
||||||
|
tearDownClass,
|
||||||
|
setUpModule,
|
||||||
|
tearDownModule,
|
||||||
|
asyncSetUp,
|
||||||
|
asyncTearDown,
|
||||||
|
setUpTestData,
|
||||||
|
failureException,
|
||||||
|
longMessage,
|
||||||
|
maxDiff,
|
||||||
|
]
|
||||||
|
linter.pep8_naming.classmethod_decorators = []
|
||||||
|
linter.pep8_naming.staticmethod_decorators = []
|
||||||
|
linter.pycodestyle.max_line_length = 88
|
||||||
|
linter.pycodestyle.max_doc_length = none
|
||||||
|
linter.pycodestyle.ignore_overlong_task_comments = false
|
||||||
|
linter.pyflakes.extend_generics = []
|
||||||
|
linter.pylint.allow_magic_value_types = [
|
||||||
|
str,
|
||||||
|
bytes,
|
||||||
|
]
|
||||||
|
linter.pylint.allow_dunder_method_names = []
|
||||||
|
linter.pylint.max_args = 5
|
||||||
|
linter.pylint.max_positional_args = 5
|
||||||
|
linter.pylint.max_returns = 6
|
||||||
|
linter.pylint.max_bool_expr = 5
|
||||||
|
linter.pylint.max_branches = 12
|
||||||
|
linter.pylint.max_statements = 50
|
||||||
|
linter.pylint.max_public_methods = 20
|
||||||
|
linter.pylint.max_locals = 15
|
||||||
|
linter.pyupgrade.keep_runtime_typing = false
|
||||||
|
|
||||||
|
# Formatter Settings
|
||||||
|
formatter.exclude = []
|
||||||
|
formatter.target_version = Py37
|
||||||
|
formatter.preview = disabled
|
||||||
|
formatter.line_width = 88
|
||||||
|
formatter.line_ending = auto
|
||||||
|
formatter.indent_style = space
|
||||||
|
formatter.indent_width = 4
|
||||||
|
formatter.quote_style = double
|
||||||
|
formatter.magic_trailing_comma = respect
|
||||||
|
formatter.docstring_code_format = disabled
|
||||||
|
formatter.docstring_code_line_width = dynamic
|
||||||
|
|
||||||
|
----- stderr -----
|
||||||
|
|
|
@ -35,6 +35,7 @@ mod source_code;
|
||||||
use crate::formatter::Formatter;
|
use crate::formatter::Formatter;
|
||||||
use crate::group_id::UniqueGroupIdBuilder;
|
use crate::group_id::UniqueGroupIdBuilder;
|
||||||
use crate::prelude::TagKind;
|
use crate::prelude::TagKind;
|
||||||
|
use std::fmt;
|
||||||
use std::fmt::{Debug, Display};
|
use std::fmt::{Debug, Display};
|
||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
use std::num::{NonZeroU16, NonZeroU8, TryFromIntError};
|
use std::num::{NonZeroU16, NonZeroU8, TryFromIntError};
|
||||||
|
@ -113,6 +114,12 @@ impl Default for IndentWidth {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Display for IndentWidth {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
|
Display::fmt(&self.0, f)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl TryFrom<u8> for IndentWidth {
|
impl TryFrom<u8> for IndentWidth {
|
||||||
type Error = TryFromIntError;
|
type Error = TryFromIntError;
|
||||||
|
|
||||||
|
@ -146,6 +153,12 @@ impl Default for LineWidth {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Display for LineWidth {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
|
Display::fmt(&self.0, f)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl TryFrom<u16> for LineWidth {
|
impl TryFrom<u16> for LineWidth {
|
||||||
type Error = TryFromIntError;
|
type Error = TryFromIntError;
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
use std::error::Error;
|
use std::error::Error;
|
||||||
|
use std::fmt;
|
||||||
use std::hash::Hasher;
|
use std::hash::Hasher;
|
||||||
use std::num::{NonZeroU16, NonZeroU8, ParseIntError};
|
use std::num::{NonZeroU16, NonZeroU8, ParseIntError};
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
|
@ -39,6 +40,12 @@ impl Default for LineLength {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl fmt::Display for LineLength {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
|
fmt::Display::fmt(&self.0, f)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl CacheKey for LineLength {
|
impl CacheKey for LineLength {
|
||||||
fn cache_key(&self, state: &mut CacheKeyHasher) {
|
fn cache_key(&self, state: &mut CacheKeyHasher) {
|
||||||
state.write_u16(self.0.get());
|
state.write_u16(self.0.get());
|
||||||
|
@ -248,6 +255,12 @@ impl Default for IndentWidth {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl fmt::Display for IndentWidth {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
|
fmt::Display::fmt(&self.0, f)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl From<NonZeroU8> for IndentWidth {
|
impl From<NonZeroU8> for IndentWidth {
|
||||||
fn from(tab_size: NonZeroU8) -> Self {
|
fn from(tab_size: NonZeroU8) -> Self {
|
||||||
Self(tab_size)
|
Self(tab_size)
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use crate::registry::Rule;
|
use crate::registry::Rule;
|
||||||
use ruff_macros::CacheKey;
|
use ruff_macros::CacheKey;
|
||||||
use std::fmt::{Debug, Formatter};
|
use std::fmt::{Debug, Display, Formatter};
|
||||||
use std::iter::FusedIterator;
|
use std::iter::FusedIterator;
|
||||||
|
|
||||||
const RULESET_SIZE: usize = 13;
|
const RULESET_SIZE: usize = 13;
|
||||||
|
@ -269,6 +269,21 @@ impl Debug for RuleSet {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Display for RuleSet {
|
||||||
|
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||||
|
if self.is_empty() {
|
||||||
|
write!(f, "[]")?;
|
||||||
|
} else {
|
||||||
|
writeln!(f, "[")?;
|
||||||
|
for rule in self {
|
||||||
|
writeln!(f, "\t{rule:?},")?;
|
||||||
|
}
|
||||||
|
write!(f, "]")?;
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl FromIterator<Rule> for RuleSet {
|
impl FromIterator<Rule> for RuleSet {
|
||||||
fn from_iter<T: IntoIterator<Item = Rule>>(iter: T) -> Self {
|
fn from_iter<T: IntoIterator<Item = Rule>>(iter: T) -> Self {
|
||||||
let mut set = RuleSet::empty();
|
let mut set = RuleSet::empty();
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
//! Settings for the `flake-annotations` plugin.
|
//! Settings for the `flake-annotations` plugin.
|
||||||
|
|
||||||
|
use crate::display_settings;
|
||||||
use ruff_macros::CacheKey;
|
use ruff_macros::CacheKey;
|
||||||
|
use std::fmt::{Display, Formatter};
|
||||||
|
|
||||||
#[derive(Debug, Default, CacheKey)]
|
#[derive(Debug, Default, CacheKey)]
|
||||||
#[allow(clippy::struct_excessive_bools)]
|
#[allow(clippy::struct_excessive_bools)]
|
||||||
|
@ -11,3 +13,20 @@ pub struct Settings {
|
||||||
pub allow_star_arg_any: bool,
|
pub allow_star_arg_any: bool,
|
||||||
pub ignore_fully_untyped: bool,
|
pub ignore_fully_untyped: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Display for Settings {
|
||||||
|
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||||
|
display_settings! {
|
||||||
|
formatter = f,
|
||||||
|
namespace = "linter.flake8_annotations",
|
||||||
|
fields = [
|
||||||
|
self.mypy_init_return,
|
||||||
|
self.suppress_dummy_args,
|
||||||
|
self.suppress_none_returning,
|
||||||
|
self.allow_star_arg_any,
|
||||||
|
self.ignore_fully_untyped
|
||||||
|
]
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
//! Settings for the `flake8-bandit` plugin.
|
//! Settings for the `flake8-bandit` plugin.
|
||||||
|
|
||||||
|
use crate::display_settings;
|
||||||
use ruff_macros::CacheKey;
|
use ruff_macros::CacheKey;
|
||||||
|
use std::fmt::{Display, Formatter};
|
||||||
|
|
||||||
pub fn default_tmp_dirs() -> Vec<String> {
|
pub fn default_tmp_dirs() -> Vec<String> {
|
||||||
["/tmp", "/var/tmp", "/dev/shm"]
|
["/tmp", "/var/tmp", "/dev/shm"]
|
||||||
|
@ -22,3 +24,17 @@ impl Default for Settings {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Display for Settings {
|
||||||
|
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||||
|
display_settings! {
|
||||||
|
formatter = f,
|
||||||
|
namespace = "linter.flake8_bandit",
|
||||||
|
fields = [
|
||||||
|
self.hardcoded_tmp_directory | array,
|
||||||
|
self.check_typed_exception
|
||||||
|
]
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,8 +1,23 @@
|
||||||
//! Settings for the `flake8-bugbear` plugin.
|
//! Settings for the `flake8-bugbear` plugin.
|
||||||
|
|
||||||
|
use crate::display_settings;
|
||||||
use ruff_macros::CacheKey;
|
use ruff_macros::CacheKey;
|
||||||
|
use std::fmt::{Display, Formatter};
|
||||||
|
|
||||||
#[derive(Debug, Default, CacheKey)]
|
#[derive(Debug, Default, CacheKey)]
|
||||||
pub struct Settings {
|
pub struct Settings {
|
||||||
pub extend_immutable_calls: Vec<String>,
|
pub extend_immutable_calls: Vec<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Display for Settings {
|
||||||
|
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||||
|
display_settings! {
|
||||||
|
formatter = f,
|
||||||
|
namespace = "linter.flake8_bugbear",
|
||||||
|
fields = [
|
||||||
|
self.extend_immutable_calls | array
|
||||||
|
]
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,8 +1,23 @@
|
||||||
//! Settings for the `flake8-builtins` plugin.
|
//! Settings for the `flake8-builtins` plugin.
|
||||||
|
|
||||||
|
use crate::display_settings;
|
||||||
use ruff_macros::CacheKey;
|
use ruff_macros::CacheKey;
|
||||||
|
use std::fmt::{Display, Formatter};
|
||||||
|
|
||||||
#[derive(Debug, Default, CacheKey)]
|
#[derive(Debug, Default, CacheKey)]
|
||||||
pub struct Settings {
|
pub struct Settings {
|
||||||
pub builtins_ignorelist: Vec<String>,
|
pub builtins_ignorelist: Vec<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Display for Settings {
|
||||||
|
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||||
|
display_settings! {
|
||||||
|
formatter = f,
|
||||||
|
namespace = "linter.flake8_builtins",
|
||||||
|
fields = [
|
||||||
|
self.builtins_ignorelist | array
|
||||||
|
]
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,8 +1,23 @@
|
||||||
//! Settings for the `flake8-comprehensions` plugin.
|
//! Settings for the `flake8-comprehensions` plugin.
|
||||||
|
|
||||||
|
use crate::display_settings;
|
||||||
use ruff_macros::CacheKey;
|
use ruff_macros::CacheKey;
|
||||||
|
use std::fmt::{Display, Formatter};
|
||||||
|
|
||||||
#[derive(Debug, Default, CacheKey)]
|
#[derive(Debug, Default, CacheKey)]
|
||||||
pub struct Settings {
|
pub struct Settings {
|
||||||
pub allow_dict_calls_with_keyword_arguments: bool,
|
pub allow_dict_calls_with_keyword_arguments: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Display for Settings {
|
||||||
|
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||||
|
display_settings! {
|
||||||
|
formatter = f,
|
||||||
|
namespace = "linter.flake8_comprehensions",
|
||||||
|
fields = [
|
||||||
|
self.allow_dict_calls_with_keyword_arguments
|
||||||
|
]
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -2,7 +2,9 @@
|
||||||
|
|
||||||
use once_cell::sync::Lazy;
|
use once_cell::sync::Lazy;
|
||||||
use regex::Regex;
|
use regex::Regex;
|
||||||
|
use std::fmt::{Display, Formatter};
|
||||||
|
|
||||||
|
use crate::display_settings;
|
||||||
use ruff_macros::CacheKey;
|
use ruff_macros::CacheKey;
|
||||||
|
|
||||||
#[derive(Debug, CacheKey)]
|
#[derive(Debug, CacheKey)]
|
||||||
|
@ -24,3 +26,18 @@ impl Default for Settings {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Display for Settings {
|
||||||
|
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||||
|
display_settings! {
|
||||||
|
formatter = f,
|
||||||
|
namespace = "linter.flake8_copyright",
|
||||||
|
fields = [
|
||||||
|
self.notice_rgx,
|
||||||
|
self.author | optional,
|
||||||
|
self.min_file_size,
|
||||||
|
]
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,8 +1,23 @@
|
||||||
//! Settings for the `flake8-errmsg` plugin.
|
//! Settings for the `flake8-errmsg` plugin.
|
||||||
|
|
||||||
|
use crate::display_settings;
|
||||||
use ruff_macros::CacheKey;
|
use ruff_macros::CacheKey;
|
||||||
|
use std::fmt::{Display, Formatter};
|
||||||
|
|
||||||
#[derive(Debug, Default, CacheKey)]
|
#[derive(Debug, Default, CacheKey)]
|
||||||
pub struct Settings {
|
pub struct Settings {
|
||||||
pub max_string_length: usize,
|
pub max_string_length: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Display for Settings {
|
||||||
|
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||||
|
display_settings! {
|
||||||
|
formatter = f,
|
||||||
|
namespace = "linter.flake8_errmsg",
|
||||||
|
fields = [
|
||||||
|
self.max_string_length
|
||||||
|
]
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
|
use crate::display_settings;
|
||||||
use ruff_macros::CacheKey;
|
use ruff_macros::CacheKey;
|
||||||
|
use std::fmt::{Display, Formatter};
|
||||||
|
|
||||||
#[derive(Debug, CacheKey)]
|
#[derive(Debug, CacheKey)]
|
||||||
pub struct Settings {
|
pub struct Settings {
|
||||||
|
@ -20,3 +22,16 @@ impl Default for Settings {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Display for Settings {
|
||||||
|
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||||
|
display_settings! {
|
||||||
|
formatter = f,
|
||||||
|
namespace = "linter.flake8_gettext",
|
||||||
|
fields = [
|
||||||
|
self.functions_names | array
|
||||||
|
]
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
//! Settings for the `flake8-implicit-str-concat` plugin.
|
//! Settings for the `flake8-implicit-str-concat` plugin.
|
||||||
|
|
||||||
|
use crate::display_settings;
|
||||||
use ruff_macros::CacheKey;
|
use ruff_macros::CacheKey;
|
||||||
|
use std::fmt::{Display, Formatter};
|
||||||
|
|
||||||
#[derive(Debug, CacheKey)]
|
#[derive(Debug, CacheKey)]
|
||||||
pub struct Settings {
|
pub struct Settings {
|
||||||
|
@ -14,3 +16,16 @@ impl Default for Settings {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Display for Settings {
|
||||||
|
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||||
|
display_settings! {
|
||||||
|
formatter = f,
|
||||||
|
namespace = "linter.flake8_implicit_str_concat",
|
||||||
|
fields = [
|
||||||
|
self.allow_multiline
|
||||||
|
]
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
//! Settings for import conventions.
|
//! Settings for import conventions.
|
||||||
|
|
||||||
use rustc_hash::{FxHashMap, FxHashSet};
|
use rustc_hash::{FxHashMap, FxHashSet};
|
||||||
|
use std::fmt::{Display, Formatter};
|
||||||
|
|
||||||
|
use crate::display_settings;
|
||||||
use ruff_macros::CacheKey;
|
use ruff_macros::CacheKey;
|
||||||
|
|
||||||
const CONVENTIONAL_ALIASES: &[(&str, &str)] = &[
|
const CONVENTIONAL_ALIASES: &[(&str, &str)] = &[
|
||||||
|
@ -44,3 +46,18 @@ impl Default for Settings {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Display for Settings {
|
||||||
|
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||||
|
display_settings! {
|
||||||
|
formatter = f,
|
||||||
|
namespace = "linter.flake8_import_conventions",
|
||||||
|
fields = [
|
||||||
|
self.aliases | debug,
|
||||||
|
self.banned_aliases | debug,
|
||||||
|
self.banned_from | array,
|
||||||
|
]
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
//! Settings for the `flake8-pytest-style` plugin.
|
//! Settings for the `flake8-pytest-style` plugin.
|
||||||
use std::error::Error;
|
use std::error::Error;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
use std::fmt::Formatter;
|
||||||
|
|
||||||
|
use crate::display_settings;
|
||||||
use ruff_macros::CacheKey;
|
use ruff_macros::CacheKey;
|
||||||
|
|
||||||
use crate::settings::types::IdentifierPattern;
|
use crate::settings::types::IdentifierPattern;
|
||||||
|
@ -47,6 +49,25 @@ impl Default for Settings {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl fmt::Display for Settings {
|
||||||
|
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||||
|
display_settings! {
|
||||||
|
formatter = f,
|
||||||
|
namespace = "linter.flake8_pytest_style",
|
||||||
|
fields = [
|
||||||
|
self.fixture_parentheses,
|
||||||
|
self.parametrize_names_type,
|
||||||
|
self.parametrize_values_type,
|
||||||
|
self.parametrize_values_row_type,
|
||||||
|
self.raises_require_match_for | array,
|
||||||
|
self.raises_extend_require_match_for | array,
|
||||||
|
self.mark_parentheses
|
||||||
|
]
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Error returned by the [`TryFrom`] implementation of [`Settings`].
|
/// Error returned by the [`TryFrom`] implementation of [`Settings`].
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum SettingsError {
|
pub enum SettingsError {
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
//! Settings for the `flake8-quotes` plugin.
|
//! Settings for the `flake8-quotes` plugin.
|
||||||
|
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
use std::fmt::{Display, Formatter};
|
||||||
|
|
||||||
|
use crate::display_settings;
|
||||||
use ruff_macros::CacheKey;
|
use ruff_macros::CacheKey;
|
||||||
|
|
||||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, Serialize, Deserialize, CacheKey)]
|
#[derive(Debug, Copy, Clone, PartialEq, Eq, Serialize, Deserialize, CacheKey)]
|
||||||
|
@ -39,6 +41,22 @@ impl Default for Settings {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Display for Settings {
|
||||||
|
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||||
|
display_settings! {
|
||||||
|
formatter = f,
|
||||||
|
namespace = "linter.flake8_quotes",
|
||||||
|
fields = [
|
||||||
|
self.inline_quotes,
|
||||||
|
self.multiline_quotes,
|
||||||
|
self.docstring_quotes,
|
||||||
|
self.avoid_escape
|
||||||
|
]
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Quote {
|
impl Quote {
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub const fn opposite(self) -> Self {
|
pub const fn opposite(self) -> Self {
|
||||||
|
@ -56,3 +74,12 @@ impl Quote {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Display for Quote {
|
||||||
|
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||||
|
match self {
|
||||||
|
Self::Double => write!(f, "double"),
|
||||||
|
Self::Single => write!(f, "single"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
//! Settings for the `flake8-self` plugin.
|
//! Settings for the `flake8-self` plugin.
|
||||||
|
|
||||||
|
use crate::display_settings;
|
||||||
use ruff_macros::CacheKey;
|
use ruff_macros::CacheKey;
|
||||||
|
use std::fmt::{Display, Formatter};
|
||||||
|
|
||||||
// By default, ignore the `namedtuple` methods and attributes, as well as the
|
// By default, ignore the `namedtuple` methods and attributes, as well as the
|
||||||
// _sunder_ names in Enum, which are underscore-prefixed to prevent conflicts
|
// _sunder_ names in Enum, which are underscore-prefixed to prevent conflicts
|
||||||
|
@ -27,3 +29,16 @@ impl Default for Settings {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Display for Settings {
|
||||||
|
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||||
|
display_settings! {
|
||||||
|
formatter = f,
|
||||||
|
namespace = "linter.flake8_self",
|
||||||
|
fields = [
|
||||||
|
self.ignore_names | array
|
||||||
|
]
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
use rustc_hash::FxHashMap;
|
use rustc_hash::FxHashMap;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
use std::fmt::{Display, Formatter};
|
||||||
|
|
||||||
|
use crate::display_settings;
|
||||||
use ruff_macros::CacheKey;
|
use ruff_macros::CacheKey;
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, CacheKey)]
|
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, CacheKey)]
|
||||||
|
@ -22,9 +24,33 @@ pub enum Strictness {
|
||||||
All,
|
All,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Display for Strictness {
|
||||||
|
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||||
|
match self {
|
||||||
|
Self::Parents => write!(f, "\"parents\""),
|
||||||
|
Self::All => write!(f, "\"all\""),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, CacheKey, Default)]
|
#[derive(Debug, CacheKey, Default)]
|
||||||
pub struct Settings {
|
pub struct Settings {
|
||||||
pub ban_relative_imports: Strictness,
|
pub ban_relative_imports: Strictness,
|
||||||
pub banned_api: FxHashMap<String, ApiBan>,
|
pub banned_api: FxHashMap<String, ApiBan>,
|
||||||
pub banned_module_level_imports: Vec<String>,
|
pub banned_module_level_imports: Vec<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Display for Settings {
|
||||||
|
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||||
|
display_settings! {
|
||||||
|
formatter = f,
|
||||||
|
namespace = "linter.flake8_tidy_imports",
|
||||||
|
fields = [
|
||||||
|
self.ban_relative_imports,
|
||||||
|
self.banned_api | debug,
|
||||||
|
self.banned_module_level_imports | array,
|
||||||
|
]
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
//! Settings for the `flake8-type-checking` plugin.
|
//! Settings for the `flake8-type-checking` plugin.
|
||||||
|
|
||||||
|
use crate::display_settings;
|
||||||
use ruff_macros::CacheKey;
|
use ruff_macros::CacheKey;
|
||||||
|
use std::fmt::{Display, Formatter};
|
||||||
|
|
||||||
#[derive(Debug, CacheKey)]
|
#[derive(Debug, CacheKey)]
|
||||||
pub struct Settings {
|
pub struct Settings {
|
||||||
|
@ -22,3 +24,20 @@ impl Default for Settings {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Display for Settings {
|
||||||
|
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||||
|
display_settings! {
|
||||||
|
formatter = f,
|
||||||
|
namespace = "linter.flake8_type_checking",
|
||||||
|
fields = [
|
||||||
|
self.strict,
|
||||||
|
self.exempt_modules | array,
|
||||||
|
self.runtime_required_base_classes | array,
|
||||||
|
self.runtime_required_decorators | array,
|
||||||
|
self.quote_annotations
|
||||||
|
]
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,8 +1,23 @@
|
||||||
//! Settings for the `flake8-unused-arguments` plugin.
|
//! Settings for the `flake8-unused-arguments` plugin.
|
||||||
|
|
||||||
|
use crate::display_settings;
|
||||||
use ruff_macros::CacheKey;
|
use ruff_macros::CacheKey;
|
||||||
|
use std::fmt::{Display, Formatter};
|
||||||
|
|
||||||
#[derive(Debug, Default, CacheKey)]
|
#[derive(Debug, Default, CacheKey)]
|
||||||
pub struct Settings {
|
pub struct Settings {
|
||||||
pub ignore_variadic_names: bool,
|
pub ignore_variadic_names: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Display for Settings {
|
||||||
|
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||||
|
display_settings! {
|
||||||
|
formatter = f,
|
||||||
|
namespace = "linter.flake8_unused_arguments",
|
||||||
|
fields = [
|
||||||
|
self.ignore_variadic_names
|
||||||
|
]
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
use std::collections::BTreeMap;
|
use std::collections::BTreeMap;
|
||||||
|
use std::fmt;
|
||||||
use std::hash::BuildHasherDefault;
|
use std::hash::BuildHasherDefault;
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
use std::{fs, iter};
|
use std::{fs, iter};
|
||||||
|
@ -40,6 +41,18 @@ pub enum ImportType {
|
||||||
LocalFolder,
|
LocalFolder,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl fmt::Display for ImportType {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
|
match self {
|
||||||
|
Self::Future => write!(f, "future"),
|
||||||
|
Self::StandardLibrary => write!(f, "standard_library"),
|
||||||
|
Self::ThirdParty => write!(f, "third_party"),
|
||||||
|
Self::FirstParty => write!(f, "first_party"),
|
||||||
|
Self::LocalFolder => write!(f, "local_folder"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialOrd, Ord, PartialEq, Eq, Clone, Hash, Serialize, Deserialize, CacheKey)]
|
#[derive(Debug, PartialOrd, Ord, PartialEq, Eq, Clone, Hash, Serialize, Deserialize, CacheKey)]
|
||||||
#[serde(untagged)]
|
#[serde(untagged)]
|
||||||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||||
|
@ -48,6 +61,15 @@ pub enum ImportSection {
|
||||||
UserDefined(String),
|
UserDefined(String),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl fmt::Display for ImportSection {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
|
match self {
|
||||||
|
Self::Known(import_type) => write!(f, "known {{ type = {import_type} }}",),
|
||||||
|
Self::UserDefined(string) => fmt::Debug::fmt(string, f),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
enum Reason<'a> {
|
enum Reason<'a> {
|
||||||
NonZeroLevel,
|
NonZeroLevel,
|
||||||
|
@ -378,3 +400,18 @@ impl KnownModules {
|
||||||
user_defined
|
user_defined
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl fmt::Display for KnownModules {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
|
if self.known.is_empty() {
|
||||||
|
write!(f, "{{}}")?;
|
||||||
|
} else {
|
||||||
|
writeln!(f, "{{")?;
|
||||||
|
for (pattern, import_section) in &self.known {
|
||||||
|
writeln!(f, "\t{pattern} => {import_section:?},")?;
|
||||||
|
}
|
||||||
|
write!(f, "}}")?;
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -3,10 +3,12 @@
|
||||||
use std::collections::BTreeSet;
|
use std::collections::BTreeSet;
|
||||||
use std::error::Error;
|
use std::error::Error;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
use std::fmt::{Display, Formatter};
|
||||||
|
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use strum::IntoEnumIterator;
|
use strum::IntoEnumIterator;
|
||||||
|
|
||||||
|
use crate::display_settings;
|
||||||
use ruff_macros::CacheKey;
|
use ruff_macros::CacheKey;
|
||||||
|
|
||||||
use crate::rules::isort::categorize::KnownModules;
|
use crate::rules::isort::categorize::KnownModules;
|
||||||
|
@ -32,6 +34,15 @@ impl Default for RelativeImportsOrder {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Display for RelativeImportsOrder {
|
||||||
|
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
|
||||||
|
match self {
|
||||||
|
Self::ClosestToFurthest => write!(f, "closest_to_furthest"),
|
||||||
|
Self::FurthestToClosest => write!(f, "furthest_to_closest"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, CacheKey)]
|
#[derive(Debug, CacheKey)]
|
||||||
#[allow(clippy::struct_excessive_bools)]
|
#[allow(clippy::struct_excessive_bools)]
|
||||||
pub struct Settings {
|
pub struct Settings {
|
||||||
|
@ -94,6 +105,43 @@ impl Default for Settings {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Display for Settings {
|
||||||
|
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
|
||||||
|
display_settings! {
|
||||||
|
formatter = f,
|
||||||
|
namespace = "linter.isort",
|
||||||
|
fields = [
|
||||||
|
self.required_imports | array,
|
||||||
|
self.combine_as_imports,
|
||||||
|
self.force_single_line,
|
||||||
|
self.force_sort_within_sections,
|
||||||
|
self.detect_same_package,
|
||||||
|
self.case_sensitive,
|
||||||
|
self.force_wrap_aliases,
|
||||||
|
self.force_to_top | array,
|
||||||
|
self.known_modules,
|
||||||
|
self.order_by_type,
|
||||||
|
self.relative_imports_order,
|
||||||
|
self.single_line_exclusions | array,
|
||||||
|
self.split_on_trailing_comma,
|
||||||
|
self.classes | array,
|
||||||
|
self.constants | array,
|
||||||
|
self.variables | array,
|
||||||
|
self.no_lines_before | array,
|
||||||
|
self.lines_after_imports,
|
||||||
|
self.lines_between_types,
|
||||||
|
self.forced_separate | array,
|
||||||
|
self.section_order | array,
|
||||||
|
self.no_sections,
|
||||||
|
self.from_first,
|
||||||
|
self.length_sort,
|
||||||
|
self.length_sort_straight
|
||||||
|
]
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Error returned by the [`TryFrom`] implementation of [`Settings`].
|
/// Error returned by the [`TryFrom`] implementation of [`Settings`].
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum SettingsError {
|
pub enum SettingsError {
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
//! Settings for the `mccabe` plugin.
|
//! Settings for the `mccabe` plugin.
|
||||||
|
|
||||||
|
use crate::display_settings;
|
||||||
use ruff_macros::CacheKey;
|
use ruff_macros::CacheKey;
|
||||||
|
use std::fmt::{Display, Formatter};
|
||||||
|
|
||||||
#[derive(Debug, CacheKey)]
|
#[derive(Debug, CacheKey)]
|
||||||
pub struct Settings {
|
pub struct Settings {
|
||||||
|
@ -16,3 +18,16 @@ impl Default for Settings {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Display for Settings {
|
||||||
|
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||||
|
display_settings! {
|
||||||
|
formatter = f,
|
||||||
|
namespace = "linter.mccabe",
|
||||||
|
fields = [
|
||||||
|
self.max_complexity
|
||||||
|
]
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -2,7 +2,9 @@
|
||||||
|
|
||||||
use std::error::Error;
|
use std::error::Error;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
use std::fmt::Formatter;
|
||||||
|
|
||||||
|
use crate::display_settings;
|
||||||
use ruff_macros::CacheKey;
|
use ruff_macros::CacheKey;
|
||||||
|
|
||||||
use crate::settings::types::IdentifierPattern;
|
use crate::settings::types::IdentifierPattern;
|
||||||
|
@ -44,6 +46,21 @@ impl Default for Settings {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl fmt::Display for Settings {
|
||||||
|
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
|
||||||
|
display_settings! {
|
||||||
|
formatter = f,
|
||||||
|
namespace = "linter.pep8_naming",
|
||||||
|
fields = [
|
||||||
|
self.ignore_names | array,
|
||||||
|
self.classmethod_decorators | array,
|
||||||
|
self.staticmethod_decorators | array
|
||||||
|
]
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Error returned by the [`TryFrom`] implementation of [`Settings`].
|
/// Error returned by the [`TryFrom`] implementation of [`Settings`].
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum SettingsError {
|
pub enum SettingsError {
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
//! Settings for the `pycodestyle` plugin.
|
//! Settings for the `pycodestyle` plugin.
|
||||||
|
|
||||||
|
use crate::display_settings;
|
||||||
use ruff_macros::CacheKey;
|
use ruff_macros::CacheKey;
|
||||||
|
use std::fmt;
|
||||||
|
|
||||||
use crate::line_width::LineLength;
|
use crate::line_width::LineLength;
|
||||||
|
|
||||||
|
@ -10,3 +12,18 @@ pub struct Settings {
|
||||||
pub max_doc_length: Option<LineLength>,
|
pub max_doc_length: Option<LineLength>,
|
||||||
pub ignore_overlong_task_comments: bool,
|
pub ignore_overlong_task_comments: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl fmt::Display for Settings {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
|
display_settings! {
|
||||||
|
formatter = f,
|
||||||
|
namespace = "linter.pycodestyle",
|
||||||
|
fields = [
|
||||||
|
self.max_line_length,
|
||||||
|
self.max_doc_length | optional,
|
||||||
|
self.ignore_overlong_task_comments,
|
||||||
|
]
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,9 +1,11 @@
|
||||||
//! Settings for the `pydocstyle` plugin.
|
//! Settings for the `pydocstyle` plugin.
|
||||||
|
|
||||||
use std::collections::BTreeSet;
|
use std::collections::BTreeSet;
|
||||||
|
use std::fmt;
|
||||||
|
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
use crate::display_settings;
|
||||||
use ruff_macros::CacheKey;
|
use ruff_macros::CacheKey;
|
||||||
|
|
||||||
use crate::registry::Rule;
|
use crate::registry::Rule;
|
||||||
|
@ -71,9 +73,34 @@ impl Convention {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl fmt::Display for Convention {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
|
match self {
|
||||||
|
Self::Google => write!(f, "google"),
|
||||||
|
Self::Numpy => write!(f, "numpy"),
|
||||||
|
Self::Pep257 => write!(f, "pep257"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Default, CacheKey)]
|
#[derive(Debug, Default, CacheKey)]
|
||||||
pub struct Settings {
|
pub struct Settings {
|
||||||
pub convention: Option<Convention>,
|
pub convention: Option<Convention>,
|
||||||
pub ignore_decorators: BTreeSet<String>,
|
pub ignore_decorators: BTreeSet<String>,
|
||||||
pub property_decorators: BTreeSet<String>,
|
pub property_decorators: BTreeSet<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl fmt::Display for Settings {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
|
display_settings! {
|
||||||
|
formatter = f,
|
||||||
|
namespace = "linter.pydocstyle",
|
||||||
|
fields = [
|
||||||
|
self.convention | optional,
|
||||||
|
self.ignore_decorators | debug,
|
||||||
|
self.property_decorators | debug
|
||||||
|
]
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,8 +1,23 @@
|
||||||
//! Settings for the `Pyflakes` plugin.
|
//! Settings for the `Pyflakes` plugin.
|
||||||
|
|
||||||
|
use crate::display_settings;
|
||||||
use ruff_macros::CacheKey;
|
use ruff_macros::CacheKey;
|
||||||
|
use std::fmt;
|
||||||
|
|
||||||
#[derive(Debug, Default, CacheKey)]
|
#[derive(Debug, Default, CacheKey)]
|
||||||
pub struct Settings {
|
pub struct Settings {
|
||||||
pub extend_generics: Vec<String>,
|
pub extend_generics: Vec<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl fmt::Display for Settings {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
|
display_settings! {
|
||||||
|
formatter = f,
|
||||||
|
namespace = "linter.pyflakes",
|
||||||
|
fields = [
|
||||||
|
self.extend_generics | debug
|
||||||
|
]
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -2,7 +2,9 @@
|
||||||
|
|
||||||
use rustc_hash::FxHashSet;
|
use rustc_hash::FxHashSet;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
use std::fmt;
|
||||||
|
|
||||||
|
use crate::display_settings;
|
||||||
use ruff_macros::CacheKey;
|
use ruff_macros::CacheKey;
|
||||||
use ruff_python_ast::{ExprNumberLiteral, LiteralExpressionRef, Number};
|
use ruff_python_ast::{ExprNumberLiteral, LiteralExpressionRef, Number};
|
||||||
|
|
||||||
|
@ -34,6 +36,18 @@ impl ConstantType {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl fmt::Display for ConstantType {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
|
match self {
|
||||||
|
Self::Bytes => write!(f, "bytes"),
|
||||||
|
Self::Complex => write!(f, "complex"),
|
||||||
|
Self::Float => write!(f, "float"),
|
||||||
|
Self::Int => write!(f, "int"),
|
||||||
|
Self::Str => write!(f, "str"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, CacheKey)]
|
#[derive(Debug, CacheKey)]
|
||||||
pub struct Settings {
|
pub struct Settings {
|
||||||
pub allow_magic_value_types: Vec<ConstantType>,
|
pub allow_magic_value_types: Vec<ConstantType>,
|
||||||
|
@ -64,3 +78,25 @@ impl Default for Settings {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl fmt::Display for Settings {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
|
display_settings! {
|
||||||
|
formatter = f,
|
||||||
|
namespace = "linter.pylint",
|
||||||
|
fields = [
|
||||||
|
self.allow_magic_value_types | array,
|
||||||
|
self.allow_dunder_method_names | array,
|
||||||
|
self.max_args,
|
||||||
|
self.max_positional_args,
|
||||||
|
self.max_returns,
|
||||||
|
self.max_bool_expr,
|
||||||
|
self.max_branches,
|
||||||
|
self.max_statements,
|
||||||
|
self.max_public_methods,
|
||||||
|
self.max_locals
|
||||||
|
]
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,8 +1,23 @@
|
||||||
//! Settings for the `pyupgrade` plugin.
|
//! Settings for the `pyupgrade` plugin.
|
||||||
|
|
||||||
|
use crate::display_settings;
|
||||||
use ruff_macros::CacheKey;
|
use ruff_macros::CacheKey;
|
||||||
|
use std::fmt;
|
||||||
|
|
||||||
#[derive(Debug, Default, CacheKey)]
|
#[derive(Debug, Default, CacheKey)]
|
||||||
pub struct Settings {
|
pub struct Settings {
|
||||||
pub keep_runtime_typing: bool,
|
pub keep_runtime_typing: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl fmt::Display for Settings {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
|
display_settings! {
|
||||||
|
formatter = f,
|
||||||
|
namespace = "linter.pyupgrade",
|
||||||
|
fields = [
|
||||||
|
self.keep_runtime_typing
|
||||||
|
]
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -16,8 +16,7 @@ mod tests {
|
||||||
|
|
||||||
use crate::pyproject_toml::lint_pyproject_toml;
|
use crate::pyproject_toml::lint_pyproject_toml;
|
||||||
use crate::registry::Rule;
|
use crate::registry::Rule;
|
||||||
use crate::settings::resolve_per_file_ignores;
|
use crate::settings::types::{PerFileIgnore, PerFileIgnores, PreviewMode, PythonVersion};
|
||||||
use crate::settings::types::{PerFileIgnore, PreviewMode, PythonVersion};
|
|
||||||
use crate::test::{test_path, test_resource_path};
|
use crate::test::{test_path, test_resource_path};
|
||||||
use crate::{assert_messages, settings};
|
use crate::{assert_messages, settings};
|
||||||
|
|
||||||
|
@ -171,7 +170,7 @@ mod tests {
|
||||||
let mut settings =
|
let mut settings =
|
||||||
settings::LinterSettings::for_rules(vec![Rule::UnusedNOQA, Rule::UnusedImport]);
|
settings::LinterSettings::for_rules(vec![Rule::UnusedNOQA, Rule::UnusedImport]);
|
||||||
|
|
||||||
settings.per_file_ignores = resolve_per_file_ignores(vec![PerFileIgnore::new(
|
settings.per_file_ignores = PerFileIgnores::resolve(vec![PerFileIgnore::new(
|
||||||
"RUF100_2.py".to_string(),
|
"RUF100_2.py".to_string(),
|
||||||
&["F401".parse().unwrap()],
|
&["F401".parse().unwrap()],
|
||||||
None,
|
None,
|
||||||
|
@ -228,7 +227,7 @@ mod tests {
|
||||||
let diagnostics = test_path(
|
let diagnostics = test_path(
|
||||||
Path::new("ruff/ruff_per_file_ignores.py"),
|
Path::new("ruff/ruff_per_file_ignores.py"),
|
||||||
&settings::LinterSettings {
|
&settings::LinterSettings {
|
||||||
per_file_ignores: resolve_per_file_ignores(vec![PerFileIgnore::new(
|
per_file_ignores: PerFileIgnores::resolve(vec![PerFileIgnore::new(
|
||||||
"ruff_per_file_ignores.py".to_string(),
|
"ruff_per_file_ignores.py".to_string(),
|
||||||
&["F401".parse().unwrap(), "RUF100".parse().unwrap()],
|
&["F401".parse().unwrap(), "RUF100".parse().unwrap()],
|
||||||
None,
|
None,
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use std::fmt::Debug;
|
use std::fmt::{Debug, Display, Formatter};
|
||||||
|
|
||||||
use ruff_diagnostics::Applicability;
|
use ruff_diagnostics::Applicability;
|
||||||
use ruff_macros::CacheKey;
|
use ruff_macros::CacheKey;
|
||||||
|
@ -6,6 +6,7 @@ use rustc_hash::FxHashMap;
|
||||||
use strum::IntoEnumIterator;
|
use strum::IntoEnumIterator;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
|
display_settings,
|
||||||
registry::{Rule, RuleSet},
|
registry::{Rule, RuleSet},
|
||||||
rule_selector::{PreviewOptions, Specificity},
|
rule_selector::{PreviewOptions, Specificity},
|
||||||
RuleSelector,
|
RuleSelector,
|
||||||
|
@ -95,6 +96,20 @@ impl FixSafetyTable {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Display for FixSafetyTable {
|
||||||
|
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||||
|
display_settings! {
|
||||||
|
formatter = f,
|
||||||
|
namespace = "linter.safety_table",
|
||||||
|
fields = [
|
||||||
|
self.forced_safe,
|
||||||
|
self.forced_unsafe
|
||||||
|
]
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
|
@ -2,10 +2,9 @@
|
||||||
//! command-line options. Structure is optimized for internal usage, as opposed
|
//! command-line options. Structure is optimized for internal usage, as opposed
|
||||||
//! to external visibility or parsing.
|
//! to external visibility or parsing.
|
||||||
|
|
||||||
|
use std::fmt::{Display, Formatter};
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
|
|
||||||
use anyhow::Result;
|
|
||||||
use globset::{Glob, GlobMatcher};
|
|
||||||
use once_cell::sync::Lazy;
|
use once_cell::sync::Lazy;
|
||||||
use path_absolutize::path_dedot;
|
use path_absolutize::path_dedot;
|
||||||
use regex::Regex;
|
use regex::Regex;
|
||||||
|
@ -15,7 +14,7 @@ use crate::codes::RuleCodePrefix;
|
||||||
use ruff_macros::CacheKey;
|
use ruff_macros::CacheKey;
|
||||||
|
|
||||||
use crate::line_width::LineLength;
|
use crate::line_width::LineLength;
|
||||||
use crate::registry::{Linter, Rule, RuleSet};
|
use crate::registry::{Linter, Rule};
|
||||||
use crate::rules::{
|
use crate::rules::{
|
||||||
flake8_annotations, flake8_bandit, flake8_bugbear, flake8_builtins, flake8_comprehensions,
|
flake8_annotations, flake8_bandit, flake8_bugbear, flake8_builtins, flake8_comprehensions,
|
||||||
flake8_copyright, flake8_errmsg, flake8_gettext, flake8_implicit_str_concat,
|
flake8_copyright, flake8_errmsg, flake8_gettext, flake8_implicit_str_concat,
|
||||||
|
@ -23,7 +22,7 @@ use crate::rules::{
|
||||||
flake8_tidy_imports, flake8_type_checking, flake8_unused_arguments, isort, mccabe, pep8_naming,
|
flake8_tidy_imports, flake8_type_checking, flake8_unused_arguments, isort, mccabe, pep8_naming,
|
||||||
pycodestyle, pydocstyle, pyflakes, pylint, pyupgrade,
|
pycodestyle, pydocstyle, pyflakes, pylint, pyupgrade,
|
||||||
};
|
};
|
||||||
use crate::settings::types::{ExtensionMapping, FilePatternSet, PerFileIgnore, PythonVersion};
|
use crate::settings::types::{ExtensionMapping, FilePatternSet, PerFileIgnores, PythonVersion};
|
||||||
use crate::{codes, RuleSelector};
|
use crate::{codes, RuleSelector};
|
||||||
|
|
||||||
use super::line_width::IndentWidth;
|
use super::line_width::IndentWidth;
|
||||||
|
@ -38,6 +37,126 @@ pub mod flags;
|
||||||
pub mod rule_table;
|
pub mod rule_table;
|
||||||
pub mod types;
|
pub mod types;
|
||||||
|
|
||||||
|
/// `display_settings!` is a macro that can display and format struct fields in a readable,
|
||||||
|
/// namespaced format. It's particularly useful at generating `Display` implementations
|
||||||
|
/// for types used in settings.
|
||||||
|
///
|
||||||
|
/// # Example
|
||||||
|
/// ```
|
||||||
|
/// use std::fmt;
|
||||||
|
/// use ruff_linter::display_settings;
|
||||||
|
/// #[derive(Default)]
|
||||||
|
/// struct Settings {
|
||||||
|
/// option_a: bool,
|
||||||
|
/// sub_settings: SubSettings,
|
||||||
|
/// option_b: String,
|
||||||
|
/// }
|
||||||
|
///
|
||||||
|
/// struct SubSettings {
|
||||||
|
/// name: String
|
||||||
|
/// }
|
||||||
|
///
|
||||||
|
/// impl Default for SubSettings {
|
||||||
|
/// fn default() -> Self {
|
||||||
|
/// Self { name: "Default Name".into() }
|
||||||
|
/// }
|
||||||
|
///
|
||||||
|
/// }
|
||||||
|
///
|
||||||
|
/// impl fmt::Display for SubSettings {
|
||||||
|
/// fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
|
/// display_settings! {
|
||||||
|
/// formatter = f,
|
||||||
|
/// namespace = "sub_settings",
|
||||||
|
/// fields = [
|
||||||
|
/// self.name | quoted
|
||||||
|
/// ]
|
||||||
|
/// }
|
||||||
|
/// Ok(())
|
||||||
|
/// }
|
||||||
|
///
|
||||||
|
/// }
|
||||||
|
///
|
||||||
|
/// impl fmt::Display for Settings {
|
||||||
|
/// fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
|
/// display_settings! {
|
||||||
|
/// formatter = f,
|
||||||
|
/// fields = [
|
||||||
|
/// self.option_a,
|
||||||
|
/// self.sub_settings | nested,
|
||||||
|
/// self.option_b | quoted,
|
||||||
|
/// ]
|
||||||
|
/// }
|
||||||
|
/// Ok(())
|
||||||
|
/// }
|
||||||
|
///
|
||||||
|
/// }
|
||||||
|
///
|
||||||
|
/// const EXPECTED_OUTPUT: &str = r#"option_a = false
|
||||||
|
/// sub_settings.name = "Default Name"
|
||||||
|
/// option_b = ""
|
||||||
|
/// "#;
|
||||||
|
///
|
||||||
|
/// fn main() {
|
||||||
|
/// let settings = Settings::default();
|
||||||
|
/// assert_eq!(format!("{settings}"), EXPECTED_OUTPUT);
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! display_settings {
|
||||||
|
(formatter = $fmt:ident, namespace = $namespace:literal, fields = [$($settings:ident.$field:ident $(| $modifier:tt)?),* $(,)?]) => {
|
||||||
|
{
|
||||||
|
const _PREFIX: &str = concat!($namespace, ".");
|
||||||
|
$(
|
||||||
|
display_settings!(@field $fmt, _PREFIX, $settings.$field $(| $modifier)?);
|
||||||
|
)*
|
||||||
|
}
|
||||||
|
};
|
||||||
|
(formatter = $fmt:ident, fields = [$($settings:ident.$field:ident $(| $modifier:tt)?),* $(,)?]) => {
|
||||||
|
{
|
||||||
|
const _PREFIX: &str = "";
|
||||||
|
$(
|
||||||
|
display_settings!(@field $fmt, _PREFIX, $settings.$field $(| $modifier)?);
|
||||||
|
)*
|
||||||
|
}
|
||||||
|
};
|
||||||
|
(@field $fmt:ident, $prefix:ident, $settings:ident.$field:ident | debug) => {
|
||||||
|
writeln!($fmt, "{}{} = {:?}", $prefix, stringify!($field), $settings.$field)?;
|
||||||
|
};
|
||||||
|
(@field $fmt:ident, $prefix:ident, $settings:ident.$field:ident | quoted) => {
|
||||||
|
writeln!($fmt, "{}{} = \"{}\"", $prefix, stringify!($field), $settings.$field)?;
|
||||||
|
};
|
||||||
|
(@field $fmt:ident, $prefix:ident, $settings:ident.$field:ident | nested) => {
|
||||||
|
write!($fmt, "{}", $settings.$field)?;
|
||||||
|
};
|
||||||
|
(@field $fmt:ident, $prefix:ident, $settings:ident.$field:ident | optional) => {
|
||||||
|
{
|
||||||
|
write!($fmt, "{}{} = ", $prefix, stringify!($field))?;
|
||||||
|
match &$settings.$field {
|
||||||
|
Some(value) => writeln!($fmt, "{}", value)?,
|
||||||
|
None => writeln!($fmt, "none")?
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
(@field $fmt:ident, $prefix:ident, $settings:ident.$field:ident | array) => {
|
||||||
|
{
|
||||||
|
write!($fmt, "{}{} = ", $prefix, stringify!($field))?;
|
||||||
|
if $settings.$field.is_empty() {
|
||||||
|
writeln!($fmt, "[]")?;
|
||||||
|
} else {
|
||||||
|
writeln!($fmt, "[")?;
|
||||||
|
for elem in &$settings.$field {
|
||||||
|
writeln!($fmt, "\t{elem},")?;
|
||||||
|
}
|
||||||
|
writeln!($fmt, "]")?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
(@field $fmt:ident, $prefix:ident, $settings:ident.$field:ident) => {
|
||||||
|
writeln!($fmt, "{}{} = {}", $prefix, stringify!($field), $settings.$field)?;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, CacheKey)]
|
#[derive(Debug, CacheKey)]
|
||||||
pub struct LinterSettings {
|
pub struct LinterSettings {
|
||||||
pub exclude: FilePatternSet,
|
pub exclude: FilePatternSet,
|
||||||
|
@ -45,7 +164,7 @@ pub struct LinterSettings {
|
||||||
pub project_root: PathBuf,
|
pub project_root: PathBuf,
|
||||||
|
|
||||||
pub rules: RuleTable,
|
pub rules: RuleTable,
|
||||||
pub per_file_ignores: Vec<(GlobMatcher, GlobMatcher, RuleSet)>,
|
pub per_file_ignores: PerFileIgnores,
|
||||||
pub fix_safety: FixSafetyTable,
|
pub fix_safety: FixSafetyTable,
|
||||||
|
|
||||||
pub target_version: PythonVersion,
|
pub target_version: PythonVersion,
|
||||||
|
@ -93,6 +212,73 @@ pub struct LinterSettings {
|
||||||
pub pyupgrade: pyupgrade::settings::Settings,
|
pub pyupgrade: pyupgrade::settings::Settings,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Display for LinterSettings {
|
||||||
|
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||||
|
writeln!(f, "\n# Linter Settings")?;
|
||||||
|
display_settings! {
|
||||||
|
formatter = f,
|
||||||
|
namespace = "linter",
|
||||||
|
fields = [
|
||||||
|
self.exclude,
|
||||||
|
self.project_root | debug,
|
||||||
|
|
||||||
|
self.rules | nested,
|
||||||
|
self.per_file_ignores,
|
||||||
|
self.fix_safety | nested,
|
||||||
|
|
||||||
|
self.target_version | debug,
|
||||||
|
self.preview,
|
||||||
|
self.explicit_preview_rules,
|
||||||
|
self.extension | nested,
|
||||||
|
|
||||||
|
self.allowed_confusables | array,
|
||||||
|
self.builtins | array,
|
||||||
|
self.dummy_variable_rgx,
|
||||||
|
self.external | array,
|
||||||
|
self.ignore_init_module_imports,
|
||||||
|
self.logger_objects | array,
|
||||||
|
self.namespace_packages | debug,
|
||||||
|
self.src | debug,
|
||||||
|
self.tab_size,
|
||||||
|
self.line_length,
|
||||||
|
self.task_tags | array,
|
||||||
|
self.typing_modules | array,
|
||||||
|
]
|
||||||
|
}
|
||||||
|
writeln!(f, "\n# Linter Plugins")?;
|
||||||
|
display_settings! {
|
||||||
|
formatter = f,
|
||||||
|
namespace = "linter",
|
||||||
|
fields = [
|
||||||
|
self.flake8_annotations | nested,
|
||||||
|
self.flake8_bandit | nested,
|
||||||
|
self.flake8_bugbear | nested,
|
||||||
|
self.flake8_builtins | nested,
|
||||||
|
self.flake8_comprehensions | nested,
|
||||||
|
self.flake8_copyright | nested,
|
||||||
|
self.flake8_errmsg | nested,
|
||||||
|
self.flake8_gettext | nested,
|
||||||
|
self.flake8_implicit_str_concat | nested,
|
||||||
|
self.flake8_import_conventions | nested,
|
||||||
|
self.flake8_pytest_style | nested,
|
||||||
|
self.flake8_quotes | nested,
|
||||||
|
self.flake8_self | nested,
|
||||||
|
self.flake8_tidy_imports | nested,
|
||||||
|
self.flake8_type_checking | nested,
|
||||||
|
self.flake8_unused_arguments | nested,
|
||||||
|
self.isort | nested,
|
||||||
|
self.mccabe | nested,
|
||||||
|
self.pep8_naming | nested,
|
||||||
|
self.pycodestyle | nested,
|
||||||
|
self.pyflakes | nested,
|
||||||
|
self.pylint | nested,
|
||||||
|
self.pyupgrade | nested,
|
||||||
|
]
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub const DEFAULT_SELECTORS: &[RuleSelector] = &[
|
pub const DEFAULT_SELECTORS: &[RuleSelector] = &[
|
||||||
RuleSelector::Linter(Linter::Pyflakes),
|
RuleSelector::Linter(Linter::Pyflakes),
|
||||||
// Only include pycodestyle rules that do not overlap with the formatter
|
// Only include pycodestyle rules that do not overlap with the formatter
|
||||||
|
@ -152,7 +338,7 @@ impl LinterSettings {
|
||||||
logger_objects: vec![],
|
logger_objects: vec![],
|
||||||
namespace_packages: vec![],
|
namespace_packages: vec![],
|
||||||
|
|
||||||
per_file_ignores: vec![],
|
per_file_ignores: PerFileIgnores::default(),
|
||||||
fix_safety: FixSafetyTable::default(),
|
fix_safety: FixSafetyTable::default(),
|
||||||
|
|
||||||
src: vec![path_dedot::CWD.clone()],
|
src: vec![path_dedot::CWD.clone()],
|
||||||
|
@ -204,22 +390,3 @@ impl Default for LinterSettings {
|
||||||
Self::new(path_dedot::CWD.as_path())
|
Self::new(path_dedot::CWD.as_path())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Given a list of patterns, create a `GlobSet`.
|
|
||||||
pub fn resolve_per_file_ignores(
|
|
||||||
per_file_ignores: Vec<PerFileIgnore>,
|
|
||||||
) -> Result<Vec<(GlobMatcher, GlobMatcher, RuleSet)>> {
|
|
||||||
per_file_ignores
|
|
||||||
.into_iter()
|
|
||||||
.map(|per_file_ignore| {
|
|
||||||
// Construct absolute path matcher.
|
|
||||||
let absolute =
|
|
||||||
Glob::new(&per_file_ignore.absolute.to_string_lossy())?.compile_matcher();
|
|
||||||
|
|
||||||
// Construct basename matcher.
|
|
||||||
let basename = Glob::new(&per_file_ignore.basename)?.compile_matcher();
|
|
||||||
|
|
||||||
Ok((absolute, basename, per_file_ignore.rules))
|
|
||||||
})
|
|
||||||
.collect()
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
use std::fmt::Debug;
|
use std::fmt::{Debug, Display, Formatter};
|
||||||
|
|
||||||
|
use crate::display_settings;
|
||||||
use ruff_macros::CacheKey;
|
use ruff_macros::CacheKey;
|
||||||
|
|
||||||
use crate::registry::{Rule, RuleSet, RuleSetIterator};
|
use crate::registry::{Rule, RuleSet, RuleSetIterator};
|
||||||
|
@ -62,6 +63,20 @@ impl RuleTable {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Display for RuleTable {
|
||||||
|
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||||
|
display_settings! {
|
||||||
|
formatter = f,
|
||||||
|
namespace = "linter.rules",
|
||||||
|
fields = [
|
||||||
|
self.enabled,
|
||||||
|
self.should_fix
|
||||||
|
]
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl FromIterator<Rule> for RuleTable {
|
impl FromIterator<Rule> for RuleTable {
|
||||||
fn from_iter<T: IntoIterator<Item = Rule>>(iter: T) -> Self {
|
fn from_iter<T: IntoIterator<Item = Rule>>(iter: T) -> Self {
|
||||||
let rules = RuleSet::from_iter(iter);
|
let rules = RuleSet::from_iter(iter);
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
use std::fmt::{Display, Formatter};
|
||||||
use std::hash::{Hash, Hasher};
|
use std::hash::{Hash, Hasher};
|
||||||
use std::ops::Deref;
|
use std::ops::Deref;
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
|
@ -5,7 +6,7 @@ use std::str::FromStr;
|
||||||
use std::string::ToString;
|
use std::string::ToString;
|
||||||
|
|
||||||
use anyhow::{bail, Result};
|
use anyhow::{bail, Result};
|
||||||
use globset::{Glob, GlobSet, GlobSetBuilder};
|
use globset::{Glob, GlobMatcher, GlobSet, GlobSetBuilder};
|
||||||
use pep440_rs::{Version as Pep440Version, VersionSpecifiers};
|
use pep440_rs::{Version as Pep440Version, VersionSpecifiers};
|
||||||
use rustc_hash::FxHashMap;
|
use rustc_hash::FxHashMap;
|
||||||
use serde::{de, Deserialize, Deserializer, Serialize};
|
use serde::{de, Deserialize, Deserializer, Serialize};
|
||||||
|
@ -17,9 +18,9 @@ use ruff_diagnostics::Applicability;
|
||||||
use ruff_macros::CacheKey;
|
use ruff_macros::CacheKey;
|
||||||
use ruff_python_ast::PySourceType;
|
use ruff_python_ast::PySourceType;
|
||||||
|
|
||||||
use crate::fs;
|
|
||||||
use crate::registry::RuleSet;
|
use crate::registry::RuleSet;
|
||||||
use crate::rule_selector::RuleSelector;
|
use crate::rule_selector::RuleSelector;
|
||||||
|
use crate::{display_settings, fs};
|
||||||
|
|
||||||
#[derive(
|
#[derive(
|
||||||
Clone,
|
Clone,
|
||||||
|
@ -121,6 +122,15 @@ impl From<bool> for PreviewMode {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Display for PreviewMode {
|
||||||
|
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||||
|
match self {
|
||||||
|
Self::Disabled => write!(f, "disabled"),
|
||||||
|
Self::Enabled => write!(f, "enabled"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Toggle for unsafe fixes.
|
/// Toggle for unsafe fixes.
|
||||||
/// `Hint` will not apply unsafe fixes but a message will be shown when they are available.
|
/// `Hint` will not apply unsafe fixes but a message will be shown when they are available.
|
||||||
/// `Disabled` will not apply unsafe fixes or show a message.
|
/// `Disabled` will not apply unsafe fixes or show a message.
|
||||||
|
@ -133,6 +143,20 @@ pub enum UnsafeFixes {
|
||||||
Enabled,
|
Enabled,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Display for UnsafeFixes {
|
||||||
|
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||||
|
write!(
|
||||||
|
f,
|
||||||
|
"{}",
|
||||||
|
match self {
|
||||||
|
Self::Hint => "hint",
|
||||||
|
Self::Disabled => "disabled",
|
||||||
|
Self::Enabled => "enabled",
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl From<bool> for UnsafeFixes {
|
impl From<bool> for UnsafeFixes {
|
||||||
fn from(value: bool) -> Self {
|
fn from(value: bool) -> Self {
|
||||||
if value {
|
if value {
|
||||||
|
@ -178,6 +202,19 @@ impl FilePattern {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Display for FilePattern {
|
||||||
|
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||||
|
write!(
|
||||||
|
f,
|
||||||
|
"{:?}",
|
||||||
|
match self {
|
||||||
|
Self::Builtin(pattern) => pattern,
|
||||||
|
Self::User(pattern, _) => pattern.as_str(),
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl FromStr for FilePattern {
|
impl FromStr for FilePattern {
|
||||||
type Err = anyhow::Error;
|
type Err = anyhow::Error;
|
||||||
|
|
||||||
|
@ -192,9 +229,14 @@ impl FromStr for FilePattern {
|
||||||
pub struct FilePatternSet {
|
pub struct FilePatternSet {
|
||||||
set: GlobSet,
|
set: GlobSet,
|
||||||
cache_key: u64,
|
cache_key: u64,
|
||||||
|
// This field is only for displaying the internals
|
||||||
|
// of `set`.
|
||||||
|
#[allow(clippy::used_underscore_binding)]
|
||||||
|
_set_internals: Vec<FilePattern>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FilePatternSet {
|
impl FilePatternSet {
|
||||||
|
#[allow(clippy::used_underscore_binding)]
|
||||||
pub fn try_from_iter<I>(patterns: I) -> Result<Self, anyhow::Error>
|
pub fn try_from_iter<I>(patterns: I) -> Result<Self, anyhow::Error>
|
||||||
where
|
where
|
||||||
I: IntoIterator<Item = FilePattern>,
|
I: IntoIterator<Item = FilePattern>,
|
||||||
|
@ -202,7 +244,10 @@ impl FilePatternSet {
|
||||||
let mut builder = GlobSetBuilder::new();
|
let mut builder = GlobSetBuilder::new();
|
||||||
let mut hasher = CacheKeyHasher::new();
|
let mut hasher = CacheKeyHasher::new();
|
||||||
|
|
||||||
|
let mut _set_internals = vec![];
|
||||||
|
|
||||||
for pattern in patterns {
|
for pattern in patterns {
|
||||||
|
_set_internals.push(pattern.clone());
|
||||||
pattern.cache_key(&mut hasher);
|
pattern.cache_key(&mut hasher);
|
||||||
pattern.add_to(&mut builder)?;
|
pattern.add_to(&mut builder)?;
|
||||||
}
|
}
|
||||||
|
@ -212,10 +257,26 @@ impl FilePatternSet {
|
||||||
Ok(FilePatternSet {
|
Ok(FilePatternSet {
|
||||||
set,
|
set,
|
||||||
cache_key: hasher.finish(),
|
cache_key: hasher.finish(),
|
||||||
|
_set_internals,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Display for FilePatternSet {
|
||||||
|
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||||
|
if self._set_internals.is_empty() {
|
||||||
|
write!(f, "[]")?;
|
||||||
|
} else {
|
||||||
|
writeln!(f, "[")?;
|
||||||
|
for pattern in &self._set_internals {
|
||||||
|
writeln!(f, "\t{pattern},")?;
|
||||||
|
}
|
||||||
|
write!(f, "]")?;
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Deref for FilePatternSet {
|
impl Deref for FilePatternSet {
|
||||||
type Target = GlobSet;
|
type Target = GlobSet;
|
||||||
|
|
||||||
|
@ -395,6 +456,19 @@ impl ExtensionMapping {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Display for ExtensionMapping {
|
||||||
|
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||||
|
display_settings! {
|
||||||
|
formatter = f,
|
||||||
|
namespace = "linter.extension",
|
||||||
|
fields = [
|
||||||
|
self.mapping | debug
|
||||||
|
]
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl From<FxHashMap<String, Language>> for ExtensionMapping {
|
impl From<FxHashMap<String, Language>> for ExtensionMapping {
|
||||||
fn from(value: FxHashMap<String, Language>) -> Self {
|
fn from(value: FxHashMap<String, Language>) -> Self {
|
||||||
Self { mapping: value }
|
Self { mapping: value }
|
||||||
|
@ -429,6 +503,23 @@ pub enum SerializationFormat {
|
||||||
Sarif,
|
Sarif,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Display for SerializationFormat {
|
||||||
|
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||||
|
match self {
|
||||||
|
Self::Text => write!(f, "text"),
|
||||||
|
Self::Json => write!(f, "json"),
|
||||||
|
Self::JsonLines => write!(f, "json_lines"),
|
||||||
|
Self::Junit => write!(f, "junit"),
|
||||||
|
Self::Grouped => write!(f, "grouped"),
|
||||||
|
Self::Github => write!(f, "github"),
|
||||||
|
Self::Gitlab => write!(f, "gitlab"),
|
||||||
|
Self::Pylint => write!(f, "pylint"),
|
||||||
|
Self::Azure => write!(f, "azure"),
|
||||||
|
Self::Sarif => write!(f, "sarif"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Default for SerializationFormat {
|
impl Default for SerializationFormat {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self::Text
|
Self::Text
|
||||||
|
@ -468,3 +559,55 @@ impl Deref for Version {
|
||||||
/// [`fnmatch`](https://docs.python.org/3/library/fnmatch.html) for
|
/// [`fnmatch`](https://docs.python.org/3/library/fnmatch.html) for
|
||||||
/// pattern matching.
|
/// pattern matching.
|
||||||
pub type IdentifierPattern = glob::Pattern;
|
pub type IdentifierPattern = glob::Pattern;
|
||||||
|
|
||||||
|
#[derive(Debug, CacheKey, Default)]
|
||||||
|
pub struct PerFileIgnores {
|
||||||
|
// Ordered as (absolute path matcher, basename matcher, rules)
|
||||||
|
ignores: Vec<(GlobMatcher, GlobMatcher, RuleSet)>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PerFileIgnores {
|
||||||
|
/// Given a list of patterns, create a `GlobSet`.
|
||||||
|
pub fn resolve(per_file_ignores: Vec<PerFileIgnore>) -> Result<Self> {
|
||||||
|
let ignores: Result<Vec<_>> = per_file_ignores
|
||||||
|
.into_iter()
|
||||||
|
.map(|per_file_ignore| {
|
||||||
|
// Construct absolute path matcher.
|
||||||
|
let absolute =
|
||||||
|
Glob::new(&per_file_ignore.absolute.to_string_lossy())?.compile_matcher();
|
||||||
|
|
||||||
|
// Construct basename matcher.
|
||||||
|
let basename = Glob::new(&per_file_ignore.basename)?.compile_matcher();
|
||||||
|
|
||||||
|
Ok((absolute, basename, per_file_ignore.rules))
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
Ok(Self { ignores: ignores? })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Display for PerFileIgnores {
|
||||||
|
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||||
|
if self.is_empty() {
|
||||||
|
write!(f, "{{}}")?;
|
||||||
|
} else {
|
||||||
|
writeln!(f, "{{")?;
|
||||||
|
for (absolute, basename, rules) in &self.ignores {
|
||||||
|
writeln!(
|
||||||
|
f,
|
||||||
|
"\t{{ absolute = {absolute:#?}, basename = {basename:#?}, rules = {rules} }},"
|
||||||
|
)?;
|
||||||
|
}
|
||||||
|
write!(f, "}}")?;
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Deref for PerFileIgnores {
|
||||||
|
type Target = Vec<(GlobMatcher, GlobMatcher, RuleSet)>;
|
||||||
|
|
||||||
|
fn deref(&self) -> &Self::Target {
|
||||||
|
&self.ignores
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@ use ruff_formatter::printer::{LineEnding, PrinterOptions, SourceMapGeneration};
|
||||||
use ruff_formatter::{FormatOptions, IndentStyle, IndentWidth, LineWidth};
|
use ruff_formatter::{FormatOptions, IndentStyle, IndentWidth, LineWidth};
|
||||||
use ruff_macros::CacheKey;
|
use ruff_macros::CacheKey;
|
||||||
use ruff_python_ast::PySourceType;
|
use ruff_python_ast::PySourceType;
|
||||||
|
use std::fmt;
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
|
|
||||||
|
@ -241,6 +242,16 @@ pub enum QuoteStyle {
|
||||||
Preserve,
|
Preserve,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl fmt::Display for QuoteStyle {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
|
match self {
|
||||||
|
Self::Single => write!(f, "single"),
|
||||||
|
Self::Double => write!(f, "double"),
|
||||||
|
Self::Preserve => write!(f, "preserve"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl FromStr for QuoteStyle {
|
impl FromStr for QuoteStyle {
|
||||||
type Err = &'static str;
|
type Err = &'static str;
|
||||||
|
|
||||||
|
@ -277,6 +288,15 @@ impl MagicTrailingComma {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl fmt::Display for MagicTrailingComma {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
|
match self {
|
||||||
|
Self::Respect => write!(f, "respect"),
|
||||||
|
Self::Ignore => write!(f, "ignore"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl FromStr for MagicTrailingComma {
|
impl FromStr for MagicTrailingComma {
|
||||||
type Err = &'static str;
|
type Err = &'static str;
|
||||||
|
|
||||||
|
@ -306,6 +326,15 @@ impl PreviewMode {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl fmt::Display for PreviewMode {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
|
match self {
|
||||||
|
Self::Disabled => write!(f, "disabled"),
|
||||||
|
Self::Enabled => write!(f, "enabled"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, Eq, PartialEq, Default, CacheKey)]
|
#[derive(Copy, Clone, Debug, Eq, PartialEq, Default, CacheKey)]
|
||||||
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
|
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
|
||||||
#[cfg_attr(feature = "serde", serde(rename_all = "lowercase"))]
|
#[cfg_attr(feature = "serde", serde(rename_all = "lowercase"))]
|
||||||
|
@ -323,6 +352,15 @@ impl DocstringCode {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl fmt::Display for DocstringCode {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
|
match self {
|
||||||
|
Self::Disabled => write!(f, "disabled"),
|
||||||
|
Self::Enabled => write!(f, "enabled"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone, Default, Eq, PartialEq, CacheKey)]
|
#[derive(Copy, Clone, Default, Eq, PartialEq, CacheKey)]
|
||||||
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
|
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
|
||||||
#[cfg_attr(feature = "serde", serde(rename_all = "lowercase"))]
|
#[cfg_attr(feature = "serde", serde(rename_all = "lowercase"))]
|
||||||
|
@ -338,8 +376,8 @@ pub enum DocstringCodeLineWidth {
|
||||||
Dynamic,
|
Dynamic,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl std::fmt::Debug for DocstringCodeLineWidth {
|
impl fmt::Debug for DocstringCodeLineWidth {
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
match *self {
|
match *self {
|
||||||
DocstringCodeLineWidth::Fixed(v) => v.value().fmt(f),
|
DocstringCodeLineWidth::Fixed(v) => v.value().fmt(f),
|
||||||
DocstringCodeLineWidth::Dynamic => "dynamic".fmt(f),
|
DocstringCodeLineWidth::Dynamic => "dynamic".fmt(f),
|
||||||
|
@ -347,6 +385,15 @@ impl std::fmt::Debug for DocstringCodeLineWidth {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl fmt::Display for DocstringCodeLineWidth {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
|
match self {
|
||||||
|
Self::Fixed(width) => width.fmt(f),
|
||||||
|
Self::Dynamic => write!(f, "dynamic"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Responsible for deserializing the `DocstringCodeLineWidth::Dynamic`
|
/// Responsible for deserializing the `DocstringCodeLineWidth::Dynamic`
|
||||||
/// variant.
|
/// variant.
|
||||||
fn deserialize_docstring_code_line_width_dynamic<'de, D>(d: D) -> Result<(), D::Error>
|
fn deserialize_docstring_code_line_width_dynamic<'de, D>(d: D) -> Result<(), D::Error>
|
||||||
|
|
|
@ -25,12 +25,10 @@ use ruff_linter::rule_selector::{PreviewOptions, Specificity};
|
||||||
use ruff_linter::rules::pycodestyle;
|
use ruff_linter::rules::pycodestyle;
|
||||||
use ruff_linter::settings::rule_table::RuleTable;
|
use ruff_linter::settings::rule_table::RuleTable;
|
||||||
use ruff_linter::settings::types::{
|
use ruff_linter::settings::types::{
|
||||||
ExtensionMapping, FilePattern, FilePatternSet, PerFileIgnore, PreviewMode, PythonVersion,
|
ExtensionMapping, FilePattern, FilePatternSet, PerFileIgnore, PerFileIgnores, PreviewMode,
|
||||||
SerializationFormat, UnsafeFixes, Version,
|
PythonVersion, SerializationFormat, UnsafeFixes, Version,
|
||||||
};
|
|
||||||
use ruff_linter::settings::{
|
|
||||||
resolve_per_file_ignores, LinterSettings, DEFAULT_SELECTORS, DUMMY_VARIABLE_RGX, TASK_TAGS,
|
|
||||||
};
|
};
|
||||||
|
use ruff_linter::settings::{LinterSettings, DEFAULT_SELECTORS, DUMMY_VARIABLE_RGX, TASK_TAGS};
|
||||||
use ruff_linter::{
|
use ruff_linter::{
|
||||||
fs, warn_user, warn_user_once, warn_user_once_by_id, RuleSelector, RUFF_PKG_VERSION,
|
fs, warn_user, warn_user_once, warn_user_once_by_id, RuleSelector, RUFF_PKG_VERSION,
|
||||||
};
|
};
|
||||||
|
@ -260,7 +258,7 @@ impl Configuration {
|
||||||
line_length,
|
line_length,
|
||||||
tab_size: self.indent_width.unwrap_or_default(),
|
tab_size: self.indent_width.unwrap_or_default(),
|
||||||
namespace_packages: self.namespace_packages.unwrap_or_default(),
|
namespace_packages: self.namespace_packages.unwrap_or_default(),
|
||||||
per_file_ignores: resolve_per_file_ignores(
|
per_file_ignores: PerFileIgnores::resolve(
|
||||||
lint.per_file_ignores
|
lint.per_file_ignores
|
||||||
.unwrap_or_default()
|
.unwrap_or_default()
|
||||||
.into_iter()
|
.into_iter()
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
use path_absolutize::path_dedot;
|
use path_absolutize::path_dedot;
|
||||||
use ruff_cache::cache_dir;
|
use ruff_cache::cache_dir;
|
||||||
use ruff_formatter::{FormatOptions, IndentStyle, IndentWidth, LineWidth};
|
use ruff_formatter::{FormatOptions, IndentStyle, IndentWidth, LineWidth};
|
||||||
|
use ruff_linter::display_settings;
|
||||||
use ruff_linter::settings::types::{
|
use ruff_linter::settings::types::{
|
||||||
ExtensionMapping, FilePattern, FilePatternSet, SerializationFormat, UnsafeFixes,
|
ExtensionMapping, FilePattern, FilePatternSet, SerializationFormat, UnsafeFixes,
|
||||||
};
|
};
|
||||||
|
@ -12,6 +13,7 @@ use ruff_python_formatter::{
|
||||||
QuoteStyle,
|
QuoteStyle,
|
||||||
};
|
};
|
||||||
use ruff_source_file::find_newline;
|
use ruff_source_file::find_newline;
|
||||||
|
use std::fmt;
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
|
|
||||||
#[derive(Debug, CacheKey)]
|
#[derive(Debug, CacheKey)]
|
||||||
|
@ -55,6 +57,30 @@ impl Default for Settings {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl fmt::Display for Settings {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
|
writeln!(f, "\n# General Settings")?;
|
||||||
|
display_settings! {
|
||||||
|
formatter = f,
|
||||||
|
fields = [
|
||||||
|
// We want the quotes and lossy UTF8 conversion for this path, so
|
||||||
|
// using PathBuf's `Debug` formatter suffices.
|
||||||
|
self.cache_dir | debug,
|
||||||
|
self.fix,
|
||||||
|
self.fix_only,
|
||||||
|
self.output_format,
|
||||||
|
self.show_fixes,
|
||||||
|
self.show_source,
|
||||||
|
self.unsafe_fixes,
|
||||||
|
self.file_resolver | nested,
|
||||||
|
self.linter | nested,
|
||||||
|
self.formatter | nested
|
||||||
|
]
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, CacheKey)]
|
#[derive(Debug, CacheKey)]
|
||||||
pub struct FileResolverSettings {
|
pub struct FileResolverSettings {
|
||||||
pub exclude: FilePatternSet,
|
pub exclude: FilePatternSet,
|
||||||
|
@ -66,6 +92,26 @@ pub struct FileResolverSettings {
|
||||||
pub project_root: PathBuf,
|
pub project_root: PathBuf,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl fmt::Display for FileResolverSettings {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
|
writeln!(f, "\n# File Resolver Settings")?;
|
||||||
|
display_settings! {
|
||||||
|
formatter = f,
|
||||||
|
namespace = "file_resolver",
|
||||||
|
fields = [
|
||||||
|
self.exclude,
|
||||||
|
self.extend_exclude,
|
||||||
|
self.force_exclude,
|
||||||
|
self.include,
|
||||||
|
self.extend_include,
|
||||||
|
self.respect_gitignore,
|
||||||
|
self.project_root | debug,
|
||||||
|
]
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub(crate) static EXCLUDE: &[FilePattern] = &[
|
pub(crate) static EXCLUDE: &[FilePattern] = &[
|
||||||
FilePattern::Builtin(".bzr"),
|
FilePattern::Builtin(".bzr"),
|
||||||
FilePattern::Builtin(".direnv"),
|
FilePattern::Builtin(".direnv"),
|
||||||
|
@ -195,6 +241,30 @@ impl Default for FormatterSettings {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl fmt::Display for FormatterSettings {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
|
writeln!(f, "\n# Formatter Settings")?;
|
||||||
|
display_settings! {
|
||||||
|
formatter = f,
|
||||||
|
namespace = "formatter",
|
||||||
|
fields = [
|
||||||
|
self.exclude,
|
||||||
|
self.target_version | debug,
|
||||||
|
self.preview,
|
||||||
|
self.line_width,
|
||||||
|
self.line_ending,
|
||||||
|
self.indent_style,
|
||||||
|
self.indent_width,
|
||||||
|
self.quote_style,
|
||||||
|
self.magic_trailing_comma,
|
||||||
|
self.docstring_code_format,
|
||||||
|
self.docstring_code_line_width,
|
||||||
|
]
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(
|
#[derive(
|
||||||
Copy, Clone, Debug, Eq, PartialEq, Default, CacheKey, serde::Serialize, serde::Deserialize,
|
Copy, Clone, Debug, Eq, PartialEq, Default, CacheKey, serde::Serialize, serde::Deserialize,
|
||||||
)]
|
)]
|
||||||
|
@ -216,3 +286,14 @@ pub enum LineEnding {
|
||||||
/// Line endings will be converted to `\n` on Unix and `\r\n` on Windows.
|
/// Line endings will be converted to `\n` on Unix and `\r\n` on Windows.
|
||||||
Native,
|
Native,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl fmt::Display for LineEnding {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
|
match self {
|
||||||
|
Self::Auto => write!(f, "auto"),
|
||||||
|
Self::Lf => write!(f, "lf"),
|
||||||
|
Self::CrLf => write!(f, "crlf"),
|
||||||
|
Self::Native => write!(f, "native"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue