Skip to content

Commit

Permalink
Merge branch 'main' into thartman/sim103-detect-implicit-else
Browse files Browse the repository at this point in the history
  • Loading branch information
charliermarsh committed Mar 17, 2024
2 parents 03170c1 + 8619986 commit 1b7d160
Show file tree
Hide file tree
Showing 34 changed files with 514 additions and 110 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ coverage.xml
.hypothesis/
.pytest_cache/
cover/
repos/

# Translations
*.mo
Expand Down
46 changes: 45 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,49 @@
# Changelog

## 0.3.3

### Preview features

- \[`flake8-bandit`\]: Implement `S610` rule ([#10316](https://github.com/astral-sh/ruff/pull/10316))
- \[`pycodestyle`\] Implement `blank-line-at-end-of-file` (`W391`) ([#10243](https://github.com/astral-sh/ruff/pull/10243))
- \[`pycodestyle`\] Implement `redundant-backslash` (`E502`) ([#10292](https://github.com/astral-sh/ruff/pull/10292))
- \[`pylint`\] - implement `redeclared-assigned-name` (`W0128`) ([#9268](https://github.com/astral-sh/ruff/pull/9268))

### Rule changes

- \[`flake8_comprehensions`\] Handled special case for `C400` which also matches `C416` ([#10419](https://github.com/astral-sh/ruff/pull/10419))
- \[`flake8-bandit`\] Implement upstream updates for `S311`, `S324` and `S605` ([#10313](https://github.com/astral-sh/ruff/pull/10313))
- \[`pyflakes`\] Remove `F401` fix for `__init__` imports by default and allow opt-in to unsafe fix ([#10365](https://github.com/astral-sh/ruff/pull/10365))
- \[`pylint`\] Implement `invalid-bool-return-type` (`E304`) ([#10377](https://github.com/astral-sh/ruff/pull/10377))
- \[`pylint`\] Include builtin warnings in useless-exception-statement (`PLW0133`) ([#10394](https://github.com/astral-sh/ruff/pull/10394))

### CLI

- Add message on success to `ruff check` ([#8631](https://github.com/astral-sh/ruff/pull/8631))

### Bug fixes

- \[`PIE970`\] Allow trailing ellipsis in `typing.TYPE_CHECKING` ([#10413](https://github.com/astral-sh/ruff/pull/10413))
- Avoid `TRIO115` if the argument is a variable ([#10376](https://github.com/astral-sh/ruff/pull/10376))
- \[`F811`\] Avoid removing shadowed imports that point to different symbols ([#10387](https://github.com/astral-sh/ruff/pull/10387))
- Fix `F821` and `F822` false positives in `.pyi` files ([#10341](https://github.com/astral-sh/ruff/pull/10341))
- Fix `F821` false negatives in `.py` files when `from __future__ import annotations` is active ([#10362](https://github.com/astral-sh/ruff/pull/10362))
- Fix case where `Indexer` fails to identify continuation preceded by newline #10351 ([#10354](https://github.com/astral-sh/ruff/pull/10354))
- Sort hash maps in `Settings` display ([#10370](https://github.com/astral-sh/ruff/pull/10370))
- Track conditional deletions in the semantic model ([#10415](https://github.com/astral-sh/ruff/pull/10415))
- \[`C413`\] Wrap expressions in parentheses when negating ([#10346](https://github.com/astral-sh/ruff/pull/10346))
- \[`pycodestyle`\] Do not ignore lines before the first logical line in blank lines rules. ([#10382](https://github.com/astral-sh/ruff/pull/10382))
- \[`pycodestyle`\] Do not trigger `E225` and `E275` when the next token is a ')' ([#10315](https://github.com/astral-sh/ruff/pull/10315))
- \[`pylint`\] Avoid false-positive slot non-assignment for `__dict__` (`PLE0237`) ([#10348](https://github.com/astral-sh/ruff/pull/10348))
- Gate f-string struct size test for Rustc \< 1.76 ([#10371](https://github.com/astral-sh/ruff/pull/10371))

### Documentation

- Use `ruff.toml` format in README ([#10393](https://github.com/astral-sh/ruff/pull/10393))
- \[`RUF008`\] Make it clearer that a mutable default in a dataclass is only valid if it is typed as a ClassVar ([#10395](https://github.com/astral-sh/ruff/pull/10395))
- \[`pylint`\] Extend docs and test in `invalid-str-return-type` (`E307`) ([#10400](https://github.com/astral-sh/ruff/pull/10400))
- Remove `.` from `check` and `format` commands ([#10217](https://github.com/astral-sh/ruff/pull/10217))

## 0.3.2

### Preview features
Expand Down Expand Up @@ -1199,7 +1243,7 @@ Read Ruff's new [versioning policy](https://docs.astral.sh/ruff/versioning/).
- \[`refurb`\] Add `single-item-membership-test` (`FURB171`) ([#7815](https://github.com/astral-sh/ruff/pull/7815))
- \[`pylint`\] Add `and-or-ternary` (`R1706`) ([#7811](https://github.com/astral-sh/ruff/pull/7811))

_New rules are added in [preview](https://docs.astral.sh/ruff/preview/)._
*New rules are added in [preview](https://docs.astral.sh/ruff/preview/).*

### Configuration

Expand Down
6 changes: 3 additions & 3 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,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.3.2
rev: v0.3.3
hooks:
# Run the linter.
- id: ruff
Expand Down
2 changes: 1 addition & 1 deletion crates/ruff/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "ruff"
version = "0.3.2"
version = "0.3.3"
publish = false
authors = { workspace = true }
edition = { workspace = true }
Expand Down
2 changes: 1 addition & 1 deletion crates/ruff_linter/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "ruff_linter"
version = "0.3.2"
version = "0.3.3"
publish = false
authors = { workspace = true }
edition = { workspace = true }
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,20 @@
# Cannot combine with C416. Should use list comprehension here.
even_nums = list(2 * x for x in range(3))
odd_nums = list(
2 * x + 1 for x in range(3)
)


# Short-circuit case, combine with C416 and should produce x = list(range(3))
x = list(x for x in range(3))
x = list(
x for x in range(3)
)


# Not built-in list.
def list(*args, **kwargs):
return None


list(2 * x for x in range(3))
list(x for x in range(3))
Original file line number Diff line number Diff line change
Expand Up @@ -227,3 +227,11 @@ def func(self) -> str:
def impl(self) -> str:
"""Docstring"""
return self.func()


import typing

if typing.TYPE_CHECKING:
def contains_meaningful_ellipsis() -> list[int]:
"""Allow this in a TYPE_CHECKING block."""
...
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,13 @@ def f():
print(X)


def f():
global X

if X > 0:
del X


###
# Non-errors.
###
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
FIRST, FIRST = (1, 2) # PLW0128
FIRST, (FIRST, SECOND) = (1, (1, 2)) # PLW0128
FIRST, (FIRST, SECOND, (THIRD, FIRST)) = (1, (1, 2)) # PLW0128
FIRST, SECOND, THIRD, FIRST, SECOND = (1, 2, 3, 4) # PLW0128

FIRST, SECOND, _, _, _ignored = (1, 2, 3, 4, 5) # OK
30 changes: 23 additions & 7 deletions crates/ruff_linter/src/checkers/ast/analyze/deferred_scopes.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use ruff_diagnostics::{Diagnostic, Fix};
use ruff_python_semantic::analyze::visibility;
use ruff_python_semantic::{Binding, BindingKind, Imported, ScopeKind};
use ruff_python_semantic::{Binding, BindingKind, Imported, ResolvedReference, ScopeKind};
use ruff_text_size::Ranged;

use crate::checkers::ast::Checker;
Expand Down Expand Up @@ -91,13 +91,29 @@ pub(crate) fn deferred_scopes(checker: &mut Checker) {
if checker.enabled(Rule::GlobalVariableNotAssigned) {
for (name, binding_id) in scope.bindings() {
let binding = checker.semantic.binding(binding_id);
// If the binding is a `global`, then it's a top-level `global` that was never
// assigned in the current scope. If it were assigned, the `global` would be
// shadowed by the assignment.
if binding.kind.is_global() {
diagnostics.push(Diagnostic::new(
pylint::rules::GlobalVariableNotAssigned {
name: (*name).to_string(),
},
binding.range(),
));
// If the binding was conditionally deleted, it will include a reference within
// a `Del` context, but won't be shadowed by a `BindingKind::Deletion`, as in:
// ```python
// if condition:
// del var
// ```
if binding
.references
.iter()
.map(|id| checker.semantic.reference(*id))
.all(ResolvedReference::is_load)
{
diagnostics.push(Diagnostic::new(
pylint::rules::GlobalVariableNotAssigned {
name: (*name).to_string(),
},
binding.range(),
));
}
}
}
}
Expand Down
3 changes: 3 additions & 0 deletions crates/ruff_linter/src/checkers/ast/analyze/statement.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1389,6 +1389,9 @@ pub(crate) fn statement(stmt: &Stmt, checker: &mut Checker) {
}
}
Stmt::Assign(assign @ ast::StmtAssign { targets, value, .. }) => {
if checker.enabled(Rule::RedeclaredAssignedName) {
pylint::rules::redeclared_assigned_name(checker, targets);
}
if checker.enabled(Rule::LambdaAssignment) {
if let [target] = &targets[..] {
pycodestyle::rules::lambda_assignment(checker, target, value, None, stmt);
Expand Down
9 changes: 7 additions & 2 deletions crates/ruff_linter/src/checkers/ast/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -540,7 +540,11 @@ impl<'a> Visitor<'a> for Checker<'a> {
for name in names {
if let Some((scope_id, binding_id)) = self.semantic.nonlocal(name) {
// Mark the binding as "used".
self.semantic.add_local_reference(binding_id, name.range());
self.semantic.add_local_reference(
binding_id,
ExprContext::Load,
name.range(),
);

// Mark the binding in the enclosing scope as "rebound" in the current
// scope.
Expand Down Expand Up @@ -2113,7 +2117,8 @@ impl<'a> Checker<'a> {
// Mark anything referenced in `__all__` as used.
// TODO(charlie): `range` here should be the range of the name in `__all__`, not
// the range of `__all__` itself.
self.semantic.add_global_reference(binding_id, range);
self.semantic
.add_global_reference(binding_id, ExprContext::Load, range);
} else {
if self.semantic.global_scope().uses_star_imports() {
if self.enabled(Rule::UndefinedLocalWithImportStarUsage) {
Expand Down
1 change: 1 addition & 0 deletions crates/ruff_linter/src/codes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -294,6 +294,7 @@ pub fn code_to_rule(linter: Linter, code: &str) -> Option<(RuleGroup, Rule)> {
(Pylint, "W0108") => (RuleGroup::Preview, rules::pylint::rules::UnnecessaryLambda),
(Pylint, "W0120") => (RuleGroup::Stable, rules::pylint::rules::UselessElseOnLoop),
(Pylint, "W0127") => (RuleGroup::Stable, rules::pylint::rules::SelfAssigningVariable),
(Pylint, "W0128") => (RuleGroup::Preview, rules::pylint::rules::RedeclaredAssignedName),
(Pylint, "W0129") => (RuleGroup::Stable, rules::pylint::rules::AssertOnStringLiteral),
(Pylint, "W0131") => (RuleGroup::Stable, rules::pylint::rules::NamedExprWithoutContext),
(Pylint, "W0133") => (RuleGroup::Preview, rules::pylint::rules::UselessExceptionStatement),
Expand Down
1 change: 1 addition & 0 deletions crates/ruff_linter/src/renamer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,7 @@ impl Renamer {
| BindingKind::ClassDefinition(_)
| BindingKind::FunctionDefinition(_)
| BindingKind::Deletion
| BindingKind::ConditionalDeletion(_)
| BindingKind::UnboundException(_) => {
Some(Edit::range_replacement(target.to_string(), binding.range()))
}
Expand Down
Loading

0 comments on commit 1b7d160

Please sign in to comment.