Compare commits
1 Commits
0.14.3
...
alex/into_
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1a30934c33 |
55
CHANGELOG.md
55
CHANGELOG.md
@@ -1,60 +1,5 @@
|
||||
# Changelog
|
||||
|
||||
## 0.14.3
|
||||
|
||||
Released on 2025-10-30.
|
||||
|
||||
### Preview features
|
||||
|
||||
- Respect `--output-format` with `--watch` ([#21097](https://github.com/astral-sh/ruff/pull/21097))
|
||||
- \[`pydoclint`\] Fix false positive on explicit exception re-raising (`DOC501`, `DOC502`) ([#21011](https://github.com/astral-sh/ruff/pull/21011))
|
||||
- \[`pyflakes`\] Revert to stable behavior if imports for module lie in alternate branches for `F401` ([#20878](https://github.com/astral-sh/ruff/pull/20878))
|
||||
- \[`pylint`\] Implement `stop-iteration-return` (`PLR1708`) ([#20733](https://github.com/astral-sh/ruff/pull/20733))
|
||||
- \[`ruff`\] Add support for additional eager conversion patterns (`RUF065`) ([#20657](https://github.com/astral-sh/ruff/pull/20657))
|
||||
|
||||
### Bug fixes
|
||||
|
||||
- Fix finding keyword range for clause header after statement ending with semicolon ([#21067](https://github.com/astral-sh/ruff/pull/21067))
|
||||
- Fix syntax error false positive on nested alternative patterns ([#21104](https://github.com/astral-sh/ruff/pull/21104))
|
||||
- \[`ISC001`\] Fix panic when string literals are unclosed ([#21034](https://github.com/astral-sh/ruff/pull/21034))
|
||||
- \[`flake8-django`\] Apply `DJ001` to annotated fields ([#20907](https://github.com/astral-sh/ruff/pull/20907))
|
||||
- \[`flake8-pyi`\] Fix `PYI034` to not trigger on metaclasses (`PYI034`) ([#20881](https://github.com/astral-sh/ruff/pull/20881))
|
||||
- \[`flake8-type-checking`\] Fix `TC003` false positive with `future-annotations` ([#21125](https://github.com/astral-sh/ruff/pull/21125))
|
||||
- \[`pyflakes`\] Fix false positive for `__class__` in lambda expressions within class definitions (`F821`) ([#20564](https://github.com/astral-sh/ruff/pull/20564))
|
||||
- \[`pyupgrade`\] Fix false positive for `TypeVar` with default on Python \<3.13 (`UP046`,`UP047`) ([#21045](https://github.com/astral-sh/ruff/pull/21045))
|
||||
|
||||
### Rule changes
|
||||
|
||||
- Add missing docstring sections to the numpy list ([#20931](https://github.com/astral-sh/ruff/pull/20931))
|
||||
- \[`airflow`\] Extend `airflow.models..Param` check (`AIR311`) ([#21043](https://github.com/astral-sh/ruff/pull/21043))
|
||||
- \[`airflow`\] Warn that `airflow....DAG.create_dagrun` has been removed (`AIR301`) ([#21093](https://github.com/astral-sh/ruff/pull/21093))
|
||||
- \[`refurb`\] Preserve digit separators in `Decimal` constructor (`FURB157`) ([#20588](https://github.com/astral-sh/ruff/pull/20588))
|
||||
|
||||
### Server
|
||||
|
||||
- Avoid sending an unnecessary "clear diagnostics" message for clients supporting pull diagnostics ([#21105](https://github.com/astral-sh/ruff/pull/21105))
|
||||
|
||||
### Documentation
|
||||
|
||||
- \[`flake8-bandit`\] Fix correct example for `S308` ([#21128](https://github.com/astral-sh/ruff/pull/21128))
|
||||
|
||||
### Other changes
|
||||
|
||||
- Clearer error message when `line-length` goes beyond threshold ([#21072](https://github.com/astral-sh/ruff/pull/21072))
|
||||
|
||||
### Contributors
|
||||
|
||||
- [@danparizher](https://github.com/danparizher)
|
||||
- [@jvacek](https://github.com/jvacek)
|
||||
- [@ntBre](https://github.com/ntBre)
|
||||
- [@augustelalande](https://github.com/augustelalande)
|
||||
- [@prakhar1144](https://github.com/prakhar1144)
|
||||
- [@TaKO8Ki](https://github.com/TaKO8Ki)
|
||||
- [@dylwil3](https://github.com/dylwil3)
|
||||
- [@fatelei](https://github.com/fatelei)
|
||||
- [@ShaharNaveh](https://github.com/ShaharNaveh)
|
||||
- [@Lee-W](https://github.com/Lee-W)
|
||||
|
||||
## 0.14.2
|
||||
|
||||
Released on 2025-10-23.
|
||||
|
||||
6
Cargo.lock
generated
6
Cargo.lock
generated
@@ -2835,7 +2835,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "ruff"
|
||||
version = "0.14.3"
|
||||
version = "0.14.2"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"argfile",
|
||||
@@ -3092,7 +3092,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "ruff_linter"
|
||||
version = "0.14.3"
|
||||
version = "0.14.2"
|
||||
dependencies = [
|
||||
"aho-corasick",
|
||||
"anyhow",
|
||||
@@ -3447,7 +3447,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "ruff_wasm"
|
||||
version = "0.14.3"
|
||||
version = "0.14.2"
|
||||
dependencies = [
|
||||
"console_error_panic_hook",
|
||||
"console_log",
|
||||
|
||||
@@ -147,8 +147,8 @@ curl -LsSf https://astral.sh/ruff/install.sh | sh
|
||||
powershell -c "irm https://astral.sh/ruff/install.ps1 | iex"
|
||||
|
||||
# For a specific version.
|
||||
curl -LsSf https://astral.sh/ruff/0.14.3/install.sh | sh
|
||||
powershell -c "irm https://astral.sh/ruff/0.14.3/install.ps1 | iex"
|
||||
curl -LsSf https://astral.sh/ruff/0.14.2/install.sh | sh
|
||||
powershell -c "irm https://astral.sh/ruff/0.14.2/install.ps1 | iex"
|
||||
```
|
||||
|
||||
You can also install Ruff via [Homebrew](https://formulae.brew.sh/formula/ruff), [Conda](https://anaconda.org/conda-forge/ruff),
|
||||
@@ -181,7 +181,7 @@ Ruff can also be used as a [pre-commit](https://pre-commit.com/) hook via [`ruff
|
||||
```yaml
|
||||
- repo: https://github.com/astral-sh/ruff-pre-commit
|
||||
# Ruff version.
|
||||
rev: v0.14.3
|
||||
rev: v0.14.2
|
||||
hooks:
|
||||
# Run the linter.
|
||||
- id: ruff-check
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "ruff"
|
||||
version = "0.14.3"
|
||||
version = "0.14.2"
|
||||
publish = true
|
||||
authors = { workspace = true }
|
||||
edition = { workspace = true }
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "ruff_linter"
|
||||
version = "0.14.3"
|
||||
version = "0.14.2"
|
||||
publish = false
|
||||
authors = { workspace = true }
|
||||
edition = { workspace = true }
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "ruff_wasm"
|
||||
version = "0.14.3"
|
||||
version = "0.14.2"
|
||||
publish = false
|
||||
authors = { workspace = true }
|
||||
edition = { workspace = true }
|
||||
|
||||
@@ -212,10 +212,7 @@ pub fn completion<'db>(
|
||||
offset: TextSize,
|
||||
) -> Vec<Completion<'db>> {
|
||||
let parsed = parsed_module(db, file).load(db);
|
||||
|
||||
let tokens = tokens_start_before(parsed.tokens(), offset);
|
||||
|
||||
if is_in_comment(tokens) || is_in_string(tokens) || is_in_definition_place(db, tokens, file) {
|
||||
if is_in_comment(&parsed, offset) || is_in_string(&parsed, offset) {
|
||||
return vec![];
|
||||
}
|
||||
|
||||
@@ -832,7 +829,8 @@ fn find_typed_text(
|
||||
|
||||
/// Whether the given offset within the parsed module is within
|
||||
/// a comment or not.
|
||||
fn is_in_comment(tokens: &[Token]) -> bool {
|
||||
fn is_in_comment(parsed: &ParsedModuleRef, offset: TextSize) -> bool {
|
||||
let tokens = tokens_start_before(parsed.tokens(), offset);
|
||||
tokens.last().is_some_and(|t| t.kind().is_comment())
|
||||
}
|
||||
|
||||
@@ -841,7 +839,8 @@ fn is_in_comment(tokens: &[Token]) -> bool {
|
||||
///
|
||||
/// Note that this will return `false` when positioned within an
|
||||
/// interpolation block in an f-string or a t-string.
|
||||
fn is_in_string(tokens: &[Token]) -> bool {
|
||||
fn is_in_string(parsed: &ParsedModuleRef, offset: TextSize) -> bool {
|
||||
let tokens = tokens_start_before(parsed.tokens(), offset);
|
||||
tokens.last().is_some_and(|t| {
|
||||
matches!(
|
||||
t.kind(),
|
||||
@@ -850,29 +849,6 @@ fn is_in_string(tokens: &[Token]) -> bool {
|
||||
})
|
||||
}
|
||||
|
||||
/// If the tokens end with `class f` or `def f` we return true.
|
||||
/// If the tokens end with `class` or `def`, we return false.
|
||||
/// This is fine because we don't provide completions anyway.
|
||||
fn is_in_definition_place(db: &dyn Db, tokens: &[Token], file: File) -> bool {
|
||||
tokens
|
||||
.len()
|
||||
.checked_sub(2)
|
||||
.and_then(|i| tokens.get(i))
|
||||
.is_some_and(|t| {
|
||||
if matches!(
|
||||
t.kind(),
|
||||
TokenKind::Def | TokenKind::Class | TokenKind::Type
|
||||
) {
|
||||
true
|
||||
} else if t.kind() == TokenKind::Name {
|
||||
let source = source_text(db, file);
|
||||
&source[t.range()] == "type"
|
||||
} else {
|
||||
false
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/// Order completions according to the following rules:
|
||||
///
|
||||
/// 1) Names with no underscore prefix
|
||||
@@ -4082,83 +4058,6 @@ def f[T](x: T):
|
||||
test.build().contains("__repr__");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn no_completions_in_function_def_name() {
|
||||
let builder = completion_test_builder(
|
||||
"\
|
||||
def f<CURSOR>
|
||||
",
|
||||
);
|
||||
|
||||
builder.auto_import().build().not_contains("fabs");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn no_completions_in_function_def_empty_name() {
|
||||
let builder = completion_test_builder(
|
||||
"\
|
||||
def <CURSOR>
|
||||
",
|
||||
);
|
||||
|
||||
builder.auto_import().build().not_contains("fabs");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn no_completions_in_class_def_name() {
|
||||
let builder = completion_test_builder(
|
||||
"\
|
||||
class f<CURSOR>
|
||||
",
|
||||
);
|
||||
|
||||
builder.auto_import().build().not_contains("fabs");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn no_completions_in_class_def_empty_name() {
|
||||
let builder = completion_test_builder(
|
||||
"\
|
||||
class <CURSOR>
|
||||
",
|
||||
);
|
||||
|
||||
builder.auto_import().build().not_contains("fabs");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn no_completions_in_type_def_name() {
|
||||
let builder = completion_test_builder(
|
||||
"\
|
||||
type f<CURSOR> = int
|
||||
",
|
||||
);
|
||||
|
||||
builder.auto_import().build().not_contains("fabs");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn no_completions_in_maybe_type_def_name() {
|
||||
let builder = completion_test_builder(
|
||||
"\
|
||||
type f<CURSOR>
|
||||
",
|
||||
);
|
||||
|
||||
builder.auto_import().build().not_contains("fabs");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn no_completions_in_type_def_empty_name() {
|
||||
let builder = completion_test_builder(
|
||||
"\
|
||||
type <CURSOR>
|
||||
",
|
||||
);
|
||||
|
||||
builder.auto_import().build().not_contains("fabs");
|
||||
}
|
||||
|
||||
/// A way to create a simple single-file (named `main.py`) completion test
|
||||
/// builder.
|
||||
///
|
||||
|
||||
@@ -819,17 +819,6 @@ impl<'db> Type<'db> {
|
||||
.is_some_and(|instance| instance.has_known_class(db, KnownClass::NoneType))
|
||||
}
|
||||
|
||||
fn is_bool(&self, db: &'db dyn Db) -> bool {
|
||||
self.as_nominal_instance()
|
||||
.is_some_and(|instance| instance.has_known_class(db, KnownClass::Bool))
|
||||
}
|
||||
|
||||
fn is_enum(&self, db: &'db dyn Db) -> bool {
|
||||
self.as_nominal_instance()
|
||||
.and_then(|instance| crate::types::enums::enum_metadata(db, instance.class_literal(db)))
|
||||
.is_some()
|
||||
}
|
||||
|
||||
/// Return true if this type overrides __eq__ or __ne__ methods
|
||||
fn overrides_equality(&self, db: &'db dyn Db) -> bool {
|
||||
let check_dunder = |dunder_name, allowed_return_value| {
|
||||
@@ -1142,7 +1131,7 @@ impl<'db> Type<'db> {
|
||||
|
||||
#[cfg(test)]
|
||||
#[track_caller]
|
||||
pub(crate) fn expect_function_literal(self) -> FunctionType<'db> {
|
||||
pub(crate) const fn expect_function_literal(self) -> FunctionType<'db> {
|
||||
self.as_function_literal()
|
||||
.expect("Expected a Type::FunctionLiteral variant")
|
||||
}
|
||||
@@ -1152,42 +1141,42 @@ impl<'db> Type<'db> {
|
||||
}
|
||||
|
||||
pub(crate) fn is_union_of_single_valued(&self, db: &'db dyn Db) -> bool {
|
||||
self.as_union().is_some_and(|union| {
|
||||
union.elements(db).iter().all(|ty| {
|
||||
ty.is_single_valued(db)
|
||||
|| ty.is_bool(db)
|
||||
|| ty.is_literal_string()
|
||||
|| (ty.is_enum(db) && !ty.overrides_equality(db))
|
||||
})
|
||||
}) || self.is_bool(db)
|
||||
|| self.is_literal_string()
|
||||
|| (self.is_enum(db) && !self.overrides_equality(db))
|
||||
match self {
|
||||
Type::LiteralString => true,
|
||||
Type::NominalInstance(instance) => {
|
||||
instance.has_known_class(db, KnownClass::Bool)
|
||||
|| (enums::enum_metadata(db, instance.class_literal(db)).is_some()
|
||||
&& !self.overrides_equality(db))
|
||||
}
|
||||
Type::Union(union) => union.elements(db).iter().all(|element| {
|
||||
element.is_single_valued(db) || element.is_union_of_single_valued(db)
|
||||
}),
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn is_union_with_single_valued(&self, db: &'db dyn Db) -> bool {
|
||||
self.as_union().is_some_and(|union| {
|
||||
union.elements(db).iter().any(|ty| {
|
||||
ty.is_single_valued(db)
|
||||
|| ty.is_bool(db)
|
||||
|| ty.is_literal_string()
|
||||
|| (ty.is_enum(db) && !ty.overrides_equality(db))
|
||||
})
|
||||
}) || self.is_bool(db)
|
||||
|| self.is_literal_string()
|
||||
|| (self.is_enum(db) && !self.overrides_equality(db))
|
||||
match self {
|
||||
Type::LiteralString => true,
|
||||
Type::NominalInstance(instance) => {
|
||||
instance.has_known_class(db, KnownClass::Bool)
|
||||
|| (enums::enum_metadata(db, instance.class_literal(db)).is_some()
|
||||
&& !self.overrides_equality(db))
|
||||
}
|
||||
Type::Union(union) => union.elements(db).iter().any(|element| {
|
||||
element.is_single_valued(db) || element.is_union_of_single_valued(db)
|
||||
}),
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn as_string_literal(self) -> Option<StringLiteralType<'db>> {
|
||||
pub(crate) const fn as_string_literal(self) -> Option<StringLiteralType<'db>> {
|
||||
match self {
|
||||
Type::StringLiteral(string_literal) => Some(string_literal),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) const fn is_literal_string(&self) -> bool {
|
||||
matches!(self, Type::LiteralString)
|
||||
}
|
||||
|
||||
pub(crate) fn string_literal(db: &'db dyn Db, string: &str) -> Self {
|
||||
Self::StringLiteral(StringLiteralType::new(db, string))
|
||||
}
|
||||
@@ -7291,20 +7280,6 @@ impl<'db> Type<'db> {
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn generic_origin(self, db: &'db dyn Db) -> Option<ClassLiteral<'db>> {
|
||||
match self {
|
||||
Type::GenericAlias(generic) => Some(generic.origin(db)),
|
||||
Type::NominalInstance(instance) => {
|
||||
if let ClassType::Generic(generic) = instance.class(db) {
|
||||
Some(generic.origin(db))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) fn has_divergent_type(self, db: &'db dyn Db, div: Type<'db>) -> bool {
|
||||
any_over_type(db, self, &|ty| ty == div, false)
|
||||
}
|
||||
@@ -11138,7 +11113,7 @@ impl<'db> TypeAliasType<'db> {
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn as_pep_695_type_alias(self) -> Option<PEP695TypeAliasType<'db>> {
|
||||
pub(crate) const fn as_pep_695_type_alias(self) -> Option<PEP695TypeAliasType<'db>> {
|
||||
match self {
|
||||
TypeAliasType::PEP695(type_alias) => Some(type_alias),
|
||||
TypeAliasType::ManualPEP695(_) => None,
|
||||
|
||||
@@ -256,15 +256,14 @@ impl<'a, 'db> FromIterator<(Argument<'a>, Option<Type<'db>>)> for CallArguments<
|
||||
pub(crate) fn is_expandable_type<'db>(db: &'db dyn Db, ty: Type<'db>) -> bool {
|
||||
match ty {
|
||||
Type::NominalInstance(instance) => {
|
||||
let class = instance.class(db);
|
||||
class.is_known(db, KnownClass::Bool)
|
||||
instance.has_known_class(db, KnownClass::Bool)
|
||||
|| instance.tuple_spec(db).is_some_and(|spec| match &*spec {
|
||||
Tuple::Fixed(fixed_length_tuple) => fixed_length_tuple
|
||||
.all_elements()
|
||||
.any(|element| is_expandable_type(db, *element)),
|
||||
Tuple::Variable(_) => false,
|
||||
})
|
||||
|| enum_metadata(db, class.class_literal(db).0).is_some()
|
||||
|| enum_metadata(db, instance.class_literal(db)).is_some()
|
||||
}
|
||||
Type::Union(_) => true,
|
||||
_ => false,
|
||||
@@ -278,9 +277,7 @@ fn expand_type<'db>(db: &'db dyn Db, ty: Type<'db>) -> Option<Vec<Type<'db>>> {
|
||||
// NOTE: Update `is_expandable_type` if this logic changes accordingly.
|
||||
match ty {
|
||||
Type::NominalInstance(instance) => {
|
||||
let class = instance.class(db);
|
||||
|
||||
if class.is_known(db, KnownClass::Bool) {
|
||||
if instance.has_known_class(db, KnownClass::Bool) {
|
||||
return Some(vec![
|
||||
Type::BooleanLiteral(true),
|
||||
Type::BooleanLiteral(false),
|
||||
@@ -315,7 +312,7 @@ fn expand_type<'db>(db: &'db dyn Db, ty: Type<'db>) -> Option<Vec<Type<'db>>> {
|
||||
};
|
||||
}
|
||||
|
||||
if let Some(enum_members) = enum_member_literals(db, class.class_literal(db).0, None) {
|
||||
if let Some(enum_members) = enum_member_literals(db, instance.class_literal(db), None) {
|
||||
return Some(enum_members.collect());
|
||||
}
|
||||
|
||||
|
||||
@@ -377,10 +377,7 @@ impl<'db> ClassType<'db> {
|
||||
}
|
||||
|
||||
pub(super) fn has_pep_695_type_params(self, db: &'db dyn Db) -> bool {
|
||||
match self {
|
||||
Self::NonGeneric(class) => class.has_pep_695_type_params(db),
|
||||
Self::Generic(generic) => generic.origin(db).has_pep_695_type_params(db),
|
||||
}
|
||||
self.class_literal(db).0.has_pep_695_type_params(db)
|
||||
}
|
||||
|
||||
/// Returns the class literal and specialization for this class. For a non-generic class, this
|
||||
@@ -3463,11 +3460,10 @@ impl<'db> ClassLiteral<'db> {
|
||||
) -> bool {
|
||||
let mut result = false;
|
||||
for explicit_base in class.explicit_bases(db) {
|
||||
let explicit_base_class_literal = match explicit_base {
|
||||
Type::ClassLiteral(class_literal) => *class_literal,
|
||||
Type::GenericAlias(generic_alias) => generic_alias.origin(db),
|
||||
_ => continue,
|
||||
let Some(explicit_base) = explicit_base.to_class_type(db) else {
|
||||
continue;
|
||||
};
|
||||
let explicit_base_class_literal = explicit_base.class_literal(db).0;
|
||||
if !classes_on_stack.insert(explicit_base_class_literal) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -1379,16 +1379,11 @@ impl<'db, 'ast> TypeInferenceBuilder<'db, 'ast> {
|
||||
KnownClass::OrderedDict,
|
||||
];
|
||||
|
||||
SAFE_MUTABLE_CLASSES
|
||||
.iter()
|
||||
.map(|class| class.to_instance(db))
|
||||
.any(|safe_mutable_class| {
|
||||
ty.is_equivalent_to(db, safe_mutable_class)
|
||||
|| ty
|
||||
.generic_origin(db)
|
||||
.zip(safe_mutable_class.generic_origin(db))
|
||||
.is_some_and(|(l, r)| l == r)
|
||||
})
|
||||
ty.as_nominal_instance().is_some_and(|instance| {
|
||||
SAFE_MUTABLE_CLASSES
|
||||
.iter()
|
||||
.any(|known_class| instance.has_known_class(db, *known_class))
|
||||
})
|
||||
}
|
||||
|
||||
debug_assert!(
|
||||
|
||||
@@ -614,9 +614,7 @@ impl<'db, 'ast> NarrowingConstraintsBuilder<'db, 'ast> {
|
||||
for element in lhs_union.elements(self.db) {
|
||||
// Keep only the non-single-valued portion of the original type.
|
||||
if !element.is_single_valued(self.db)
|
||||
&& !element.is_literal_string()
|
||||
&& !element.is_bool(self.db)
|
||||
&& (!element.is_enum(self.db) || element.overrides_equality(self.db))
|
||||
&& !element.is_union_of_single_valued(self.db)
|
||||
{
|
||||
builder = builder.add(*element);
|
||||
}
|
||||
@@ -650,9 +648,7 @@ impl<'db, 'ast> NarrowingConstraintsBuilder<'db, 'ast> {
|
||||
if let Some(lhs_union) = lhs_ty.as_union() {
|
||||
for element in lhs_union.elements(self.db) {
|
||||
if element.is_single_valued(self.db)
|
||||
|| element.is_literal_string()
|
||||
|| element.is_bool(self.db)
|
||||
|| (element.is_enum(self.db) && !element.overrides_equality(self.db))
|
||||
|| element.is_union_of_single_valued(self.db)
|
||||
{
|
||||
single_builder = single_builder.add(*element);
|
||||
} else {
|
||||
|
||||
@@ -80,7 +80,7 @@ You can add the following configuration to `.gitlab-ci.yml` to run a `ruff forma
|
||||
stage: build
|
||||
interruptible: true
|
||||
image:
|
||||
name: ghcr.io/astral-sh/ruff:0.14.3-alpine
|
||||
name: ghcr.io/astral-sh/ruff:0.14.2-alpine
|
||||
before_script:
|
||||
- cd $CI_PROJECT_DIR
|
||||
- ruff --version
|
||||
@@ -106,7 +106,7 @@ Ruff can be used as a [pre-commit](https://pre-commit.com) hook via [`ruff-pre-c
|
||||
```yaml
|
||||
- repo: https://github.com/astral-sh/ruff-pre-commit
|
||||
# Ruff version.
|
||||
rev: v0.14.3
|
||||
rev: v0.14.2
|
||||
hooks:
|
||||
# Run the linter.
|
||||
- id: ruff-check
|
||||
@@ -119,7 +119,7 @@ To enable lint fixes, add the `--fix` argument to the lint hook:
|
||||
```yaml
|
||||
- repo: https://github.com/astral-sh/ruff-pre-commit
|
||||
# Ruff version.
|
||||
rev: v0.14.3
|
||||
rev: v0.14.2
|
||||
hooks:
|
||||
# Run the linter.
|
||||
- id: ruff-check
|
||||
@@ -133,7 +133,7 @@ To avoid running on Jupyter Notebooks, remove `jupyter` from the list of allowed
|
||||
```yaml
|
||||
- repo: https://github.com/astral-sh/ruff-pre-commit
|
||||
# Ruff version.
|
||||
rev: v0.14.3
|
||||
rev: v0.14.2
|
||||
hooks:
|
||||
# Run the linter.
|
||||
- id: ruff-check
|
||||
|
||||
@@ -369,7 +369,7 @@ This tutorial has focused on Ruff's command-line interface, but Ruff can also be
|
||||
```yaml
|
||||
- repo: https://github.com/astral-sh/ruff-pre-commit
|
||||
# Ruff version.
|
||||
rev: v0.14.3
|
||||
rev: v0.14.2
|
||||
hooks:
|
||||
# Run the linter.
|
||||
- id: ruff
|
||||
|
||||
@@ -4,7 +4,7 @@ build-backend = "maturin"
|
||||
|
||||
[project]
|
||||
name = "ruff"
|
||||
version = "0.14.3"
|
||||
version = "0.14.2"
|
||||
description = "An extremely fast Python linter and code formatter, written in Rust."
|
||||
authors = [{ name = "Astral Software Inc.", email = "hey@astral.sh" }]
|
||||
readme = "README.md"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[project]
|
||||
name = "scripts"
|
||||
version = "0.14.3"
|
||||
version = "0.14.2"
|
||||
description = ""
|
||||
authors = ["Charles Marsh <charlie.r.marsh@gmail.com>"]
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@ project_root="$(dirname "$script_root")"
|
||||
echo "Updating metadata with rooster..."
|
||||
cd "$project_root"
|
||||
uvx --python 3.12 --isolated -- \
|
||||
rooster@0.1.1 release "$@"
|
||||
rooster@0.1.0 release "$@"
|
||||
|
||||
echo "Updating lockfile..."
|
||||
cargo update -p ruff
|
||||
|
||||
Reference in New Issue
Block a user