Skip to content

Commit 5ac0467

Browse files
committed
Merge branch 'main' into dcreager/relation-with-constraints
* main: (29 commits) [ty] add docstrings to completions based on type (#20008) [`pyupgrade`] Avoid reporting `__future__` features as unnecessary when they are used (`UP010`) (#19769) [`flake8-use-pathlib`] Add fixes for `PTH102` and `PTH103` (#19514) [ty] correctly ignore field specifiers when not specified (#20002) `Option::unwrap` is now const (#20007) [ty] Re-arrange "list modules" implementation for Salsa caching [ty] Test "list modules" versus "resolve module" in every mdtest [ty] Wire up "list modules" API to make module completions work [ty] Tweak some completion tests [ty] Add "list modules" implementation [ty] Lightly expose `FileModule` and `NamespacePackage` fields [ty] Add some more helper routines to `ModulePath` [ty] Fix a bug when converting `ModulePath` to `ModuleName` [ty] Split out another constructor for `ModuleName` [ty] Add stub-file tests to existing module resolver [ty] Expose some routines in the module resolver [ty] Add more path helper functions [`flake8-annotations`] Remove unused import in example (`ANN401`) (#20000) [ty] distinguish base conda from child conda (#19990) [ty] Fix server hang (#19991) ...
2 parents 38b8d13 + 859475f commit 5ac0467

File tree

86 files changed

+7199
-706
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

86 files changed

+7199
-706
lines changed

Cargo.lock

Lines changed: 3 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,7 @@ regex-automata = { version = "0.4.9" }
143143
rustc-hash = { version = "2.0.0" }
144144
rustc-stable-hash = { version = "0.1.2" }
145145
# When updating salsa, make sure to also update the revision in `fuzz/Cargo.toml`
146-
salsa = { git = "https://github.com/salsa-rs/salsa.git", rev = "918d35d873b2b73a0237536144ef4d22e8d57f27", default-features = false, features = [
146+
salsa = { git = "https://github.com/salsa-rs/salsa.git", rev = "a3ffa22cb26756473d56f867aedec3fd907c4dd9", default-features = false, features = [
147147
"compact_str",
148148
"macros",
149149
"salsa_unstable",

crates/ruff/tests/lint.rs

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5801,3 +5801,32 @@ fn future_annotations_preview_warning() {
58015801
",
58025802
);
58035803
}
5804+
5805+
#[test]
5806+
fn up045_nested_optional_flatten_all() {
5807+
let contents = "\
5808+
from typing import Optional
5809+
nested_optional: Optional[Optional[Optional[str]]] = None
5810+
";
5811+
5812+
assert_cmd_snapshot!(
5813+
Command::new(get_cargo_bin(BIN_NAME))
5814+
.args(STDIN_BASE_OPTIONS)
5815+
.args(["--select", "UP045", "--diff", "--target-version", "py312"])
5816+
.arg("-")
5817+
.pass_stdin(contents),
5818+
@r"
5819+
success: false
5820+
exit_code: 1
5821+
----- stdout -----
5822+
@@ -1,2 +1,2 @@
5823+
from typing import Optional
5824+
-nested_optional: Optional[Optional[Optional[str]]] = None
5825+
+nested_optional: str | None = None
5826+
5827+
5828+
----- stderr -----
5829+
Would fix 1 error.
5830+
",
5831+
);
5832+
}

crates/ruff_linter/resources/test/fixtures/flake8_use_pathlib/full_name.py

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,4 +106,22 @@ def bar(x: int):
106106
os.replace("src", "dst", dst_dir_fd=2)
107107

108108
os.getcwd()
109-
os.getcwdb()
109+
os.getcwdb()
110+
111+
os.mkdir(path="directory")
112+
113+
os.mkdir(
114+
# comment 1
115+
"directory",
116+
mode=0o777
117+
)
118+
119+
os.mkdir("directory", mode=0o777, dir_fd=1)
120+
121+
os.makedirs("name", 0o777, exist_ok=False)
122+
123+
os.makedirs("name", 0o777, False)
124+
125+
os.makedirs(name="name", mode=0o777, exist_ok=False)
126+
127+
os.makedirs("name", unknown_kwarg=True)
File renamed without changes.
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
from __future__ import nested_scopes, generators
2+
from __future__ import with_statement, unicode_literals
3+
4+
from __future__ import absolute_import, division
5+
from __future__ import generator_stop
6+
from __future__ import print_function, nested_scopes, generator_stop
7+
8+
print(with_statement)
9+
generators = 1
10+
11+
12+
class Foo():
13+
14+
def boo(self):
15+
print(division)
16+
17+
18+
__all__ = ["print_function", "generator_stop"]

crates/ruff_linter/resources/test/fixtures/pyupgrade/UP045.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,3 +69,10 @@ class ServiceRefOrValue:
6969
a8: typing_extensions.Optional[typing.NamedTuple] = None
7070
a9: "Optional[NamedTuple]" = None
7171
a10: Optional[NamedTupleTE] = None
72+
73+
74+
# Test for: https://github.com/astral-sh/ruff/issues/19746
75+
# Nested Optional types should be flattened
76+
nested_optional: Optional[Optional[str]] = None
77+
nested_optional_typing: typing.Optional[Optional[int]] = None
78+
triple_nested_optional: Optional[Optional[Optional[str]]] = None

crates/ruff_linter/src/checkers/ast/analyze/deferred_scopes.rs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
1+
use ruff_python_ast::PythonVersion;
12
use ruff_python_semantic::{Binding, ScopeKind};
23

34
use crate::checkers::ast::Checker;
45
use crate::codes::Rule;
56
use crate::rules::{
67
flake8_builtins, flake8_pyi, flake8_type_checking, flake8_unused_arguments, pep8_naming,
7-
pyflakes, pylint, ruff,
8+
pyflakes, pylint, pyupgrade, ruff,
89
};
910

1011
/// Run lint rules over all deferred scopes in the [`SemanticModel`].
@@ -45,6 +46,7 @@ pub(crate) fn deferred_scopes(checker: &Checker) {
4546
Rule::UnusedStaticMethodArgument,
4647
Rule::UnusedUnpackedVariable,
4748
Rule::UnusedVariable,
49+
Rule::UnnecessaryFutureImport,
4850
]) {
4951
return;
5052
}
@@ -224,6 +226,11 @@ pub(crate) fn deferred_scopes(checker: &Checker) {
224226
if checker.is_rule_enabled(Rule::UnusedImport) {
225227
pyflakes::rules::unused_import(checker, scope);
226228
}
229+
if checker.is_rule_enabled(Rule::UnnecessaryFutureImport) {
230+
if checker.target_version() >= PythonVersion::PY37 {
231+
pyupgrade::rules::unnecessary_future_import(checker, scope);
232+
}
233+
}
227234

228235
if checker.is_rule_enabled(Rule::ImportPrivateName) {
229236
pylint::rules::import_private_name(checker, scope);

crates/ruff_linter/src/checkers/ast/analyze/expression.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1039,8 +1039,6 @@ pub(crate) fn expression(expr: &Expr, checker: &Checker) {
10391039
flake8_simplify::rules::zip_dict_keys_and_values(checker, call);
10401040
}
10411041
if checker.any_rule_enabled(&[
1042-
Rule::OsMkdir,
1043-
Rule::OsMakedirs,
10441042
Rule::OsStat,
10451043
Rule::OsPathJoin,
10461044
Rule::OsPathSplitext,
@@ -1120,6 +1118,12 @@ pub(crate) fn expression(expr: &Expr, checker: &Checker) {
11201118
if checker.is_rule_enabled(Rule::OsPathSamefile) {
11211119
flake8_use_pathlib::rules::os_path_samefile(checker, call, segments);
11221120
}
1121+
if checker.is_rule_enabled(Rule::OsMkdir) {
1122+
flake8_use_pathlib::rules::os_mkdir(checker, call, segments);
1123+
}
1124+
if checker.is_rule_enabled(Rule::OsMakedirs) {
1125+
flake8_use_pathlib::rules::os_makedirs(checker, call, segments);
1126+
}
11231127
if checker.is_rule_enabled(Rule::PathConstructorCurrentDirectory) {
11241128
flake8_use_pathlib::rules::path_constructor_current_directory(
11251129
checker, call, segments,

crates/ruff_linter/src/checkers/ast/analyze/statement.rs

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -728,13 +728,6 @@ pub(crate) fn statement(stmt: &Stmt, checker: &mut Checker) {
728728
pylint::rules::non_ascii_module_import(checker, alias);
729729
}
730730
}
731-
if checker.is_rule_enabled(Rule::UnnecessaryFutureImport) {
732-
if checker.target_version() >= PythonVersion::PY37 {
733-
if let Some("__future__") = module {
734-
pyupgrade::rules::unnecessary_future_import(checker, stmt, names);
735-
}
736-
}
737-
}
738731
if checker.is_rule_enabled(Rule::DeprecatedMockImport) {
739732
pyupgrade::rules::deprecated_mock_import(checker, stmt);
740733
}

0 commit comments

Comments
 (0)