mirror of
https://github.com/astral-sh/ruff.git
synced 2025-09-30 13:51:37 +00:00
Error on zero tab width (#6429)
## Summary Error if `tab-size` is set to zero (it is used as a divisor). Closes #6423. Also fixes a typo. ## Test Plan Running ruff with a config ```toml [tool.ruff] tab-size = 0 ``` returns an error message to the user saying that `tab-size` must be greater than zero.
This commit is contained in:
parent
55d6fd53cd
commit
1b9fed8397
6 changed files with 27 additions and 19 deletions
|
@ -1,4 +1,5 @@
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
use std::num::NonZeroU8;
|
||||||
use unicode_width::UnicodeWidthChar;
|
use unicode_width::UnicodeWidthChar;
|
||||||
|
|
||||||
use ruff_macros::CacheKey;
|
use ruff_macros::CacheKey;
|
||||||
|
@ -83,7 +84,7 @@ impl LineWidth {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn update(mut self, chars: impl Iterator<Item = char>) -> Self {
|
fn update(mut self, chars: impl Iterator<Item = char>) -> Self {
|
||||||
let tab_size: usize = self.tab_size.into();
|
let tab_size: usize = self.tab_size.as_usize();
|
||||||
for c in chars {
|
for c in chars {
|
||||||
match c {
|
match c {
|
||||||
'\t' => {
|
'\t' => {
|
||||||
|
@ -144,22 +145,22 @@ impl PartialOrd<LineLength> for LineWidth {
|
||||||
/// The size of a tab.
|
/// The size of a tab.
|
||||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize, CacheKey)]
|
#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize, CacheKey)]
|
||||||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||||
pub struct TabSize(pub u8);
|
pub struct TabSize(pub NonZeroU8);
|
||||||
|
|
||||||
|
impl TabSize {
|
||||||
|
fn as_usize(self) -> usize {
|
||||||
|
self.0.get() as usize
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Default for TabSize {
|
impl Default for TabSize {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self(4)
|
Self(NonZeroU8::new(4).unwrap())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<u8> for TabSize {
|
impl From<NonZeroU8> for TabSize {
|
||||||
fn from(tab_size: u8) -> Self {
|
fn from(tab_size: NonZeroU8) -> Self {
|
||||||
Self(tab_size)
|
Self(tab_size)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<TabSize> for usize {
|
|
||||||
fn from(tab_size: TabSize) -> Self {
|
|
||||||
tab_size.0 as usize
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -293,12 +293,10 @@ impl Display for MessageCodeFrame<'_> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn replace_whitespace(source: &str, annotation_range: TextRange) -> SourceCode {
|
fn replace_whitespace(source: &str, annotation_range: TextRange) -> SourceCode {
|
||||||
static TAB_SIZE: TabSize = TabSize(4); // TODO(jonathan): use `tab-size`
|
|
||||||
|
|
||||||
let mut result = String::new();
|
let mut result = String::new();
|
||||||
let mut last_end = 0;
|
let mut last_end = 0;
|
||||||
let mut range = annotation_range;
|
let mut range = annotation_range;
|
||||||
let mut line_width = LineWidth::new(TAB_SIZE);
|
let mut line_width = LineWidth::new(TabSize::default());
|
||||||
|
|
||||||
for (index, c) in source.char_indices() {
|
for (index, c) in source.char_indices() {
|
||||||
let old_width = line_width.get();
|
let old_width = line_width.get();
|
||||||
|
|
|
@ -6,6 +6,7 @@ pub(crate) mod helpers;
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
|
use std::num::NonZeroU8;
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
|
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
|
@ -204,7 +205,7 @@ mod tests {
|
||||||
let diagnostics = test_path(
|
let diagnostics = test_path(
|
||||||
Path::new("pycodestyle/E501_2.py"),
|
Path::new("pycodestyle/E501_2.py"),
|
||||||
&settings::Settings {
|
&settings::Settings {
|
||||||
tab_size: tab_size.into(),
|
tab_size: NonZeroU8::new(tab_size).unwrap().into(),
|
||||||
..settings::Settings::for_rule(Rule::LineTooLong)
|
..settings::Settings::for_rule(Rule::LineTooLong)
|
||||||
},
|
},
|
||||||
)?;
|
)?;
|
||||||
|
|
|
@ -312,13 +312,13 @@ pub struct Options {
|
||||||
"#
|
"#
|
||||||
)]
|
)]
|
||||||
/// The line length to use when enforcing long-lines violations (like
|
/// The line length to use when enforcing long-lines violations (like
|
||||||
/// `E501`).
|
/// `E501`). Must be greater than `0`.
|
||||||
pub line_length: Option<LineLength>,
|
pub line_length: Option<LineLength>,
|
||||||
#[option(
|
#[option(
|
||||||
default = "4",
|
default = "4",
|
||||||
value_type = "int",
|
value_type = "int",
|
||||||
example = r#"
|
example = r#"
|
||||||
tab_size = 8
|
tab-size = 8
|
||||||
"#
|
"#
|
||||||
)]
|
)]
|
||||||
/// The tabulation size to calculate line length.
|
/// The tabulation size to calculate line length.
|
||||||
|
|
|
@ -2,6 +2,7 @@ use std::borrow::Cow;
|
||||||
use std::collections::hash_map::DefaultHasher;
|
use std::collections::hash_map::DefaultHasher;
|
||||||
use std::collections::{BTreeMap, BTreeSet, HashMap, HashSet};
|
use std::collections::{BTreeMap, BTreeSet, HashMap, HashSet};
|
||||||
use std::hash::{Hash, Hasher};
|
use std::hash::{Hash, Hasher};
|
||||||
|
use std::num::NonZeroU8;
|
||||||
use std::ops::{Deref, DerefMut};
|
use std::ops::{Deref, DerefMut};
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
|
|
||||||
|
@ -205,6 +206,13 @@ impl CacheKey for i8 {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl CacheKey for NonZeroU8 {
|
||||||
|
#[inline]
|
||||||
|
fn cache_key(&self, state: &mut CacheKeyHasher) {
|
||||||
|
state.write_u8(self.get());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
macro_rules! impl_cache_key_tuple {
|
macro_rules! impl_cache_key_tuple {
|
||||||
() => (
|
() => (
|
||||||
impl CacheKey for () {
|
impl CacheKey for () {
|
||||||
|
|
4
ruff.schema.json
generated
4
ruff.schema.json
generated
|
@ -376,7 +376,7 @@
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"line-length": {
|
"line-length": {
|
||||||
"description": "The line length to use when enforcing long-lines violations (like `E501`).",
|
"description": "The line length to use when enforcing long-lines violations (like `E501`). Must be greater than `0`.",
|
||||||
"anyOf": [
|
"anyOf": [
|
||||||
{
|
{
|
||||||
"$ref": "#/definitions/LineLength"
|
"$ref": "#/definitions/LineLength"
|
||||||
|
@ -2741,7 +2741,7 @@
|
||||||
"description": "The size of a tab.",
|
"description": "The size of a tab.",
|
||||||
"type": "integer",
|
"type": "integer",
|
||||||
"format": "uint8",
|
"format": "uint8",
|
||||||
"minimum": 0.0
|
"minimum": 1.0
|
||||||
},
|
},
|
||||||
"Version": {
|
"Version": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue