Skip to content

Commit

Permalink
Merge branch 'dcreager/dont-have-a-cow' into dcreager/alist-for-live-bds
Browse files Browse the repository at this point in the history
* dcreager/dont-have-a-cow:
  [red-knot] unify LoopState and saved_break_states (#16406)
  [`pylint`] Also reports `case np.nan`/`case math.nan` (`PLW0177`) (#16378)
  [FURB156] Do not consider docstring(s) (#16391)
  Use `is_none_or` in `stdlib-module-shadowing` (#16402)
  [red-knot] Upgrade salsa to include `AtomicPtr` perf improvement (#16398)
  [red-knot] Fix file watching for new non-project files (#16395)
  document MSRV policy (#16384)
  [red-knot] fix non-callable reporting for unions (#16387)
  bump MSRV to 1.83 (#16294)
  Avoid unnecessary info at non-trace server log level (#16389)
  Expand `ruff.configuration` to allow inline config (#16296)
  Start detecting version-related syntax errors in the parser (#16090)
  • Loading branch information
dcreager committed Feb 27, 2025
2 parents d26b0fd + 35c413b commit 3f38d20
Show file tree
Hide file tree
Showing 84 changed files with 1,035 additions and 247 deletions.
15 changes: 5 additions & 10 deletions Cargo.lock

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

4 changes: 2 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ resolver = "2"

[workspace.package]
edition = "2021"
rust-version = "1.80"
rust-version = "1.83"
homepage = "https://docs.astral.sh/ruff"
documentation = "https://docs.astral.sh/ruff"
repository = "https://github.com/astral-sh/ruff"
Expand Down Expand Up @@ -125,7 +125,7 @@ rayon = { version = "1.10.0" }
regex = { version = "1.10.2" }
rustc-hash = { version = "2.0.0" }
# When updating salsa, make sure to also update the revision in `fuzz/Cargo.toml`
salsa = { git = "https://github.com/salsa-rs/salsa.git", rev = "687251fb50b4893dc373a7e2609ceaefb8accbe7" }
salsa = { git = "https://github.com/salsa-rs/salsa.git", rev = "99be5d9917c3dd88e19735a82ef6bf39ba84bd7e" }
schemars = { version = "0.8.16" }
seahash = { version = "4.1.0" }
serde = { version = "1.0.197", features = ["derive"] }
Expand Down
43 changes: 43 additions & 0 deletions crates/red_knot/tests/file_watching.rs
Original file line number Diff line number Diff line change
Expand Up @@ -462,6 +462,41 @@ fn new_ignored_file() -> anyhow::Result<()> {
Ok(())
}

#[test]
fn new_non_project_file() -> anyhow::Result<()> {
let mut case = setup_with_options([("bar.py", "")], |context| {
Some(Options {
environment: Some(EnvironmentOptions {
extra_paths: Some(vec![RelativePathBuf::cli(
context.join_root_path("site_packages"),
)]),
..EnvironmentOptions::default()
}),
..Options::default()
})
})?;

let bar_path = case.project_path("bar.py");
let bar_file = case.system_file(&bar_path).unwrap();

assert_eq!(&case.collect_project_files(), &[bar_file]);

// Add a file to site packages
let black_path = case.root_path().join("site_packages/black.py");
std::fs::write(black_path.as_std_path(), "print('Hello')")?;

let changes = case.stop_watch(event_for_file("black.py"));

case.apply_changes(changes);

assert!(case.system_file(&black_path).is_ok());

// The file should not have been added to the project files
assert_eq!(&case.collect_project_files(), &[bar_file]);

Ok(())
}

#[test]
fn changed_file() -> anyhow::Result<()> {
let foo_source = "print('Hello, world!')";
Expand Down Expand Up @@ -1075,6 +1110,7 @@ fn hard_links_in_project() -> anyhow::Result<()> {

assert_eq!(source_text(case.db(), foo).as_str(), "print('Version 1')");
assert_eq!(source_text(case.db(), bar).as_str(), "print('Version 1')");
assert_eq!(case.collect_project_files(), &[bar, foo]);

// Write to the hard link target.
update_file(foo_path, "print('Version 2')").context("Failed to update foo.py")?;
Expand Down Expand Up @@ -1354,6 +1390,8 @@ mod unix {
);
assert_eq!(baz.file().path(case.db()).as_system_path(), Some(&*bar_baz));

assert_eq!(case.collect_project_files(), &[patched_bar_baz_file]);

// Write to the symlink target.
update_file(&patched_bar_baz, "def baz(): print('Version 2')")
.context("Failed to update bar/baz.py")?;
Expand Down Expand Up @@ -1389,6 +1427,7 @@ mod unix {
bar_baz_text = bar_baz_text.as_str()
);

assert_eq!(case.collect_project_files(), &[patched_bar_baz_file]);
Ok(())
}

Expand Down Expand Up @@ -1469,6 +1508,8 @@ mod unix {
Some(&*baz_original)
);

assert_eq!(case.collect_project_files(), &[]);

// Write to the symlink target.
update_file(&baz_original, "def baz(): print('Version 2')")
.context("Failed to update bar/baz.py")?;
Expand All @@ -1494,6 +1535,8 @@ mod unix {
"def baz(): print('Version 2')"
);

assert_eq!(case.collect_project_files(), &[]);

Ok(())
}
}
Expand Down
11 changes: 6 additions & 5 deletions crates/red_knot_project/src/db/changes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -208,11 +208,12 @@ impl ProjectDatabase {
return WalkState::Continue;
}

if entry
.path()
.extension()
.and_then(PySourceType::try_from_extension)
.is_some()
if entry.path().starts_with(&project_path)
&& entry
.path()
.extension()
.and_then(PySourceType::try_from_extension)
.is_some()
{
let mut paths = added_paths.lock().unwrap();

Expand Down
4 changes: 2 additions & 2 deletions crates/red_knot_project/src/metadata.rs
Original file line number Diff line number Diff line change
Expand Up @@ -77,10 +77,10 @@ impl ProjectMetadata {
// If the `options` don't specify a python version but the `project.requires-python` field is set,
// use that as a lower bound instead.
if let Some(project) = project {
if !options
if options
.environment
.as_ref()
.is_some_and(|env| env.python_version.is_some())
.is_none_or(|env| env.python_version.is_none())
{
if let Some(requires_python) = project.resolve_requires_python_lower_bound()? {
let mut environment = options.environment.unwrap_or_default();
Expand Down
36 changes: 36 additions & 0 deletions crates/red_knot_python_semantic/resources/mdtest/call/union.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ def _(flag: bool, flag2: bool):
else:
def f() -> int:
return 1
# TODO we should mention all non-callable elements of the union
# error: [call-non-callable] "Object of type `Literal[1]` is not callable"
# revealed: int | Unknown
reveal_type(f())
Expand Down Expand Up @@ -108,3 +109,38 @@ def _(flag: bool):
x = f(3)
reveal_type(x) # revealed: Unknown
```

## Union of binding errors

```py
def f1(): ...
def f2(): ...
def _(flag: bool):
if flag:
f = f1
else:
f = f2

# TODO: we should show all errors from the union, not arbitrarily pick one union element
# error: [too-many-positional-arguments] "Too many positional arguments to function `f1`: expected 0, got 1"
x = f(3)
reveal_type(x) # revealed: Unknown
```

## One not-callable, one wrong argument

```py
class C: ...

def f1(): ...
def _(flag: bool):
if flag:
f = f1
else:
f = C()

# TODO: we should either show all union errors here, or prioritize the not-callable error
# error: [too-many-positional-arguments] "Too many positional arguments to function `f1`: expected 0, got 1"
x = f(3)
reveal_type(x) # revealed: Unknown
```
Loading

0 comments on commit 3f38d20

Please sign in to comment.