mirror of
https://github.com/astral-sh/ruff.git
synced 2025-08-04 18:58:04 +00:00
add rule RUF062 for PEP 515 number formatting with digit grouping
This commit is contained in:
parent
9fc04d6bf0
commit
c30fbe2b91
10 changed files with 884 additions and 1 deletions
53
crates/ruff_linter/resources/test/fixtures/ruff/RUF062.py
vendored
Normal file
53
crates/ruff_linter/resources/test/fixtures/ruff/RUF062.py
vendored
Normal file
|
@ -0,0 +1,53 @@
|
|||
"""Tests for the RUF062 rule (large numeric literals without underscore separators)."""
|
||||
|
||||
# These should trigger the rule (large numbers without underscore separators)
|
||||
i = 1000000
|
||||
f = 123456789.123456789
|
||||
x = 0x1234ABCD
|
||||
b = 0b10101010101010101010101
|
||||
o = 0o12345671234
|
||||
|
||||
# Scientific notation
|
||||
sci = 1000000e10
|
||||
sci_uppercase = 1000000E10
|
||||
|
||||
# These should not trigger the rule (small numbers or already have separators)
|
||||
dec_small_int = 1234
|
||||
dec_small_float = 123.45
|
||||
dec_with_separators = 1_000_000
|
||||
hex_with_separators = 0x1234_ABCD
|
||||
bin_with_separators = 0b10101_01010101_01010101
|
||||
oct_with_separators = 0o123_4567_1234
|
||||
sci_with_separators = 1_000_000e10
|
||||
|
||||
# These should trigger the rule because their separators are misplaced
|
||||
dec_misplaced_separators = 123_4567_89
|
||||
oct_misplaced_separators = 0o12_34_56
|
||||
hex_misplaced_separators = 0xABCD_EF
|
||||
flt_misplaced_separators = 123.12_3456_789
|
||||
|
||||
# uppercase base prefix
|
||||
hex_uppercase = 0XABCDEF
|
||||
oct_uppercase = 0O123456
|
||||
bin_uppercase = 0B01010101010101
|
||||
|
||||
# Negative numbers should also be checked
|
||||
neg_large = -1000000
|
||||
neg_with_separators = -1_000_000 # should not trigger
|
||||
neg_with_spaces = - 100000
|
||||
neg_oct = -0o1234567
|
||||
neg_hex = -0xABCDEF
|
||||
neg_bin -0b0101010100101
|
||||
neg_hex_with_spaces = - 0xABCDEF
|
||||
|
||||
# Testing for minimun size thresholds
|
||||
dec_4_digits = 1234 # Should not trigger, just below the threshold of 5 digits
|
||||
dec_5_digits = 12345 # Should trigger, 5 digits
|
||||
oct_4_digits = 0o1234 # Should not trigger, just below the threshold of 4 digits
|
||||
oct_5_digits = 0o12345 # Should trigger, 5 digits
|
||||
bin_8_digits = 0b01010101 # Should not trigger, just below the threshold of 9 digits
|
||||
bin_9_digits = 0b101010101 # Should trigger, 9 digits
|
||||
hex_4_digits = 0xABCD # Should not trigger, just below the threshold of 5 digits
|
||||
hex_5_digits = 0xABCDE # Should trigger, 5 digits
|
||||
flt_4_digits = .1234 # Should not trigger, just below the threshold of 5 digits
|
||||
flt_5_digits = .12345 # Should trigger, 5 digits
|
|
@ -1573,6 +1573,9 @@ pub(crate) fn expression(expr: &Expr, checker: &Checker) {
|
|||
if checker.is_rule_enabled(Rule::MathConstant) {
|
||||
refurb::rules::math_constant(checker, number_literal);
|
||||
}
|
||||
if checker.is_rule_enabled(Rule::LargeNumberWithoutUnderscoreSeparators) {
|
||||
ruff::rules::large_number_without_underscore_separators(checker, expr);
|
||||
}
|
||||
}
|
||||
Expr::StringLiteral(
|
||||
string_like @ ast::ExprStringLiteral {
|
||||
|
|
|
@ -1034,6 +1034,7 @@ pub fn code_to_rule(linter: Linter, code: &str) -> Option<(RuleGroup, Rule)> {
|
|||
(Ruff, "059") => (RuleGroup::Preview, rules::ruff::rules::UnusedUnpackedVariable),
|
||||
(Ruff, "060") => (RuleGroup::Preview, rules::ruff::rules::InEmptyCollection),
|
||||
(Ruff, "061") => (RuleGroup::Preview, rules::ruff::rules::LegacyFormPytestRaises),
|
||||
(Ruff, "062") => (RuleGroup::Preview, rules::ruff::rules::LargeNumberWithoutUnderscoreSeparators),
|
||||
(Ruff, "063") => (RuleGroup::Preview, rules::ruff::rules::AccessAnnotationsFromClassDict),
|
||||
(Ruff, "064") => (RuleGroup::Preview, rules::ruff::rules::NonOctalPermissions),
|
||||
(Ruff, "100") => (RuleGroup::Stable, rules::ruff::rules::UnusedNOQA),
|
||||
|
|
|
@ -110,6 +110,7 @@ mod tests {
|
|||
#[test_case(Rule::LegacyFormPytestRaises, Path::new("RUF061_raises.py"))]
|
||||
#[test_case(Rule::LegacyFormPytestRaises, Path::new("RUF061_warns.py"))]
|
||||
#[test_case(Rule::LegacyFormPytestRaises, Path::new("RUF061_deprecated_call.py"))]
|
||||
#[test_case(Rule::LargeNumberWithoutUnderscoreSeparators, Path::new("RUF062.py"))]
|
||||
#[test_case(Rule::NonOctalPermissions, Path::new("RUF064.py"))]
|
||||
#[test_case(Rule::RedirectedNOQA, Path::new("RUF101_0.py"))]
|
||||
#[test_case(Rule::RedirectedNOQA, Path::new("RUF101_1.py"))]
|
||||
|
@ -131,6 +132,7 @@ mod tests {
|
|||
&LinterSettings {
|
||||
ruff: super::settings::Settings {
|
||||
parenthesize_tuple_in_subscript: true,
|
||||
..Default::default()
|
||||
},
|
||||
..LinterSettings::for_rule(Rule::IncorrectlyParenthesizedTupleInSubscript)
|
||||
},
|
||||
|
@ -146,6 +148,7 @@ mod tests {
|
|||
&LinterSettings {
|
||||
ruff: super::settings::Settings {
|
||||
parenthesize_tuple_in_subscript: false,
|
||||
..Default::default()
|
||||
},
|
||||
unresolved_target_version: PythonVersion::PY310.into(),
|
||||
..LinterSettings::for_rule(Rule::IncorrectlyParenthesizedTupleInSubscript)
|
||||
|
|
|
@ -0,0 +1,205 @@
|
|||
use crate::AlwaysFixableViolation;
|
||||
use crate::checkers::ast::Checker;
|
||||
use crate::rules::ruff::settings::Settings;
|
||||
use ruff_diagnostics::{Edit, Fix};
|
||||
use ruff_macros::{ViolationMetadata, derive_message_formats};
|
||||
use ruff_python_ast as ast;
|
||||
use ruff_text_size::Ranged;
|
||||
|
||||
/// ## What it does
|
||||
/// Checks for numeric literals that could be more readable with underscore separators
|
||||
/// between groups of digits.
|
||||
///
|
||||
/// ## Why is this bad?
|
||||
/// Large numeric literals can be difficult to read. Using underscore separators
|
||||
/// improves readability by visually separating groups of digits.
|
||||
///
|
||||
/// ## Example
|
||||
///
|
||||
/// ```python
|
||||
/// # Before
|
||||
/// x = 1000000
|
||||
/// y = 1234567.89
|
||||
/// ```
|
||||
///
|
||||
/// Use instead:
|
||||
/// ```python
|
||||
/// # After
|
||||
/// x = 1_000_000
|
||||
/// y = 1_234_567.89
|
||||
/// ```
|
||||
///
|
||||
/// ## References
|
||||
/// - [PEP 515 - Underscores in Numeric Literals](https://peps.python.org/pep-0515/)
|
||||
/// - [Number Localization Formatting Guide](https://randombits.dev/articles/number-localization/formatting)
|
||||
#[derive(ViolationMetadata)]
|
||||
pub(crate) struct LargeNumberWithoutUnderscoreSeparators;
|
||||
|
||||
impl AlwaysFixableViolation for LargeNumberWithoutUnderscoreSeparators {
|
||||
#[derive_message_formats]
|
||||
fn message(&self) -> String {
|
||||
"Large numeric literal without underscore separators".to_string()
|
||||
}
|
||||
|
||||
fn fix_title(&self) -> String {
|
||||
"Add underscore separators to numeric literal".to_string()
|
||||
}
|
||||
}
|
||||
|
||||
/// RUF062: Large numeric literal without underscore separators
|
||||
pub(crate) fn large_number_without_underscore_separators(checker: &Checker, expr: &ast::Expr) {
|
||||
let value_text = checker.locator().slice(expr.range());
|
||||
|
||||
// format number to compare with the source
|
||||
let formatted_value: String =
|
||||
format_number_with_underscores(value_text, &checker.settings().ruff);
|
||||
|
||||
if formatted_value != value_text {
|
||||
checker
|
||||
.report_diagnostic(LargeNumberWithoutUnderscoreSeparators, expr.range())
|
||||
.set_fix(Fix::safe_edit(Edit::range_replacement(
|
||||
formatted_value,
|
||||
expr.range(),
|
||||
)));
|
||||
}
|
||||
}
|
||||
|
||||
/// Format a numeric literal with properly placed underscore separators
|
||||
fn format_number_with_underscores(value: &str, settings: &Settings) -> String {
|
||||
// Remove existing underscores
|
||||
let value = value.replace("_", "");
|
||||
if value.starts_with("0x") || value.starts_with("0X") {
|
||||
// Hexadecimal
|
||||
let prefix = &value[..2];
|
||||
let hex_part = &value[2..];
|
||||
|
||||
let formatted = format_digits(
|
||||
hex_part,
|
||||
settings.hex_digit_group_size,
|
||||
settings.hex_digit_group_size,
|
||||
settings.hex_digit_grouping_threshold,
|
||||
);
|
||||
format!("{}{}", prefix, formatted)
|
||||
} else if value.starts_with("0b") || value.starts_with("0B") {
|
||||
// Binary
|
||||
let prefix = &value[..2];
|
||||
let bin_part = &value[2..];
|
||||
|
||||
let formatted = format_digits(
|
||||
bin_part,
|
||||
settings.bin_digit_group_size,
|
||||
settings.bin_digit_group_size,
|
||||
settings.bin_digit_grouping_threshold,
|
||||
);
|
||||
format!("{}{}", prefix, formatted)
|
||||
} else if value.starts_with("0o") || value.starts_with("0O") {
|
||||
// Octal
|
||||
let prefix = &value[..2];
|
||||
let oct_part = &value[2..];
|
||||
|
||||
let formatted = format_digits(
|
||||
oct_part,
|
||||
settings.oct_digit_group_size,
|
||||
settings.oct_digit_group_size,
|
||||
settings.oct_digit_grouping_threshold,
|
||||
);
|
||||
format!("{}{}", prefix, formatted)
|
||||
} else {
|
||||
if value.contains(['e', 'E']) {
|
||||
// Handle scientific notation
|
||||
let parts: Vec<&str> = value.split(['e', 'E']).collect();
|
||||
let base = format_number_with_underscores(parts[0], settings);
|
||||
let exponent = parts[1];
|
||||
|
||||
// Determine which separator was used (e or E)
|
||||
let separator = if value.contains('e') { 'e' } else { 'E' };
|
||||
|
||||
return format!("{}{}{}", base, separator, exponent);
|
||||
}
|
||||
|
||||
// Decimal (integer or float)
|
||||
let parts: Vec<&str> = value.split('.').collect();
|
||||
let group_size = if settings.use_indian_decimal_format {
|
||||
2
|
||||
} else {
|
||||
3
|
||||
};
|
||||
let integer_part = format_digits(
|
||||
&parts[0],
|
||||
group_size,
|
||||
3,
|
||||
settings.dec_digit_grouping_threshold,
|
||||
);
|
||||
|
||||
if parts.len() > 1 {
|
||||
// It's a float, handle the fractional part
|
||||
let float_part = format_float(
|
||||
parts[1],
|
||||
group_size,
|
||||
3,
|
||||
settings.dec_digit_grouping_threshold,
|
||||
);
|
||||
format!("{}.{}", integer_part, float_part)
|
||||
} else {
|
||||
// It's an integer
|
||||
format!("{}", integer_part)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Helper function to format digits with underscores at specified intervals
|
||||
fn format_digits(
|
||||
digits: &str,
|
||||
group_size: usize,
|
||||
first_group_size: usize,
|
||||
threshold: usize,
|
||||
) -> String {
|
||||
if digits.len() < threshold || group_size == 0 || first_group_size == 0 {
|
||||
return digits.to_string();
|
||||
}
|
||||
|
||||
let mut result = String::with_capacity(digits.len() * 2);
|
||||
let mut count = 0;
|
||||
|
||||
// Process digits from right to left
|
||||
for c in digits.chars().rev() {
|
||||
if count == first_group_size
|
||||
|| (count > first_group_size + 1 && (count - first_group_size) % group_size == 0)
|
||||
{
|
||||
result.push('_');
|
||||
}
|
||||
result.push(c);
|
||||
count += 1;
|
||||
}
|
||||
|
||||
// Reverse the result to get the correct order
|
||||
result.chars().rev().collect()
|
||||
}
|
||||
|
||||
// Helper function to format float parts with underscores at specified intervals
|
||||
fn format_float(
|
||||
digits: &str,
|
||||
group_size: usize,
|
||||
first_group_size: usize,
|
||||
threshold: usize,
|
||||
) -> String {
|
||||
if digits.len() < threshold || group_size == 0 || first_group_size == 0 {
|
||||
return digits.to_string();
|
||||
}
|
||||
|
||||
let mut result = String::with_capacity(digits.len() * 2);
|
||||
let mut count = 0;
|
||||
|
||||
// Process digits from right to left
|
||||
for c in digits.chars() {
|
||||
if count == first_group_size
|
||||
|| (count > first_group_size && (count - first_group_size) % group_size == 0)
|
||||
{
|
||||
result.push('_');
|
||||
}
|
||||
result.push(c);
|
||||
count += 1;
|
||||
}
|
||||
|
||||
result
|
||||
}
|
|
@ -32,6 +32,7 @@ pub(crate) use needless_else::*;
|
|||
pub(crate) use never_union::*;
|
||||
pub(crate) use non_octal_permissions::*;
|
||||
pub(crate) use none_not_at_end_of_union::*;
|
||||
pub(crate) use large_number_without_underscore_separators::*;
|
||||
pub(crate) use parenthesize_chained_operators::*;
|
||||
pub(crate) use post_init_default::*;
|
||||
pub(crate) use pytest_raises_ambiguous_pattern::*;
|
||||
|
@ -62,6 +63,7 @@ pub(crate) use zip_instead_of_pairwise::*;
|
|||
|
||||
mod access_annotations_from_class_dict;
|
||||
mod ambiguous_unicode_character;
|
||||
mod large_number_without_underscore_separators;
|
||||
mod assert_with_print_message;
|
||||
mod assignment_in_assert;
|
||||
mod asyncio_dangling_task;
|
||||
|
|
|
@ -4,9 +4,33 @@ use crate::display_settings;
|
|||
use ruff_macros::CacheKey;
|
||||
use std::fmt;
|
||||
|
||||
#[derive(Debug, Clone, CacheKey, Default)]
|
||||
#[derive(Debug, Clone, CacheKey)]
|
||||
pub struct Settings {
|
||||
pub parenthesize_tuple_in_subscript: bool,
|
||||
pub use_indian_decimal_format: bool,
|
||||
pub hex_digit_group_size: usize,
|
||||
pub oct_digit_group_size: usize,
|
||||
pub bin_digit_group_size: usize,
|
||||
pub hex_digit_grouping_threshold: usize,
|
||||
pub dec_digit_grouping_threshold: usize,
|
||||
pub oct_digit_grouping_threshold: usize,
|
||||
pub bin_digit_grouping_threshold: usize,
|
||||
}
|
||||
|
||||
impl Default for Settings {
|
||||
fn default() -> Self {
|
||||
Settings {
|
||||
parenthesize_tuple_in_subscript: false,
|
||||
use_indian_decimal_format: false,
|
||||
hex_digit_group_size: 4,
|
||||
oct_digit_group_size: 4,
|
||||
bin_digit_group_size: 8,
|
||||
hex_digit_grouping_threshold: 5,
|
||||
dec_digit_grouping_threshold: 5,
|
||||
oct_digit_grouping_threshold: 5,
|
||||
bin_digit_grouping_threshold: 8,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for Settings {
|
||||
|
@ -16,6 +40,14 @@ impl fmt::Display for Settings {
|
|||
namespace = "linter.ruff",
|
||||
fields = [
|
||||
self.parenthesize_tuple_in_subscript,
|
||||
self.use_indian_decimal_format,
|
||||
self.bin_digit_grouping_threshold,
|
||||
self.oct_digit_grouping_threshold,
|
||||
self.hex_digit_grouping_threshold,
|
||||
self.dec_digit_grouping_threshold,
|
||||
self.bin_digit_group_size,
|
||||
self.oct_digit_group_size,
|
||||
self.hex_digit_group_size,
|
||||
]
|
||||
}
|
||||
Ok(())
|
||||
|
|
|
@ -0,0 +1,511 @@
|
|||
---
|
||||
source: crates/ruff_linter/src/rules/ruff/mod.rs
|
||||
---
|
||||
RUF062.py:4:5: RUF062 [*] Large numeric literal without underscore separators
|
||||
|
|
||||
3 | # These should trigger the rule (large numbers without underscore separators)
|
||||
4 | i = 1000000
|
||||
| ^^^^^^^ RUF062
|
||||
5 | f = 123456789.123456789
|
||||
6 | x = 0x1234ABCD
|
||||
|
|
||||
= help: Add underscore separators to numeric literal
|
||||
|
||||
ℹ Safe fix
|
||||
1 1 | """Tests for the RUF062 rule (large numeric literals without underscore separators)."""
|
||||
2 2 |
|
||||
3 3 | # These should trigger the rule (large numbers without underscore separators)
|
||||
4 |-i = 1000000
|
||||
4 |+i = 1_000_000
|
||||
5 5 | f = 123456789.123456789
|
||||
6 6 | x = 0x1234ABCD
|
||||
7 7 | b = 0b10101010101010101010101
|
||||
|
||||
RUF062.py:5:5: RUF062 [*] Large numeric literal without underscore separators
|
||||
|
|
||||
3 | # These should trigger the rule (large numbers without underscore separators)
|
||||
4 | i = 1000000
|
||||
5 | f = 123456789.123456789
|
||||
| ^^^^^^^^^^^^^^^^^^^ RUF062
|
||||
6 | x = 0x1234ABCD
|
||||
7 | b = 0b10101010101010101010101
|
||||
|
|
||||
= help: Add underscore separators to numeric literal
|
||||
|
||||
ℹ Safe fix
|
||||
2 2 |
|
||||
3 3 | # These should trigger the rule (large numbers without underscore separators)
|
||||
4 4 | i = 1000000
|
||||
5 |-f = 123456789.123456789
|
||||
5 |+f = 123_456_789.123_456_789
|
||||
6 6 | x = 0x1234ABCD
|
||||
7 7 | b = 0b10101010101010101010101
|
||||
8 8 | o = 0o12345671234
|
||||
|
||||
RUF062.py:6:5: RUF062 [*] Large numeric literal without underscore separators
|
||||
|
|
||||
4 | i = 1000000
|
||||
5 | f = 123456789.123456789
|
||||
6 | x = 0x1234ABCD
|
||||
| ^^^^^^^^^^ RUF062
|
||||
7 | b = 0b10101010101010101010101
|
||||
8 | o = 0o12345671234
|
||||
|
|
||||
= help: Add underscore separators to numeric literal
|
||||
|
||||
ℹ Safe fix
|
||||
3 3 | # These should trigger the rule (large numbers without underscore separators)
|
||||
4 4 | i = 1000000
|
||||
5 5 | f = 123456789.123456789
|
||||
6 |-x = 0x1234ABCD
|
||||
6 |+x = 0x1234_ABCD
|
||||
7 7 | b = 0b10101010101010101010101
|
||||
8 8 | o = 0o12345671234
|
||||
9 9 |
|
||||
|
||||
RUF062.py:7:5: RUF062 [*] Large numeric literal without underscore separators
|
||||
|
|
||||
5 | f = 123456789.123456789
|
||||
6 | x = 0x1234ABCD
|
||||
7 | b = 0b10101010101010101010101
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^ RUF062
|
||||
8 | o = 0o12345671234
|
||||
|
|
||||
= help: Add underscore separators to numeric literal
|
||||
|
||||
ℹ Safe fix
|
||||
4 4 | i = 1000000
|
||||
5 5 | f = 123456789.123456789
|
||||
6 6 | x = 0x1234ABCD
|
||||
7 |-b = 0b10101010101010101010101
|
||||
7 |+b = 0b1010101_01010101_01010101
|
||||
8 8 | o = 0o12345671234
|
||||
9 9 |
|
||||
10 10 | # Scientific notation
|
||||
|
||||
RUF062.py:8:5: RUF062 [*] Large numeric literal without underscore separators
|
||||
|
|
||||
6 | x = 0x1234ABCD
|
||||
7 | b = 0b10101010101010101010101
|
||||
8 | o = 0o12345671234
|
||||
| ^^^^^^^^^^^^^ RUF062
|
||||
9 |
|
||||
10 | # Scientific notation
|
||||
|
|
||||
= help: Add underscore separators to numeric literal
|
||||
|
||||
ℹ Safe fix
|
||||
5 5 | f = 123456789.123456789
|
||||
6 6 | x = 0x1234ABCD
|
||||
7 7 | b = 0b10101010101010101010101
|
||||
8 |-o = 0o12345671234
|
||||
8 |+o = 0o123_4567_1234
|
||||
9 9 |
|
||||
10 10 | # Scientific notation
|
||||
11 11 | sci = 1000000e10
|
||||
|
||||
RUF062.py:11:7: RUF062 [*] Large numeric literal without underscore separators
|
||||
|
|
||||
10 | # Scientific notation
|
||||
11 | sci = 1000000e10
|
||||
| ^^^^^^^^^^ RUF062
|
||||
12 | sci_uppercase = 1000000E10
|
||||
|
|
||||
= help: Add underscore separators to numeric literal
|
||||
|
||||
ℹ Safe fix
|
||||
8 8 | o = 0o12345671234
|
||||
9 9 |
|
||||
10 10 | # Scientific notation
|
||||
11 |-sci = 1000000e10
|
||||
11 |+sci = 1_000_000e10
|
||||
12 12 | sci_uppercase = 1000000E10
|
||||
13 13 |
|
||||
14 14 | # These should not trigger the rule (small numbers or already have separators)
|
||||
|
||||
RUF062.py:12:17: RUF062 [*] Large numeric literal without underscore separators
|
||||
|
|
||||
10 | # Scientific notation
|
||||
11 | sci = 1000000e10
|
||||
12 | sci_uppercase = 1000000E10
|
||||
| ^^^^^^^^^^ RUF062
|
||||
13 |
|
||||
14 | # These should not trigger the rule (small numbers or already have separators)
|
||||
|
|
||||
= help: Add underscore separators to numeric literal
|
||||
|
||||
ℹ Safe fix
|
||||
9 9 |
|
||||
10 10 | # Scientific notation
|
||||
11 11 | sci = 1000000e10
|
||||
12 |-sci_uppercase = 1000000E10
|
||||
12 |+sci_uppercase = 1_000_000E10
|
||||
13 13 |
|
||||
14 14 | # These should not trigger the rule (small numbers or already have separators)
|
||||
15 15 | dec_small_int = 1234
|
||||
|
||||
RUF062.py:24:28: RUF062 [*] Large numeric literal without underscore separators
|
||||
|
|
||||
23 | # These should trigger the rule because their separators are misplaced
|
||||
24 | dec_misplaced_separators = 123_4567_89
|
||||
| ^^^^^^^^^^^ RUF062
|
||||
25 | oct_misplaced_separators = 0o12_34_56
|
||||
26 | hex_misplaced_separators = 0xABCD_EF
|
||||
|
|
||||
= help: Add underscore separators to numeric literal
|
||||
|
||||
ℹ Safe fix
|
||||
21 21 | sci_with_separators = 1_000_000e10
|
||||
22 22 |
|
||||
23 23 | # These should trigger the rule because their separators are misplaced
|
||||
24 |-dec_misplaced_separators = 123_4567_89
|
||||
24 |+dec_misplaced_separators = 123_456_789
|
||||
25 25 | oct_misplaced_separators = 0o12_34_56
|
||||
26 26 | hex_misplaced_separators = 0xABCD_EF
|
||||
27 27 | flt_misplaced_separators = 123.12_3456_789
|
||||
|
||||
RUF062.py:25:28: RUF062 [*] Large numeric literal without underscore separators
|
||||
|
|
||||
23 | # These should trigger the rule because their separators are misplaced
|
||||
24 | dec_misplaced_separators = 123_4567_89
|
||||
25 | oct_misplaced_separators = 0o12_34_56
|
||||
| ^^^^^^^^^^ RUF062
|
||||
26 | hex_misplaced_separators = 0xABCD_EF
|
||||
27 | flt_misplaced_separators = 123.12_3456_789
|
||||
|
|
||||
= help: Add underscore separators to numeric literal
|
||||
|
||||
ℹ Safe fix
|
||||
22 22 |
|
||||
23 23 | # These should trigger the rule because their separators are misplaced
|
||||
24 24 | dec_misplaced_separators = 123_4567_89
|
||||
25 |-oct_misplaced_separators = 0o12_34_56
|
||||
25 |+oct_misplaced_separators = 0o12_3456
|
||||
26 26 | hex_misplaced_separators = 0xABCD_EF
|
||||
27 27 | flt_misplaced_separators = 123.12_3456_789
|
||||
28 28 |
|
||||
|
||||
RUF062.py:26:28: RUF062 [*] Large numeric literal without underscore separators
|
||||
|
|
||||
24 | dec_misplaced_separators = 123_4567_89
|
||||
25 | oct_misplaced_separators = 0o12_34_56
|
||||
26 | hex_misplaced_separators = 0xABCD_EF
|
||||
| ^^^^^^^^^ RUF062
|
||||
27 | flt_misplaced_separators = 123.12_3456_789
|
||||
|
|
||||
= help: Add underscore separators to numeric literal
|
||||
|
||||
ℹ Safe fix
|
||||
23 23 | # These should trigger the rule because their separators are misplaced
|
||||
24 24 | dec_misplaced_separators = 123_4567_89
|
||||
25 25 | oct_misplaced_separators = 0o12_34_56
|
||||
26 |-hex_misplaced_separators = 0xABCD_EF
|
||||
26 |+hex_misplaced_separators = 0xAB_CDEF
|
||||
27 27 | flt_misplaced_separators = 123.12_3456_789
|
||||
28 28 |
|
||||
29 29 | # uppercase base prefix
|
||||
|
||||
RUF062.py:27:28: RUF062 [*] Large numeric literal without underscore separators
|
||||
|
|
||||
25 | oct_misplaced_separators = 0o12_34_56
|
||||
26 | hex_misplaced_separators = 0xABCD_EF
|
||||
27 | flt_misplaced_separators = 123.12_3456_789
|
||||
| ^^^^^^^^^^^^^^^ RUF062
|
||||
28 |
|
||||
29 | # uppercase base prefix
|
||||
|
|
||||
= help: Add underscore separators to numeric literal
|
||||
|
||||
ℹ Safe fix
|
||||
24 24 | dec_misplaced_separators = 123_4567_89
|
||||
25 25 | oct_misplaced_separators = 0o12_34_56
|
||||
26 26 | hex_misplaced_separators = 0xABCD_EF
|
||||
27 |-flt_misplaced_separators = 123.12_3456_789
|
||||
27 |+flt_misplaced_separators = 123.123_456_789
|
||||
28 28 |
|
||||
29 29 | # uppercase base prefix
|
||||
30 30 | hex_uppercase = 0XABCDEF
|
||||
|
||||
RUF062.py:30:17: RUF062 [*] Large numeric literal without underscore separators
|
||||
|
|
||||
29 | # uppercase base prefix
|
||||
30 | hex_uppercase = 0XABCDEF
|
||||
| ^^^^^^^^ RUF062
|
||||
31 | oct_uppercase = 0O123456
|
||||
32 | bin_uppercase = 0B01010101010101
|
||||
|
|
||||
= help: Add underscore separators to numeric literal
|
||||
|
||||
ℹ Safe fix
|
||||
27 27 | flt_misplaced_separators = 123.12_3456_789
|
||||
28 28 |
|
||||
29 29 | # uppercase base prefix
|
||||
30 |-hex_uppercase = 0XABCDEF
|
||||
30 |+hex_uppercase = 0XAB_CDEF
|
||||
31 31 | oct_uppercase = 0O123456
|
||||
32 32 | bin_uppercase = 0B01010101010101
|
||||
33 33 |
|
||||
|
||||
RUF062.py:31:17: RUF062 [*] Large numeric literal without underscore separators
|
||||
|
|
||||
29 | # uppercase base prefix
|
||||
30 | hex_uppercase = 0XABCDEF
|
||||
31 | oct_uppercase = 0O123456
|
||||
| ^^^^^^^^ RUF062
|
||||
32 | bin_uppercase = 0B01010101010101
|
||||
|
|
||||
= help: Add underscore separators to numeric literal
|
||||
|
||||
ℹ Safe fix
|
||||
28 28 |
|
||||
29 29 | # uppercase base prefix
|
||||
30 30 | hex_uppercase = 0XABCDEF
|
||||
31 |-oct_uppercase = 0O123456
|
||||
31 |+oct_uppercase = 0O12_3456
|
||||
32 32 | bin_uppercase = 0B01010101010101
|
||||
33 33 |
|
||||
34 34 | # Negative numbers should also be checked
|
||||
|
||||
RUF062.py:32:17: RUF062 [*] Large numeric literal without underscore separators
|
||||
|
|
||||
30 | hex_uppercase = 0XABCDEF
|
||||
31 | oct_uppercase = 0O123456
|
||||
32 | bin_uppercase = 0B01010101010101
|
||||
| ^^^^^^^^^^^^^^^^ RUF062
|
||||
33 |
|
||||
34 | # Negative numbers should also be checked
|
||||
|
|
||||
= help: Add underscore separators to numeric literal
|
||||
|
||||
ℹ Safe fix
|
||||
29 29 | # uppercase base prefix
|
||||
30 30 | hex_uppercase = 0XABCDEF
|
||||
31 31 | oct_uppercase = 0O123456
|
||||
32 |-bin_uppercase = 0B01010101010101
|
||||
32 |+bin_uppercase = 0B010101_01010101
|
||||
33 33 |
|
||||
34 34 | # Negative numbers should also be checked
|
||||
35 35 | neg_large = -1000000
|
||||
|
||||
RUF062.py:35:14: RUF062 [*] Large numeric literal without underscore separators
|
||||
|
|
||||
34 | # Negative numbers should also be checked
|
||||
35 | neg_large = -1000000
|
||||
| ^^^^^^^ RUF062
|
||||
36 | neg_with_separators = -1_000_000 # should not trigger
|
||||
37 | neg_with_spaces = - 100000
|
||||
|
|
||||
= help: Add underscore separators to numeric literal
|
||||
|
||||
ℹ Safe fix
|
||||
32 32 | bin_uppercase = 0B01010101010101
|
||||
33 33 |
|
||||
34 34 | # Negative numbers should also be checked
|
||||
35 |-neg_large = -1000000
|
||||
35 |+neg_large = -1_000_000
|
||||
36 36 | neg_with_separators = -1_000_000 # should not trigger
|
||||
37 37 | neg_with_spaces = - 100000
|
||||
38 38 | neg_oct = -0o1234567
|
||||
|
||||
RUF062.py:37:23: RUF062 [*] Large numeric literal without underscore separators
|
||||
|
|
||||
35 | neg_large = -1000000
|
||||
36 | neg_with_separators = -1_000_000 # should not trigger
|
||||
37 | neg_with_spaces = - 100000
|
||||
| ^^^^^^ RUF062
|
||||
38 | neg_oct = -0o1234567
|
||||
39 | neg_hex = -0xABCDEF
|
||||
|
|
||||
= help: Add underscore separators to numeric literal
|
||||
|
||||
ℹ Safe fix
|
||||
34 34 | # Negative numbers should also be checked
|
||||
35 35 | neg_large = -1000000
|
||||
36 36 | neg_with_separators = -1_000_000 # should not trigger
|
||||
37 |-neg_with_spaces = - 100000
|
||||
37 |+neg_with_spaces = - 100_000
|
||||
38 38 | neg_oct = -0o1234567
|
||||
39 39 | neg_hex = -0xABCDEF
|
||||
40 40 | neg_bin -0b0101010100101
|
||||
|
||||
RUF062.py:38:12: RUF062 [*] Large numeric literal without underscore separators
|
||||
|
|
||||
36 | neg_with_separators = -1_000_000 # should not trigger
|
||||
37 | neg_with_spaces = - 100000
|
||||
38 | neg_oct = -0o1234567
|
||||
| ^^^^^^^^^ RUF062
|
||||
39 | neg_hex = -0xABCDEF
|
||||
40 | neg_bin -0b0101010100101
|
||||
|
|
||||
= help: Add underscore separators to numeric literal
|
||||
|
||||
ℹ Safe fix
|
||||
35 35 | neg_large = -1000000
|
||||
36 36 | neg_with_separators = -1_000_000 # should not trigger
|
||||
37 37 | neg_with_spaces = - 100000
|
||||
38 |-neg_oct = -0o1234567
|
||||
38 |+neg_oct = -0o123_4567
|
||||
39 39 | neg_hex = -0xABCDEF
|
||||
40 40 | neg_bin -0b0101010100101
|
||||
41 41 | neg_hex_with_spaces = - 0xABCDEF
|
||||
|
||||
RUF062.py:39:12: RUF062 [*] Large numeric literal without underscore separators
|
||||
|
|
||||
37 | neg_with_spaces = - 100000
|
||||
38 | neg_oct = -0o1234567
|
||||
39 | neg_hex = -0xABCDEF
|
||||
| ^^^^^^^^ RUF062
|
||||
40 | neg_bin -0b0101010100101
|
||||
41 | neg_hex_with_spaces = - 0xABCDEF
|
||||
|
|
||||
= help: Add underscore separators to numeric literal
|
||||
|
||||
ℹ Safe fix
|
||||
36 36 | neg_with_separators = -1_000_000 # should not trigger
|
||||
37 37 | neg_with_spaces = - 100000
|
||||
38 38 | neg_oct = -0o1234567
|
||||
39 |-neg_hex = -0xABCDEF
|
||||
39 |+neg_hex = -0xAB_CDEF
|
||||
40 40 | neg_bin -0b0101010100101
|
||||
41 41 | neg_hex_with_spaces = - 0xABCDEF
|
||||
42 42 |
|
||||
|
||||
RUF062.py:40:10: RUF062 [*] Large numeric literal without underscore separators
|
||||
|
|
||||
38 | neg_oct = -0o1234567
|
||||
39 | neg_hex = -0xABCDEF
|
||||
40 | neg_bin -0b0101010100101
|
||||
| ^^^^^^^^^^^^^^^ RUF062
|
||||
41 | neg_hex_with_spaces = - 0xABCDEF
|
||||
|
|
||||
= help: Add underscore separators to numeric literal
|
||||
|
||||
ℹ Safe fix
|
||||
37 37 | neg_with_spaces = - 100000
|
||||
38 38 | neg_oct = -0o1234567
|
||||
39 39 | neg_hex = -0xABCDEF
|
||||
40 |-neg_bin -0b0101010100101
|
||||
40 |+neg_bin -0b01010_10100101
|
||||
41 41 | neg_hex_with_spaces = - 0xABCDEF
|
||||
42 42 |
|
||||
43 43 | # Testing for minimun size thresholds
|
||||
|
||||
RUF062.py:41:27: RUF062 [*] Large numeric literal without underscore separators
|
||||
|
|
||||
39 | neg_hex = -0xABCDEF
|
||||
40 | neg_bin -0b0101010100101
|
||||
41 | neg_hex_with_spaces = - 0xABCDEF
|
||||
| ^^^^^^^^ RUF062
|
||||
42 |
|
||||
43 | # Testing for minimun size thresholds
|
||||
|
|
||||
= help: Add underscore separators to numeric literal
|
||||
|
||||
ℹ Safe fix
|
||||
38 38 | neg_oct = -0o1234567
|
||||
39 39 | neg_hex = -0xABCDEF
|
||||
40 40 | neg_bin -0b0101010100101
|
||||
41 |-neg_hex_with_spaces = - 0xABCDEF
|
||||
41 |+neg_hex_with_spaces = - 0xAB_CDEF
|
||||
42 42 |
|
||||
43 43 | # Testing for minimun size thresholds
|
||||
44 44 | dec_4_digits = 1234 # Should not trigger, just below the threshold of 5 digits
|
||||
|
||||
RUF062.py:45:16: RUF062 [*] Large numeric literal without underscore separators
|
||||
|
|
||||
43 | # Testing for minimun size thresholds
|
||||
44 | dec_4_digits = 1234 # Should not trigger, just below the threshold of 5 digits
|
||||
45 | dec_5_digits = 12345 # Should trigger, 5 digits
|
||||
| ^^^^^ RUF062
|
||||
46 | oct_4_digits = 0o1234 # Should not trigger, just below the threshold of 4 digits
|
||||
47 | oct_5_digits = 0o12345 # Should trigger, 5 digits
|
||||
|
|
||||
= help: Add underscore separators to numeric literal
|
||||
|
||||
ℹ Safe fix
|
||||
42 42 |
|
||||
43 43 | # Testing for minimun size thresholds
|
||||
44 44 | dec_4_digits = 1234 # Should not trigger, just below the threshold of 5 digits
|
||||
45 |-dec_5_digits = 12345 # Should trigger, 5 digits
|
||||
45 |+dec_5_digits = 12_345 # Should trigger, 5 digits
|
||||
46 46 | oct_4_digits = 0o1234 # Should not trigger, just below the threshold of 4 digits
|
||||
47 47 | oct_5_digits = 0o12345 # Should trigger, 5 digits
|
||||
48 48 | bin_8_digits = 0b01010101 # Should not trigger, just below the threshold of 9 digits
|
||||
|
||||
RUF062.py:47:16: RUF062 [*] Large numeric literal without underscore separators
|
||||
|
|
||||
45 | dec_5_digits = 12345 # Should trigger, 5 digits
|
||||
46 | oct_4_digits = 0o1234 # Should not trigger, just below the threshold of 4 digits
|
||||
47 | oct_5_digits = 0o12345 # Should trigger, 5 digits
|
||||
| ^^^^^^^ RUF062
|
||||
48 | bin_8_digits = 0b01010101 # Should not trigger, just below the threshold of 9 digits
|
||||
49 | bin_9_digits = 0b101010101 # Should trigger, 9 digits
|
||||
|
|
||||
= help: Add underscore separators to numeric literal
|
||||
|
||||
ℹ Safe fix
|
||||
44 44 | dec_4_digits = 1234 # Should not trigger, just below the threshold of 5 digits
|
||||
45 45 | dec_5_digits = 12345 # Should trigger, 5 digits
|
||||
46 46 | oct_4_digits = 0o1234 # Should not trigger, just below the threshold of 4 digits
|
||||
47 |-oct_5_digits = 0o12345 # Should trigger, 5 digits
|
||||
47 |+oct_5_digits = 0o1_2345 # Should trigger, 5 digits
|
||||
48 48 | bin_8_digits = 0b01010101 # Should not trigger, just below the threshold of 9 digits
|
||||
49 49 | bin_9_digits = 0b101010101 # Should trigger, 9 digits
|
||||
50 50 | hex_4_digits = 0xABCD # Should not trigger, just below the threshold of 5 digits
|
||||
|
||||
RUF062.py:49:16: RUF062 [*] Large numeric literal without underscore separators
|
||||
|
|
||||
47 | oct_5_digits = 0o12345 # Should trigger, 5 digits
|
||||
48 | bin_8_digits = 0b01010101 # Should not trigger, just below the threshold of 9 digits
|
||||
49 | bin_9_digits = 0b101010101 # Should trigger, 9 digits
|
||||
| ^^^^^^^^^^^ RUF062
|
||||
50 | hex_4_digits = 0xABCD # Should not trigger, just below the threshold of 5 digits
|
||||
51 | hex_5_digits = 0xABCDE # Should trigger, 5 digits
|
||||
|
|
||||
= help: Add underscore separators to numeric literal
|
||||
|
||||
ℹ Safe fix
|
||||
46 46 | oct_4_digits = 0o1234 # Should not trigger, just below the threshold of 4 digits
|
||||
47 47 | oct_5_digits = 0o12345 # Should trigger, 5 digits
|
||||
48 48 | bin_8_digits = 0b01010101 # Should not trigger, just below the threshold of 9 digits
|
||||
49 |-bin_9_digits = 0b101010101 # Should trigger, 9 digits
|
||||
49 |+bin_9_digits = 0b1_01010101 # Should trigger, 9 digits
|
||||
50 50 | hex_4_digits = 0xABCD # Should not trigger, just below the threshold of 5 digits
|
||||
51 51 | hex_5_digits = 0xABCDE # Should trigger, 5 digits
|
||||
52 52 | flt_4_digits = .1234 # Should not trigger, just below the threshold of 5 digits
|
||||
|
||||
RUF062.py:51:16: RUF062 [*] Large numeric literal without underscore separators
|
||||
|
|
||||
49 | bin_9_digits = 0b101010101 # Should trigger, 9 digits
|
||||
50 | hex_4_digits = 0xABCD # Should not trigger, just below the threshold of 5 digits
|
||||
51 | hex_5_digits = 0xABCDE # Should trigger, 5 digits
|
||||
| ^^^^^^^ RUF062
|
||||
52 | flt_4_digits = .1234 # Should not trigger, just below the threshold of 5 digits
|
||||
53 | flt_5_digits = .12345 # Should trigger, 5 digits
|
||||
|
|
||||
= help: Add underscore separators to numeric literal
|
||||
|
||||
ℹ Safe fix
|
||||
48 48 | bin_8_digits = 0b01010101 # Should not trigger, just below the threshold of 9 digits
|
||||
49 49 | bin_9_digits = 0b101010101 # Should trigger, 9 digits
|
||||
50 50 | hex_4_digits = 0xABCD # Should not trigger, just below the threshold of 5 digits
|
||||
51 |-hex_5_digits = 0xABCDE # Should trigger, 5 digits
|
||||
51 |+hex_5_digits = 0xA_BCDE # Should trigger, 5 digits
|
||||
52 52 | flt_4_digits = .1234 # Should not trigger, just below the threshold of 5 digits
|
||||
53 53 | flt_5_digits = .12345 # Should trigger, 5 digits
|
||||
|
||||
RUF062.py:53:16: RUF062 [*] Large numeric literal without underscore separators
|
||||
|
|
||||
51 | hex_5_digits = 0xABCDE # Should trigger, 5 digits
|
||||
52 | flt_4_digits = .1234 # Should not trigger, just below the threshold of 5 digits
|
||||
53 | flt_5_digits = .12345 # Should trigger, 5 digits
|
||||
| ^^^^^^ RUF062
|
||||
|
|
||||
= help: Add underscore separators to numeric literal
|
||||
|
||||
ℹ Safe fix
|
||||
50 50 | hex_4_digits = 0xABCD # Should not trigger, just below the threshold of 5 digits
|
||||
51 51 | hex_5_digits = 0xABCDE # Should trigger, 5 digits
|
||||
52 52 | flt_4_digits = .1234 # Should not trigger, just below the threshold of 5 digits
|
||||
53 |-flt_5_digits = .12345 # Should trigger, 5 digits
|
||||
53 |+flt_5_digits = .123_45 # Should trigger, 5 digits
|
|
@ -3454,6 +3454,70 @@ pub struct RuffOptions {
|
|||
note = "The `allowed-markup-names` option has been moved to the `flake8-bandit` section of the configuration."
|
||||
)]
|
||||
pub allowed_markup_calls: Option<Vec<String>>,
|
||||
|
||||
/// Size of digits groups for large hexadecimal numbers.
|
||||
#[option(
|
||||
default = "4",
|
||||
value_type = "integer",
|
||||
example = "hex-digit-group-size = 4"
|
||||
)]
|
||||
pub hex_digit_group_size: Option<usize>,
|
||||
|
||||
/// Size of digits groups for large octal numbers.
|
||||
#[option(
|
||||
default = "4",
|
||||
value_type = "integer",
|
||||
example = "oct-digit-group-size = 4"
|
||||
)]
|
||||
pub oct_digit_group_size: Option<usize>,
|
||||
|
||||
/// Size of digits groups for large binary numbers.
|
||||
#[option(
|
||||
default = "8",
|
||||
value_type = "integer",
|
||||
example = "bin-digit-group-size = 8"
|
||||
)]
|
||||
pub bin_digit_group_size: Option<usize>,
|
||||
|
||||
/// Whether to use Indian-style decimal formatting
|
||||
#[option(
|
||||
default = r#"false"#,
|
||||
value_type = "bool",
|
||||
example = "use-indian-decimal-formatting = false"
|
||||
)]
|
||||
pub use_indian_decimal_formatting: Option<bool>,
|
||||
|
||||
/// Minimum number of decimal digits to trigger grouping
|
||||
#[option(
|
||||
default = "5",
|
||||
value_type = "integer",
|
||||
example = "dec-digit-grouping-threshold = 5"
|
||||
)]
|
||||
pub dec_digit_grouping_threshold: Option<usize>,
|
||||
|
||||
/// Minimum number of hexadecimal digits to trigger grouping
|
||||
#[option(
|
||||
default = "5",
|
||||
value_type = "integer",
|
||||
example = "hex-digit-grouping-threshold = 5"
|
||||
)]
|
||||
pub hex_digit_grouping_threshold: Option<usize>,
|
||||
|
||||
/// Minimum number of octal digits to trigger grouping
|
||||
#[option(
|
||||
default = "5",
|
||||
value_type = "integer",
|
||||
example = "oct-digit-grouping-threshold = 5"
|
||||
)]
|
||||
pub oct_digit_grouping_threshold: Option<usize>,
|
||||
|
||||
/// Minimum number of binary digits to trigger grouping
|
||||
#[option(
|
||||
default = "9",
|
||||
value_type = "integer",
|
||||
example = "bin-digit-grouping-threshold = 5"
|
||||
)]
|
||||
pub bin_digit_grouping_threshold: Option<usize>,
|
||||
}
|
||||
|
||||
impl RuffOptions {
|
||||
|
@ -3462,6 +3526,14 @@ impl RuffOptions {
|
|||
parenthesize_tuple_in_subscript: self
|
||||
.parenthesize_tuple_in_subscript
|
||||
.unwrap_or_default(),
|
||||
use_indian_decimal_format: self.use_indian_decimal_formatting.unwrap(),
|
||||
hex_digit_group_size: self.hex_digit_group_size.unwrap_or_default(),
|
||||
oct_digit_group_size: self.oct_digit_group_size.unwrap_or_default(),
|
||||
bin_digit_group_size: self.bin_digit_group_size.unwrap_or_default(),
|
||||
dec_digit_grouping_threshold: self.dec_digit_grouping_threshold.unwrap_or_default(),
|
||||
hex_digit_grouping_threshold: self.hex_digit_grouping_threshold.unwrap_or_default(),
|
||||
oct_digit_grouping_threshold: self.oct_digit_grouping_threshold.unwrap_or_default(),
|
||||
bin_digit_grouping_threshold: self.bin_digit_grouping_threshold.unwrap_or_default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
1
ruff.schema.json
generated
1
ruff.schema.json
generated
|
@ -4040,6 +4040,7 @@
|
|||
"RUF06",
|
||||
"RUF060",
|
||||
"RUF061",
|
||||
"RUF062",
|
||||
"RUF063",
|
||||
"RUF064",
|
||||
"RUF1",
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue