Compare commits

...

15 Commits

Author SHA1 Message Date
Charlie Marsh
bf0f3075cd Move docs 2024-07-05 15:37:56 -05:00
Maximilian Kolb
86b34c7c53 Respect SELinux with podman for docker mount
Tested on Fedora 40 with Podman 5.1.1 and ruff "0.5.0" and "latest".
source: https://unix.stackexchange.com/q/651198
2024-06-29 14:47:57 +02:00
Dhruv Manilawala
47b227394e Avoid E275 if keyword is followed by a semicolon (#12095)
fixes: #12094
2024-06-28 20:51:35 +05:30
Charlie Marsh
c326778652 Make requires-python inference robust to == (#12091)
## Summary

Instead of using a high patch version, attempt to detect the
minimum-supported minor.

Closes #12088.
2024-06-28 09:38:17 -04:00
Dhruv Manilawala
434ce307a7 Revert "Use correct range to highlight line continuation error" (#12089)
This PR reverts https://github.com/astral-sh/ruff/pull/12016 with a
small change where the error location points to the continuation
character only. Earlier, it would also highlight the whitespace that
came before it.

The motivation for this change is to avoid panic in
https://github.com/astral-sh/ruff/pull/11950. For example:

```py
\)
```

Playground: https://play.ruff.rs/87711071-1b54-45a3-b45a-81a336a1ea61

The range of `Unknown` token and `Rpar` is the same. Once #11950 is
enabled, the indexer would panic. It won't panic in the stable version
because we stop at the first `Unknown` token.
2024-06-28 18:10:00 +05:30
Charlie Marsh
6a37d7a1e6 Add bandit rule changes to breaking section (#12090)
Closes https://github.com/astral-sh/ruff/issues/12086.
2024-06-28 11:41:45 +00:00
Dhruv Manilawala
0179ff97da Add standalone installer instruction to docs (#12081)
Adopted from `uv` README
(https://github.com/astral-sh/uv#getting-started), this PR adds a
section of using standalone installers in the installation section of
Ruff docs.
2024-06-28 11:34:46 +00:00
Charlie Marsh
2b54fab02c Publish docs and playground on cargo-dist release (#12079)
## Summary

These are now `post-announce-jobs`. So if they fail, the release itself
will still succeed, which seems ok. (If we make them `publish-jobs`,
then we might end up publishing to PyPI but failing the release itself
if one of these fails.)

The intent is that these are still runnable via `workflow_dispatch` too.

Closes https://github.com/astral-sh/ruff/issues/12074.
2024-06-28 07:29:04 -04:00
Micha Reiser
117ab789c9 Add more NPY201 tests (#12087) 2024-06-28 09:58:39 +02:00
Étienne BERSAC
2336c078e2 Improve Emacs configuration (#12070)
Replace black and combine `ruff check --select=I --fix` and `ruff
format`.
2024-06-28 13:09:29 +05:30
Dhruv Manilawala
9fec384d11 Show syntax errors on the playground (#12083)
## Summary

This PR updates the playground to show syntax errors.

(I forgot to update this and noticed it this morning.)

## Test Plan

Build the playground locally and preview it:

<img width="764" alt="Screenshot 2024-06-28 at 11 03 35"
src="https://github.com/astral-sh/ruff/assets/67177269/1fd48d6c-ae41-4672-bf3c-32a61d9946ef">
2024-06-28 13:06:15 +05:30
Dhruv Manilawala
526efd398a Remove E999 to find diagnostic severity (#12080)
## Summary

This PR removes the need to check for `E999` code to find the diagnostic
severity in the server.

**Note:** This is just removing a redundant check because all
`ParseErrors` are converted to `Diagnostic` with default `Error`
severity by
63c92586a1/crates/ruff_server/src/lint.rs (L309-L346)

## Test Plan

Verify that syntax errors are still shown with error severity as it did
before:

<img width="1313" alt="Screenshot 2024-06-28 at 09 30 20"
src="https://github.com/astral-sh/ruff/assets/67177269/75e389a7-01ea-461c-86a2-0dfc244e515d">
2024-06-28 09:31:35 +05:30
Jane Lewis
b28dc9ac14 Remove --preview as a required argument for ruff server (#12053)
## Summary

`ruff server` has reached a point of stabilization, and `--preview` is
no longer required as a flag.

`--preview` is still supported as a flag, since future features may be
need to gated behind it initially.

## Test Plan

A simple way to test this is to run `ruff server` from the command line.
No error about a missing `--preview` argument should be reported.
2024-06-27 19:27:15 +00:00
Mateusz Sokół
59ea94ce88 [numpy] Update NPY201 to include exception deprecations (#12065)
Hi!

This PR updates `NPY201` rule to address
https://github.com/astral-sh/ruff/issues/12034 and partially
https://github.com/numpy/numpy/issues/26800.
2024-06-27 18:56:56 +00:00
Alex Waygood
5bef2b0361 fix link to the release workflow in CONTRIBUTING.md (#12073) 2024-06-27 16:15:31 +00:00
29 changed files with 1155 additions and 462 deletions

View File

@@ -1,3 +1,7 @@
# Publish the Ruff documentation.
#
# Assumed to run as a subworkflow of .github/workflows/release.yml; specifically, as a post-announce
# job within `cargo-dist`.
name: mkdocs
on:
@@ -7,8 +11,11 @@ on:
description: "The commit SHA, tag, or branch to publish. Uses the default branch if not specified."
default: ""
type: string
release:
types: [published]
workflow_call:
inputs:
plan:
required: true
type: string
jobs:
mkdocs:

View File

@@ -1,9 +1,16 @@
# Publish the Ruff playground.
#
# Assumed to run as a subworkflow of .github/workflows/release.yml; specifically, as a post-announce
# job within `cargo-dist`.
name: "[Playground] Release"
on:
workflow_dispatch:
release:
types: [published]
workflow_call:
inputs:
plan:
required: true
type: string
env:
CARGO_INCREMENTAL: 0

View File

@@ -247,3 +247,21 @@ jobs:
with:
plan: ${{ needs.plan.outputs.val }}
secrets: inherit
custom-publish-docs:
needs:
- plan
- announce
uses: ./.github/workflows/publish-docs.yml
with:
plan: ${{ needs.plan.outputs.val }}
secrets: inherit
custom-publish-playground:
needs:
- plan
- announce
uses: ./.github/workflows/publish-playground.yml
with:
plan: ${{ needs.plan.outputs.val }}
secrets: inherit

View File

@@ -12,6 +12,7 @@ See also, the "Remapped rules" section which may result in disabled rules.
- Selecting `ALL` now excludes deprecated rules
- The released archives now include an extra level of nesting, which can be removed with `--strip-components=1` when untarring.
- The release artifact's file name no longer includes the version tag. This enables users to install via `/latest` URLs on GitHub.
- The diagnostic ranges for some `flake8-bandit` rules were modified ([#10667](https://github.com/astral-sh/ruff/pull/10667)).
### Deprecations
@@ -107,7 +108,7 @@ The following deprecated CLI commands have been removed:
### Rule changes
- \[`ruff`\] Fix false positives if `gettext` is imported using an alias (`RUF027`) ([#12025](https://github.com/astral-sh/ruff/pull/12025))
- \[`npy`\] Update `trapz` and `in1d` deprecation (`NPY201`) ([#11948](https://github.com/astral-sh/ruff/pull/11948))
- \[`numpy`\] Update `trapz` and `in1d` deprecation (`NPY201`) ([#11948](https://github.com/astral-sh/ruff/pull/11948))
- \[`flake8-bandit`\] Modify diagnostic ranges for shell-related rules ([#10667](https://github.com/astral-sh/ruff/pull/10667))
### Server

View File

@@ -346,7 +346,7 @@ even patch releases may contain [non-backwards-compatible changes](https://semve
1. Run `cargo check`. This should update the lock file with new versions.
1. Create a pull request with the changelog and version updates
1. Merge the PR
1. Run the [release workflow](https://github.com/astral-sh/ruff/actions/workflows/release.yaml) with:
1. Run the [release workflow](https://github.com/astral-sh/ruff/actions/workflows/release.yml) with:
- The new version number (without starting `v`)
1. The release workflow will do the following:
1. Build all the assets. If this fails (even though we tested in step 4), we haven't tagged or

View File

@@ -271,7 +271,7 @@ local-artifacts-jobs = ["./build-binaries", "./build-docker"]
# Publish jobs to run in CI
publish-jobs = ["./publish-pypi"]
# Announcement jobs to run in CI
post-announce-jobs = ["./notify-dependents"]
post-announce-jobs = ["./notify-dependents", "./publish-docs", "./publish-playground"]
# Skip checking whether the specified configuration files are up to date
allow-dirty = ["ci"]
# Whether to install an updater program

View File

@@ -4,12 +4,7 @@ use crate::ExitStatus;
use anyhow::Result;
use ruff_server::Server;
pub(crate) fn run_server(preview: bool, worker_threads: NonZeroUsize) -> Result<ExitStatus> {
if !preview {
tracing::error!("--preview needs to be provided as a command line argument while the server is still unstable.\nFor example: `ruff server --preview`");
return Ok(ExitStatus::Error);
}
pub(crate) fn run_server(_preview: bool, worker_threads: NonZeroUsize) -> Result<ExitStatus> {
let server = Server::new(worker_threads)?;
server.run().map(|()| ExitStatus::Success)

View File

@@ -1618,3 +1618,189 @@ print(
Ok(())
}
/// Infer `3.11` from `requires-python` in `pyproject.toml`.
#[test]
fn requires_python() -> Result<()> {
let tempdir = TempDir::new()?;
let ruff_toml = tempdir.path().join("pyproject.toml");
fs::write(
&ruff_toml,
r#"[project]
requires-python = ">= 3.11"
[tool.ruff.lint]
select = ["UP006"]
"#,
)?;
insta::with_settings!({
filters => vec![(tempdir_filter(&tempdir).as_str(), "[TMP]/")]
}, {
assert_cmd_snapshot!(Command::new(get_cargo_bin(BIN_NAME))
.args(STDIN_BASE_OPTIONS)
.arg("--config")
.arg(&ruff_toml)
.args(["--stdin-filename", "test.py"])
.arg("-")
.pass_stdin(r#"from typing import List; foo: List[int]"#), @r###"
success: false
exit_code: 1
----- stdout -----
test.py:1:31: UP006 [*] Use `list` instead of `List` for type annotation
Found 1 error.
[*] 1 fixable with the `--fix` option.
----- stderr -----
"###);
});
let pyproject_toml = tempdir.path().join("pyproject.toml");
fs::write(
&pyproject_toml,
r#"[project]
requires-python = ">= 3.8"
[tool.ruff.lint]
select = ["UP006"]
"#,
)?;
insta::with_settings!({
filters => vec![(tempdir_filter(&tempdir).as_str(), "[TMP]/")]
}, {
assert_cmd_snapshot!(Command::new(get_cargo_bin(BIN_NAME))
.args(STDIN_BASE_OPTIONS)
.arg("--config")
.arg(&pyproject_toml)
.args(["--stdin-filename", "test.py"])
.arg("-")
.pass_stdin(r#"from typing import List; foo: List[int]"#), @r###"
success: true
exit_code: 0
----- stdout -----
All checks passed!
----- stderr -----
"###);
});
Ok(())
}
/// Infer `3.11` from `requires-python` in `pyproject.toml`.
#[test]
fn requires_python_patch() -> Result<()> {
let tempdir = TempDir::new()?;
let pyproject_toml = tempdir.path().join("pyproject.toml");
fs::write(
&pyproject_toml,
r#"[project]
requires-python = ">= 3.11.4"
[tool.ruff.lint]
select = ["UP006"]
"#,
)?;
insta::with_settings!({
filters => vec![(tempdir_filter(&tempdir).as_str(), "[TMP]/")]
}, {
assert_cmd_snapshot!(Command::new(get_cargo_bin(BIN_NAME))
.args(STDIN_BASE_OPTIONS)
.arg("--config")
.arg(&pyproject_toml)
.args(["--stdin-filename", "test.py"])
.arg("-")
.pass_stdin(r#"from typing import List; foo: List[int]"#), @r###"
success: false
exit_code: 1
----- stdout -----
test.py:1:31: UP006 [*] Use `list` instead of `List` for type annotation
Found 1 error.
[*] 1 fixable with the `--fix` option.
----- stderr -----
"###);
});
Ok(())
}
/// Infer `3.11` from `requires-python` in `pyproject.toml`.
#[test]
fn requires_python_equals() -> Result<()> {
let tempdir = TempDir::new()?;
let pyproject_toml = tempdir.path().join("pyproject.toml");
fs::write(
&pyproject_toml,
r#"[project]
requires-python = "== 3.11"
[tool.ruff.lint]
select = ["UP006"]
"#,
)?;
insta::with_settings!({
filters => vec![(tempdir_filter(&tempdir).as_str(), "[TMP]/")]
}, {
assert_cmd_snapshot!(Command::new(get_cargo_bin(BIN_NAME))
.args(STDIN_BASE_OPTIONS)
.arg("--config")
.arg(&pyproject_toml)
.args(["--stdin-filename", "test.py"])
.arg("-")
.pass_stdin(r#"from typing import List; foo: List[int]"#), @r###"
success: false
exit_code: 1
----- stdout -----
test.py:1:31: UP006 [*] Use `list` instead of `List` for type annotation
Found 1 error.
[*] 1 fixable with the `--fix` option.
----- stderr -----
"###);
});
Ok(())
}
/// Infer `3.11` from `requires-python` in `pyproject.toml`.
#[test]
fn requires_python_equals_patch() -> Result<()> {
let tempdir = TempDir::new()?;
let pyproject_toml = tempdir.path().join("pyproject.toml");
fs::write(
&pyproject_toml,
r#"[project]
requires-python = "== 3.11.4"
[tool.ruff.lint]
select = ["UP006"]
"#,
)?;
insta::with_settings!({
filters => vec![(tempdir_filter(&tempdir).as_str(), "[TMP]/")]
}, {
assert_cmd_snapshot!(Command::new(get_cargo_bin(BIN_NAME))
.args(STDIN_BASE_OPTIONS)
.arg("--config")
.arg(&pyproject_toml)
.args(["--stdin-filename", "test.py"])
.arg("-")
.pass_stdin(r#"from typing import List; foo: List[int]"#), @r###"
success: false
exit_code: 1
----- stdout -----
test.py:1:31: UP006 [*] Use `list` instead of `List` for type annotation
Found 1 error.
[*] 1 fixable with the `--fix` option.
----- stderr -----
"###);
});
Ok(())
}

View File

@@ -68,49 +68,3 @@ def func():
np.longfloat(12+34j)
np.lookfor
np.obj2sctype(int)
np.PINF
np.PZERO
np.recfromcsv
np.recfromtxt
np.round_(12.34)
np.safe_eval
np.sctype2char
np.sctypes
np.seterrobj
np.set_numeric_ops
np.set_string_function
np.singlecomplex(12+1j)
np.string_("asdf")
np.source
np.tracemalloc_domain
np.unicode_("asf")
np.who()
np.row_stack(([1,2], [3,4]))
np.alltrue([True, True])
np.anytrue([True, False])
np.cumproduct([1, 2, 3])
np.product([1, 2, 3])

View File

@@ -0,0 +1,58 @@
def func():
import numpy as np
np.obj2sctype(int)
np.PINF
np.PZERO
np.recfromcsv
np.recfromtxt
np.round_(12.34)
np.safe_eval
np.sctype2char
np.sctypes
np.seterrobj
np.set_numeric_ops
np.set_string_function
np.singlecomplex(12+1j)
np.string_("asdf")
np.source
np.tracemalloc_domain
np.unicode_("asf")
np.who()
np.row_stack(([1,2], [3,4]))
np.alltrue([True, True])
np.anytrue([True, False])
np.cumproduct([1, 2, 3])
np.product([1, 2, 3])
np.trapz([1, 2, 3])
np.in1d([1, 2], [1, 3, 5])
np.AxisError
np.ComplexWarning
np.compare_chararrays

View File

@@ -0,0 +1,16 @@
def func():
import numpy as np
np.DTypePromotionError
np.ModuleDeprecationWarning
np.RankWarning
np.TooHardError
np.VisibleDeprecationWarning
np.chararray
np.format_parser

View File

@@ -77,3 +77,6 @@ type Number = int
match(foo):
case(1):
pass
# https://github.com/astral-sh/ruff/issues/12094
pass;

View File

@@ -16,7 +16,10 @@ mod tests {
#[test_case(Rule::NumpyDeprecatedTypeAlias, Path::new("NPY001.py"))]
#[test_case(Rule::NumpyLegacyRandom, Path::new("NPY002.py"))]
#[test_case(Rule::NumpyDeprecatedFunction, Path::new("NPY003.py"))]
// The NPY201 tests are split into multiple files because they get fixed one by one and too many diagnostic exceed the max-iterations limit.
#[test_case(Rule::Numpy2Deprecation, Path::new("NPY201.py"))]
#[test_case(Rule::Numpy2Deprecation, Path::new("NPY201_2.py"))]
#[test_case(Rule::Numpy2Deprecation, Path::new("NPY201_3.py"))]
fn rules(rule_code: Rule, path: &Path) -> Result<()> {
let snapshot = format!("{}_{}", rule_code.as_ref(), path.to_string_lossy());
let diagnostics = test_path(

View File

@@ -574,6 +574,86 @@ pub(crate) fn numpy_2_0_deprecation(checker: &mut Checker, expr: &Expr) {
compatibility: Compatibility::BackwardsCompatible,
},
}),
["numpy", "AxisError"] => Some(Replacement {
existing: "AxisError",
details: Details::AutoImport {
path: "numpy.exceptions",
name: "AxisError",
compatibility: Compatibility::BackwardsCompatible,
},
}),
["numpy", "ComplexWarning"] => Some(Replacement {
existing: "ComplexWarning",
details: Details::AutoImport {
path: "numpy.exceptions",
name: "ComplexWarning",
compatibility: Compatibility::BackwardsCompatible,
},
}),
["numpy", "DTypePromotionError"] => Some(Replacement {
existing: "DTypePromotionError",
details: Details::AutoImport {
path: "numpy.exceptions",
name: "DTypePromotionError",
compatibility: Compatibility::BackwardsCompatible,
},
}),
["numpy", "ModuleDeprecationWarning"] => Some(Replacement {
existing: "ModuleDeprecationWarning",
details: Details::AutoImport {
path: "numpy.exceptions",
name: "ModuleDeprecationWarning",
compatibility: Compatibility::BackwardsCompatible,
},
}),
["numpy", "RankWarning"] => Some(Replacement {
existing: "RankWarning",
details: Details::AutoImport {
path: "numpy.exceptions",
name: "RankWarning",
compatibility: Compatibility::Breaking,
},
}),
["numpy", "TooHardError"] => Some(Replacement {
existing: "TooHardError",
details: Details::AutoImport {
path: "numpy.exceptions",
name: "TooHardError",
compatibility: Compatibility::BackwardsCompatible,
},
}),
["numpy", "VisibleDeprecationWarning"] => Some(Replacement {
existing: "VisibleDeprecationWarning",
details: Details::AutoImport {
path: "numpy.exceptions",
name: "VisibleDeprecationWarning",
compatibility: Compatibility::BackwardsCompatible,
},
}),
["numpy", "compare_chararrays"] => Some(Replacement {
existing: "compare_chararrays",
details: Details::AutoImport {
path: "numpy.char",
name: "compare_chararrays",
compatibility: Compatibility::BackwardsCompatible,
},
}),
["numpy", "chararray"] => Some(Replacement {
existing: "chararray",
details: Details::AutoImport {
path: "numpy.char",
name: "chararray",
compatibility: Compatibility::BackwardsCompatible,
},
}),
["numpy", "format_parser"] => Some(Replacement {
existing: "format_parser",
details: Details::AutoImport {
path: "numpy.rec",
name: "format_parser",
compatibility: Compatibility::BackwardsCompatible,
},
}),
_ => None,
});

View File

@@ -552,7 +552,6 @@ NPY201.py:68:5: NPY201 [*] `np.longfloat` will be removed in NumPy 2.0. Use `num
68 |+ np.longdouble(12+34j)
69 69 |
70 70 | np.lookfor
71 71 |
NPY201.py:70:5: NPY201 `np.lookfor` will be removed in NumPy 2.0. Search NumPys documentation directly.
|
@@ -560,370 +559,4 @@ NPY201.py:70:5: NPY201 `np.lookfor` will be removed in NumPy 2.0. Search NumPy
69 |
70 | np.lookfor
| ^^^^^^^^^^ NPY201
71 |
72 | np.obj2sctype(int)
|
NPY201.py:72:5: NPY201 `np.obj2sctype` will be removed without replacement in NumPy 2.0
|
70 | np.lookfor
71 |
72 | np.obj2sctype(int)
| ^^^^^^^^^^^^^ NPY201
73 |
74 | np.PINF
|
NPY201.py:74:5: NPY201 [*] `np.PINF` will be removed in NumPy 2.0. Use `numpy.inf` instead.
|
72 | np.obj2sctype(int)
73 |
74 | np.PINF
| ^^^^^^^ NPY201
75 |
76 | np.PZERO
|
= help: Replace with `numpy.inf`
Safe fix
71 71 |
72 72 | np.obj2sctype(int)
73 73 |
74 |- np.PINF
74 |+ np.inf
75 75 |
76 76 | np.PZERO
77 77 |
NPY201.py:76:5: NPY201 [*] `np.PZERO` will be removed in NumPy 2.0. Use `0.0` instead.
|
74 | np.PINF
75 |
76 | np.PZERO
| ^^^^^^^^ NPY201
77 |
78 | np.recfromcsv
|
= help: Replace with `0.0`
Safe fix
73 73 |
74 74 | np.PINF
75 75 |
76 |- np.PZERO
76 |+ 0.0
77 77 |
78 78 | np.recfromcsv
79 79 |
NPY201.py:78:5: NPY201 `np.recfromcsv` will be removed in NumPy 2.0. Use `np.genfromtxt` with comma delimiter instead.
|
76 | np.PZERO
77 |
78 | np.recfromcsv
| ^^^^^^^^^^^^^ NPY201
79 |
80 | np.recfromtxt
|
NPY201.py:80:5: NPY201 `np.recfromtxt` will be removed in NumPy 2.0. Use `np.genfromtxt` instead.
|
78 | np.recfromcsv
79 |
80 | np.recfromtxt
| ^^^^^^^^^^^^^ NPY201
81 |
82 | np.round_(12.34)
|
NPY201.py:82:5: NPY201 [*] `np.round_` will be removed in NumPy 2.0. Use `numpy.round` instead.
|
80 | np.recfromtxt
81 |
82 | np.round_(12.34)
| ^^^^^^^^^ NPY201
83 |
84 | np.safe_eval
|
= help: Replace with `numpy.round`
Safe fix
79 79 |
80 80 | np.recfromtxt
81 81 |
82 |- np.round_(12.34)
82 |+ np.round(12.34)
83 83 |
84 84 | np.safe_eval
85 85 |
NPY201.py:84:5: NPY201 [*] `np.safe_eval` will be removed in NumPy 2.0. Use `ast.literal_eval` instead.
|
82 | np.round_(12.34)
83 |
84 | np.safe_eval
| ^^^^^^^^^^^^ NPY201
85 |
86 | np.sctype2char
|
= help: Replace with `ast.literal_eval`
Safe fix
1 |+from ast import literal_eval
1 2 | def func():
2 3 | import numpy as np
3 4 |
--------------------------------------------------------------------------------
81 82 |
82 83 | np.round_(12.34)
83 84 |
84 |- np.safe_eval
85 |+ literal_eval
85 86 |
86 87 | np.sctype2char
87 88 |
NPY201.py:86:5: NPY201 `np.sctype2char` will be removed without replacement in NumPy 2.0
|
84 | np.safe_eval
85 |
86 | np.sctype2char
| ^^^^^^^^^^^^^^ NPY201
87 |
88 | np.sctypes
|
NPY201.py:88:5: NPY201 `np.sctypes` will be removed without replacement in NumPy 2.0
|
86 | np.sctype2char
87 |
88 | np.sctypes
| ^^^^^^^^^^ NPY201
89 |
90 | np.seterrobj
|
NPY201.py:90:5: NPY201 `np.seterrobj` will be removed in NumPy 2.0. Use the `np.errstate` context manager instead.
|
88 | np.sctypes
89 |
90 | np.seterrobj
| ^^^^^^^^^^^^ NPY201
91 |
92 | np.set_numeric_ops
|
NPY201.py:94:5: NPY201 `np.set_string_function` will be removed in NumPy 2.0. Use `np.set_printoptions` for custom printing of NumPy objects.
|
92 | np.set_numeric_ops
93 |
94 | np.set_string_function
| ^^^^^^^^^^^^^^^^^^^^^^ NPY201
95 |
96 | np.singlecomplex(12+1j)
|
NPY201.py:96:5: NPY201 [*] `np.singlecomplex` will be removed in NumPy 2.0. Use `numpy.complex64` instead.
|
94 | np.set_string_function
95 |
96 | np.singlecomplex(12+1j)
| ^^^^^^^^^^^^^^^^ NPY201
97 |
98 | np.string_("asdf")
|
= help: Replace with `numpy.complex64`
Safe fix
93 93 |
94 94 | np.set_string_function
95 95 |
96 |- np.singlecomplex(12+1j)
96 |+ np.complex64(12+1j)
97 97 |
98 98 | np.string_("asdf")
99 99 |
NPY201.py:98:5: NPY201 [*] `np.string_` will be removed in NumPy 2.0. Use `numpy.bytes_` instead.
|
96 | np.singlecomplex(12+1j)
97 |
98 | np.string_("asdf")
| ^^^^^^^^^^ NPY201
99 |
100 | np.source
|
= help: Replace with `numpy.bytes_`
Safe fix
95 95 |
96 96 | np.singlecomplex(12+1j)
97 97 |
98 |- np.string_("asdf")
98 |+ np.bytes_("asdf")
99 99 |
100 100 | np.source
101 101 |
NPY201.py:100:5: NPY201 [*] `np.source` will be removed in NumPy 2.0. Use `inspect.getsource` instead.
|
98 | np.string_("asdf")
99 |
100 | np.source
| ^^^^^^^^^ NPY201
101 |
102 | np.tracemalloc_domain
|
= help: Replace with `inspect.getsource`
Safe fix
1 |+from inspect import getsource
1 2 | def func():
2 3 | import numpy as np
3 4 |
--------------------------------------------------------------------------------
97 98 |
98 99 | np.string_("asdf")
99 100 |
100 |- np.source
101 |+ getsource
101 102 |
102 103 | np.tracemalloc_domain
103 104 |
NPY201.py:102:5: NPY201 [*] `np.tracemalloc_domain` will be removed in NumPy 2.0. Use `numpy.lib.tracemalloc_domain` instead.
|
100 | np.source
101 |
102 | np.tracemalloc_domain
| ^^^^^^^^^^^^^^^^^^^^^ NPY201
103 |
104 | np.unicode_("asf")
|
= help: Replace with `numpy.lib.tracemalloc_domain`
Safe fix
1 |+from numpy.lib import tracemalloc_domain
1 2 | def func():
2 3 | import numpy as np
3 4 |
--------------------------------------------------------------------------------
99 100 |
100 101 | np.source
101 102 |
102 |- np.tracemalloc_domain
103 |+ tracemalloc_domain
103 104 |
104 105 | np.unicode_("asf")
105 106 |
NPY201.py:104:5: NPY201 [*] `np.unicode_` will be removed in NumPy 2.0. Use `numpy.str_` instead.
|
102 | np.tracemalloc_domain
103 |
104 | np.unicode_("asf")
| ^^^^^^^^^^^ NPY201
105 |
106 | np.who()
|
= help: Replace with `numpy.str_`
Safe fix
101 101 |
102 102 | np.tracemalloc_domain
103 103 |
104 |- np.unicode_("asf")
104 |+ np.str_("asf")
105 105 |
106 106 | np.who()
107 107 |
NPY201.py:106:5: NPY201 `np.who` will be removed in NumPy 2.0. Use an IDE variable explorer or `locals()` instead.
|
104 | np.unicode_("asf")
105 |
106 | np.who()
| ^^^^^^ NPY201
107 |
108 | np.row_stack(([1,2], [3,4]))
|
NPY201.py:108:5: NPY201 [*] `np.row_stack` will be removed in NumPy 2.0. Use `numpy.vstack` instead.
|
106 | np.who()
107 |
108 | np.row_stack(([1,2], [3,4]))
| ^^^^^^^^^^^^ NPY201
109 |
110 | np.alltrue([True, True])
|
= help: Replace with `numpy.vstack`
Safe fix
105 105 |
106 106 | np.who()
107 107 |
108 |- np.row_stack(([1,2], [3,4]))
108 |+ np.vstack(([1,2], [3,4]))
109 109 |
110 110 | np.alltrue([True, True])
111 111 |
NPY201.py:110:5: NPY201 [*] `np.alltrue` will be removed in NumPy 2.0. Use `all` instead.
|
108 | np.row_stack(([1,2], [3,4]))
109 |
110 | np.alltrue([True, True])
| ^^^^^^^^^^ NPY201
111 |
112 | np.anytrue([True, False])
|
= help: Replace with `all`
Safe fix
107 107 |
108 108 | np.row_stack(([1,2], [3,4]))
109 109 |
110 |- np.alltrue([True, True])
110 |+ all([True, True])
111 111 |
112 112 | np.anytrue([True, False])
113 113 |
NPY201.py:114:5: NPY201 [*] `np.cumproduct` will be removed in NumPy 2.0. Use `numpy.cumprod` instead.
|
112 | np.anytrue([True, False])
113 |
114 | np.cumproduct([1, 2, 3])
| ^^^^^^^^^^^^^ NPY201
115 |
116 | np.product([1, 2, 3])
|
= help: Replace with `numpy.cumprod`
Safe fix
111 111 |
112 112 | np.anytrue([True, False])
113 113 |
114 |- np.cumproduct([1, 2, 3])
114 |+ np.cumprod([1, 2, 3])
115 115 |
116 116 | np.product([1, 2, 3])
NPY201.py:116:5: NPY201 [*] `np.product` will be removed in NumPy 2.0. Use `numpy.prod` instead.
|
114 | np.cumproduct([1, 2, 3])
115 |
116 | np.product([1, 2, 3])
| ^^^^^^^^^^ NPY201
|
= help: Replace with `numpy.prod`
Safe fix
113 113 |
114 114 | np.cumproduct([1, 2, 3])
115 115 |
116 |- np.product([1, 2, 3])
116 |+ np.prod([1, 2, 3])

View File

@@ -0,0 +1,484 @@
---
source: crates/ruff_linter/src/rules/numpy/mod.rs
---
NPY201_2.py:4:5: NPY201 `np.obj2sctype` will be removed without replacement in NumPy 2.0
|
2 | import numpy as np
3 |
4 | np.obj2sctype(int)
| ^^^^^^^^^^^^^ NPY201
5 |
6 | np.PINF
|
NPY201_2.py:6:5: NPY201 [*] `np.PINF` will be removed in NumPy 2.0. Use `numpy.inf` instead.
|
4 | np.obj2sctype(int)
5 |
6 | np.PINF
| ^^^^^^^ NPY201
7 |
8 | np.PZERO
|
= help: Replace with `numpy.inf`
Safe fix
3 3 |
4 4 | np.obj2sctype(int)
5 5 |
6 |- np.PINF
6 |+ np.inf
7 7 |
8 8 | np.PZERO
9 9 |
NPY201_2.py:8:5: NPY201 [*] `np.PZERO` will be removed in NumPy 2.0. Use `0.0` instead.
|
6 | np.PINF
7 |
8 | np.PZERO
| ^^^^^^^^ NPY201
9 |
10 | np.recfromcsv
|
= help: Replace with `0.0`
Safe fix
5 5 |
6 6 | np.PINF
7 7 |
8 |- np.PZERO
8 |+ 0.0
9 9 |
10 10 | np.recfromcsv
11 11 |
NPY201_2.py:10:5: NPY201 `np.recfromcsv` will be removed in NumPy 2.0. Use `np.genfromtxt` with comma delimiter instead.
|
8 | np.PZERO
9 |
10 | np.recfromcsv
| ^^^^^^^^^^^^^ NPY201
11 |
12 | np.recfromtxt
|
NPY201_2.py:12:5: NPY201 `np.recfromtxt` will be removed in NumPy 2.0. Use `np.genfromtxt` instead.
|
10 | np.recfromcsv
11 |
12 | np.recfromtxt
| ^^^^^^^^^^^^^ NPY201
13 |
14 | np.round_(12.34)
|
NPY201_2.py:14:5: NPY201 [*] `np.round_` will be removed in NumPy 2.0. Use `numpy.round` instead.
|
12 | np.recfromtxt
13 |
14 | np.round_(12.34)
| ^^^^^^^^^ NPY201
15 |
16 | np.safe_eval
|
= help: Replace with `numpy.round`
Safe fix
11 11 |
12 12 | np.recfromtxt
13 13 |
14 |- np.round_(12.34)
14 |+ np.round(12.34)
15 15 |
16 16 | np.safe_eval
17 17 |
NPY201_2.py:16:5: NPY201 [*] `np.safe_eval` will be removed in NumPy 2.0. Use `ast.literal_eval` instead.
|
14 | np.round_(12.34)
15 |
16 | np.safe_eval
| ^^^^^^^^^^^^ NPY201
17 |
18 | np.sctype2char
|
= help: Replace with `ast.literal_eval`
Safe fix
1 |+from ast import literal_eval
1 2 | def func():
2 3 | import numpy as np
3 4 |
--------------------------------------------------------------------------------
13 14 |
14 15 | np.round_(12.34)
15 16 |
16 |- np.safe_eval
17 |+ literal_eval
17 18 |
18 19 | np.sctype2char
19 20 |
NPY201_2.py:18:5: NPY201 `np.sctype2char` will be removed without replacement in NumPy 2.0
|
16 | np.safe_eval
17 |
18 | np.sctype2char
| ^^^^^^^^^^^^^^ NPY201
19 |
20 | np.sctypes
|
NPY201_2.py:20:5: NPY201 `np.sctypes` will be removed without replacement in NumPy 2.0
|
18 | np.sctype2char
19 |
20 | np.sctypes
| ^^^^^^^^^^ NPY201
21 |
22 | np.seterrobj
|
NPY201_2.py:22:5: NPY201 `np.seterrobj` will be removed in NumPy 2.0. Use the `np.errstate` context manager instead.
|
20 | np.sctypes
21 |
22 | np.seterrobj
| ^^^^^^^^^^^^ NPY201
23 |
24 | np.set_numeric_ops
|
NPY201_2.py:26:5: NPY201 `np.set_string_function` will be removed in NumPy 2.0. Use `np.set_printoptions` for custom printing of NumPy objects.
|
24 | np.set_numeric_ops
25 |
26 | np.set_string_function
| ^^^^^^^^^^^^^^^^^^^^^^ NPY201
27 |
28 | np.singlecomplex(12+1j)
|
NPY201_2.py:28:5: NPY201 [*] `np.singlecomplex` will be removed in NumPy 2.0. Use `numpy.complex64` instead.
|
26 | np.set_string_function
27 |
28 | np.singlecomplex(12+1j)
| ^^^^^^^^^^^^^^^^ NPY201
29 |
30 | np.string_("asdf")
|
= help: Replace with `numpy.complex64`
Safe fix
25 25 |
26 26 | np.set_string_function
27 27 |
28 |- np.singlecomplex(12+1j)
28 |+ np.complex64(12+1j)
29 29 |
30 30 | np.string_("asdf")
31 31 |
NPY201_2.py:30:5: NPY201 [*] `np.string_` will be removed in NumPy 2.0. Use `numpy.bytes_` instead.
|
28 | np.singlecomplex(12+1j)
29 |
30 | np.string_("asdf")
| ^^^^^^^^^^ NPY201
31 |
32 | np.source
|
= help: Replace with `numpy.bytes_`
Safe fix
27 27 |
28 28 | np.singlecomplex(12+1j)
29 29 |
30 |- np.string_("asdf")
30 |+ np.bytes_("asdf")
31 31 |
32 32 | np.source
33 33 |
NPY201_2.py:32:5: NPY201 [*] `np.source` will be removed in NumPy 2.0. Use `inspect.getsource` instead.
|
30 | np.string_("asdf")
31 |
32 | np.source
| ^^^^^^^^^ NPY201
33 |
34 | np.tracemalloc_domain
|
= help: Replace with `inspect.getsource`
Safe fix
1 |+from inspect import getsource
1 2 | def func():
2 3 | import numpy as np
3 4 |
--------------------------------------------------------------------------------
29 30 |
30 31 | np.string_("asdf")
31 32 |
32 |- np.source
33 |+ getsource
33 34 |
34 35 | np.tracemalloc_domain
35 36 |
NPY201_2.py:34:5: NPY201 [*] `np.tracemalloc_domain` will be removed in NumPy 2.0. Use `numpy.lib.tracemalloc_domain` instead.
|
32 | np.source
33 |
34 | np.tracemalloc_domain
| ^^^^^^^^^^^^^^^^^^^^^ NPY201
35 |
36 | np.unicode_("asf")
|
= help: Replace with `numpy.lib.tracemalloc_domain`
Safe fix
1 |+from numpy.lib import tracemalloc_domain
1 2 | def func():
2 3 | import numpy as np
3 4 |
--------------------------------------------------------------------------------
31 32 |
32 33 | np.source
33 34 |
34 |- np.tracemalloc_domain
35 |+ tracemalloc_domain
35 36 |
36 37 | np.unicode_("asf")
37 38 |
NPY201_2.py:36:5: NPY201 [*] `np.unicode_` will be removed in NumPy 2.0. Use `numpy.str_` instead.
|
34 | np.tracemalloc_domain
35 |
36 | np.unicode_("asf")
| ^^^^^^^^^^^ NPY201
37 |
38 | np.who()
|
= help: Replace with `numpy.str_`
Safe fix
33 33 |
34 34 | np.tracemalloc_domain
35 35 |
36 |- np.unicode_("asf")
36 |+ np.str_("asf")
37 37 |
38 38 | np.who()
39 39 |
NPY201_2.py:38:5: NPY201 `np.who` will be removed in NumPy 2.0. Use an IDE variable explorer or `locals()` instead.
|
36 | np.unicode_("asf")
37 |
38 | np.who()
| ^^^^^^ NPY201
39 |
40 | np.row_stack(([1,2], [3,4]))
|
NPY201_2.py:40:5: NPY201 [*] `np.row_stack` will be removed in NumPy 2.0. Use `numpy.vstack` instead.
|
38 | np.who()
39 |
40 | np.row_stack(([1,2], [3,4]))
| ^^^^^^^^^^^^ NPY201
41 |
42 | np.alltrue([True, True])
|
= help: Replace with `numpy.vstack`
Safe fix
37 37 |
38 38 | np.who()
39 39 |
40 |- np.row_stack(([1,2], [3,4]))
40 |+ np.vstack(([1,2], [3,4]))
41 41 |
42 42 | np.alltrue([True, True])
43 43 |
NPY201_2.py:42:5: NPY201 [*] `np.alltrue` will be removed in NumPy 2.0. Use `all` instead.
|
40 | np.row_stack(([1,2], [3,4]))
41 |
42 | np.alltrue([True, True])
| ^^^^^^^^^^ NPY201
43 |
44 | np.anytrue([True, False])
|
= help: Replace with `all`
Safe fix
39 39 |
40 40 | np.row_stack(([1,2], [3,4]))
41 41 |
42 |- np.alltrue([True, True])
42 |+ all([True, True])
43 43 |
44 44 | np.anytrue([True, False])
45 45 |
NPY201_2.py:46:5: NPY201 [*] `np.cumproduct` will be removed in NumPy 2.0. Use `numpy.cumprod` instead.
|
44 | np.anytrue([True, False])
45 |
46 | np.cumproduct([1, 2, 3])
| ^^^^^^^^^^^^^ NPY201
47 |
48 | np.product([1, 2, 3])
|
= help: Replace with `numpy.cumprod`
Safe fix
43 43 |
44 44 | np.anytrue([True, False])
45 45 |
46 |- np.cumproduct([1, 2, 3])
46 |+ np.cumprod([1, 2, 3])
47 47 |
48 48 | np.product([1, 2, 3])
49 49 |
NPY201_2.py:48:5: NPY201 [*] `np.product` will be removed in NumPy 2.0. Use `numpy.prod` instead.
|
46 | np.cumproduct([1, 2, 3])
47 |
48 | np.product([1, 2, 3])
| ^^^^^^^^^^ NPY201
49 |
50 | np.trapz([1, 2, 3])
|
= help: Replace with `numpy.prod`
Safe fix
45 45 |
46 46 | np.cumproduct([1, 2, 3])
47 47 |
48 |- np.product([1, 2, 3])
48 |+ np.prod([1, 2, 3])
49 49 |
50 50 | np.trapz([1, 2, 3])
51 51 |
NPY201_2.py:50:5: NPY201 [*] `np.trapz` will be removed in NumPy 2.0. Use `numpy.trapezoid` on NumPy 2.0, or ignore this warning on earlier versions.
|
48 | np.product([1, 2, 3])
49 |
50 | np.trapz([1, 2, 3])
| ^^^^^^^^ NPY201
51 |
52 | np.in1d([1, 2], [1, 3, 5])
|
= help: Replace with `numpy.trapezoid` (requires NumPy 2.0 or greater)
Unsafe fix
47 47 |
48 48 | np.product([1, 2, 3])
49 49 |
50 |- np.trapz([1, 2, 3])
50 |+ np.trapezoid([1, 2, 3])
51 51 |
52 52 | np.in1d([1, 2], [1, 3, 5])
53 53 |
NPY201_2.py:52:5: NPY201 [*] `np.in1d` will be removed in NumPy 2.0. Use `numpy.isin` instead.
|
50 | np.trapz([1, 2, 3])
51 |
52 | np.in1d([1, 2], [1, 3, 5])
| ^^^^^^^ NPY201
53 |
54 | np.AxisError
|
= help: Replace with `numpy.isin`
Safe fix
49 49 |
50 50 | np.trapz([1, 2, 3])
51 51 |
52 |- np.in1d([1, 2], [1, 3, 5])
52 |+ np.isin([1, 2], [1, 3, 5])
53 53 |
54 54 | np.AxisError
55 55 |
NPY201_2.py:54:5: NPY201 [*] `np.AxisError` will be removed in NumPy 2.0. Use `numpy.exceptions.AxisError` instead.
|
52 | np.in1d([1, 2], [1, 3, 5])
53 |
54 | np.AxisError
| ^^^^^^^^^^^^ NPY201
55 |
56 | np.ComplexWarning
|
= help: Replace with `numpy.exceptions.AxisError`
Safe fix
1 |+from numpy.exceptions import AxisError
1 2 | def func():
2 3 | import numpy as np
3 4 |
--------------------------------------------------------------------------------
51 52 |
52 53 | np.in1d([1, 2], [1, 3, 5])
53 54 |
54 |- np.AxisError
55 |+ AxisError
55 56 |
56 57 | np.ComplexWarning
57 58 |
NPY201_2.py:56:5: NPY201 [*] `np.ComplexWarning` will be removed in NumPy 2.0. Use `numpy.exceptions.ComplexWarning` instead.
|
54 | np.AxisError
55 |
56 | np.ComplexWarning
| ^^^^^^^^^^^^^^^^^ NPY201
57 |
58 | np.compare_chararrays
|
= help: Replace with `numpy.exceptions.ComplexWarning`
Safe fix
1 |+from numpy.exceptions import ComplexWarning
1 2 | def func():
2 3 | import numpy as np
3 4 |
--------------------------------------------------------------------------------
53 54 |
54 55 | np.AxisError
55 56 |
56 |- np.ComplexWarning
57 |+ ComplexWarning
57 58 |
58 59 | np.compare_chararrays
NPY201_2.py:58:5: NPY201 [*] `np.compare_chararrays` will be removed in NumPy 2.0. Use `numpy.char.compare_chararrays` instead.
|
56 | np.ComplexWarning
57 |
58 | np.compare_chararrays
| ^^^^^^^^^^^^^^^^^^^^^ NPY201
|
= help: Replace with `numpy.char.compare_chararrays`
Safe fix
1 |+from numpy.char import compare_chararrays
1 2 | def func():
2 3 | import numpy as np
3 4 |
--------------------------------------------------------------------------------
55 56 |
56 57 | np.ComplexWarning
57 58 |
58 |- np.compare_chararrays
59 |+ compare_chararrays

View File

@@ -0,0 +1,172 @@
---
source: crates/ruff_linter/src/rules/numpy/mod.rs
---
NPY201_3.py:4:5: NPY201 [*] `np.DTypePromotionError` will be removed in NumPy 2.0. Use `numpy.exceptions.DTypePromotionError` instead.
|
2 | import numpy as np
3 |
4 | np.DTypePromotionError
| ^^^^^^^^^^^^^^^^^^^^^^ NPY201
5 |
6 | np.ModuleDeprecationWarning
|
= help: Replace with `numpy.exceptions.DTypePromotionError`
Safe fix
1 |+from numpy.exceptions import DTypePromotionError
1 2 | def func():
2 3 | import numpy as np
3 4 |
4 |- np.DTypePromotionError
5 |+ DTypePromotionError
5 6 |
6 7 | np.ModuleDeprecationWarning
7 8 |
NPY201_3.py:6:5: NPY201 [*] `np.ModuleDeprecationWarning` will be removed in NumPy 2.0. Use `numpy.exceptions.ModuleDeprecationWarning` instead.
|
4 | np.DTypePromotionError
5 |
6 | np.ModuleDeprecationWarning
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ NPY201
7 |
8 | np.RankWarning
|
= help: Replace with `numpy.exceptions.ModuleDeprecationWarning`
Safe fix
1 |+from numpy.exceptions import ModuleDeprecationWarning
1 2 | def func():
2 3 | import numpy as np
3 4 |
4 5 | np.DTypePromotionError
5 6 |
6 |- np.ModuleDeprecationWarning
7 |+ ModuleDeprecationWarning
7 8 |
8 9 | np.RankWarning
9 10 |
NPY201_3.py:8:5: NPY201 [*] `np.RankWarning` will be removed in NumPy 2.0. Use `numpy.exceptions.RankWarning` on NumPy 2.0, or ignore this warning on earlier versions.
|
6 | np.ModuleDeprecationWarning
7 |
8 | np.RankWarning
| ^^^^^^^^^^^^^^ NPY201
9 |
10 | np.TooHardError
|
= help: Replace with `numpy.exceptions.RankWarning` (requires NumPy 2.0 or greater)
Unsafe fix
1 |+from numpy.exceptions import RankWarning
1 2 | def func():
2 3 | import numpy as np
3 4 |
--------------------------------------------------------------------------------
5 6 |
6 7 | np.ModuleDeprecationWarning
7 8 |
8 |- np.RankWarning
9 |+ RankWarning
9 10 |
10 11 | np.TooHardError
11 12 |
NPY201_3.py:10:5: NPY201 [*] `np.TooHardError` will be removed in NumPy 2.0. Use `numpy.exceptions.TooHardError` instead.
|
8 | np.RankWarning
9 |
10 | np.TooHardError
| ^^^^^^^^^^^^^^^ NPY201
11 |
12 | np.VisibleDeprecationWarning
|
= help: Replace with `numpy.exceptions.TooHardError`
Safe fix
1 |+from numpy.exceptions import TooHardError
1 2 | def func():
2 3 | import numpy as np
3 4 |
--------------------------------------------------------------------------------
7 8 |
8 9 | np.RankWarning
9 10 |
10 |- np.TooHardError
11 |+ TooHardError
11 12 |
12 13 | np.VisibleDeprecationWarning
13 14 |
NPY201_3.py:12:5: NPY201 [*] `np.VisibleDeprecationWarning` will be removed in NumPy 2.0. Use `numpy.exceptions.VisibleDeprecationWarning` instead.
|
10 | np.TooHardError
11 |
12 | np.VisibleDeprecationWarning
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ NPY201
13 |
14 | np.chararray
|
= help: Replace with `numpy.exceptions.VisibleDeprecationWarning`
Safe fix
1 |+from numpy.exceptions import VisibleDeprecationWarning
1 2 | def func():
2 3 | import numpy as np
3 4 |
--------------------------------------------------------------------------------
9 10 |
10 11 | np.TooHardError
11 12 |
12 |- np.VisibleDeprecationWarning
13 |+ VisibleDeprecationWarning
13 14 |
14 15 | np.chararray
15 16 |
NPY201_3.py:14:5: NPY201 [*] `np.chararray` will be removed in NumPy 2.0. Use `numpy.char.chararray` instead.
|
12 | np.VisibleDeprecationWarning
13 |
14 | np.chararray
| ^^^^^^^^^^^^ NPY201
15 |
16 | np.format_parser
|
= help: Replace with `numpy.char.chararray`
Safe fix
1 |+from numpy.char import chararray
1 2 | def func():
2 3 | import numpy as np
3 4 |
--------------------------------------------------------------------------------
11 12 |
12 13 | np.VisibleDeprecationWarning
13 14 |
14 |- np.chararray
15 |+ chararray
15 16 |
16 17 | np.format_parser
NPY201_3.py:16:5: NPY201 [*] `np.format_parser` will be removed in NumPy 2.0. Use `numpy.rec.format_parser` instead.
|
14 | np.chararray
15 |
16 | np.format_parser
| ^^^^^^^^^^^^^^^^ NPY201
|
= help: Replace with `numpy.rec.format_parser`
Safe fix
1 |+from numpy.rec import format_parser
1 2 | def func():
2 3 | import numpy as np
3 4 |
--------------------------------------------------------------------------------
13 14 |
14 15 | np.chararray
15 16 |
16 |- np.format_parser
17 |+ format_parser

View File

@@ -60,6 +60,7 @@ pub(crate) fn missing_whitespace_after_keyword(
|| matches!(
tok1_kind,
TokenKind::Colon
| TokenKind::Semi
| TokenKind::Newline
| TokenKind::NonLogicalNewline
// In the event of a syntax error, do not attempt to add a whitespace.

View File

@@ -124,6 +124,7 @@ E27.py:77:1: E275 [*] Missing whitespace after keyword
77 |+match (foo):
78 78 | case(1):
79 79 | pass
80 80 |
E27.py:78:5: E275 [*] Missing whitespace after keyword
|
@@ -142,3 +143,5 @@ E27.py:78:5: E275 [*] Missing whitespace after keyword
78 |- case(1):
78 |+ case (1):
79 79 | pass
80 80 |
81 81 | # https://github.com/astral-sh/ruff/issues/12094

View File

@@ -9,7 +9,8 @@ use std::string::ToString;
use anyhow::{bail, Result};
use globset::{Glob, GlobMatcher, GlobSet, GlobSetBuilder};
use pep440_rs::{Version as Pep440Version, VersionSpecifier, VersionSpecifiers};
use log::debug;
use pep440_rs::{Operator, Version as Pep440Version, Version, VersionSpecifier, VersionSpecifiers};
use rustc_hash::FxHashMap;
use serde::{de, Deserialize, Deserializer, Serialize};
use strum::IntoEnumIterator;
@@ -59,7 +60,7 @@ pub enum PythonVersion {
impl From<PythonVersion> for Pep440Version {
fn from(version: PythonVersion) -> Self {
let (major, minor) = version.as_tuple();
Self::from_str(&format!("{major}.{minor}.100")).unwrap()
Self::new([u64::from(major), u64::from(minor)])
}
}
@@ -89,18 +90,36 @@ impl PythonVersion {
self.as_tuple().1
}
/// Infer the minimum supported [`PythonVersion`] from a `requires-python` specifier.
pub fn get_minimum_supported_version(requires_version: &VersionSpecifiers) -> Option<Self> {
let mut minimum_version = None;
for python_version in PythonVersion::iter() {
if requires_version
.iter()
.all(|specifier| specifier.contains(&python_version.into()))
{
minimum_version = Some(python_version);
break;
}
/// Truncate a version to its major and minor components.
fn major_minor(version: &Version) -> Option<Version> {
let major = version.release().first()?;
let minor = version.release().get(1)?;
Some(Version::new([major, minor]))
}
minimum_version
// Extract the minimum supported version from the specifiers.
let minimum_version = requires_version
.iter()
.filter(|specifier| {
matches!(
specifier.operator(),
Operator::Equal
| Operator::EqualStar
| Operator::ExactEqual
| Operator::TildeEqual
| Operator::GreaterThan
| Operator::GreaterThanEqual
)
})
.filter_map(|specifier| major_minor(specifier.version()))
.min()?;
debug!("Detected minimum supported `requires-python` version: {minimum_version}");
// Find the Python version that matches the minimum supported version.
PythonVersion::iter().find(|version| Version::from(*version) == minimum_version)
}
/// Return `true` if the current version supports [PEP 701].

View File

@@ -404,7 +404,7 @@ impl std::fmt::Display for LexicalErrorType {
write!(f, "Got unexpected token {tok}")
}
LexicalErrorType::LineContinuationError => {
write!(f, "unexpected character after line continuation character")
write!(f, "Expected a newline after line continuation character")
}
LexicalErrorType::Eof => write!(f, "unexpected EOF while parsing"),
LexicalErrorType::OtherError(msg) => write!(f, "{msg}"),

View File

@@ -247,7 +247,7 @@ impl<'src> Lexer<'src> {
} else if !self.cursor.eat_char('\n') {
return Some(self.push_error(LexicalError::new(
LexicalErrorType::LineContinuationError,
TextRange::at(self.offset(), self.cursor.first().text_len()),
TextRange::at(self.offset() - '\\'.text_len(), '\\'.text_len()),
)));
}
indentation = Indentation::root();
@@ -339,7 +339,7 @@ impl<'src> Lexer<'src> {
} else if !self.cursor.eat_char('\n') {
return Err(LexicalError::new(
LexicalErrorType::LineContinuationError,
TextRange::at(self.offset(), self.cursor.first().text_len()),
TextRange::at(self.offset() - '\\'.text_len(), '\\'.text_len()),
));
}
}

View File

@@ -11,10 +11,10 @@ Module(
body: [
Expr(
StmtExpr {
range: 0..14,
range: 0..13,
value: Call(
ExprCall {
range: 0..14,
range: 0..13,
func: Name(
ExprName {
range: 0..4,
@@ -23,7 +23,7 @@ Module(
},
),
arguments: Arguments {
range: 4..14,
range: 4..13,
args: [
Name(
ExprName {
@@ -82,7 +82,7 @@ Module(
|
1 | call(a, b, \\\
| ^ Syntax Error: unexpected character after line continuation character
| ^ Syntax Error: Expected a newline after line continuation character
2 |
3 | def bar():
|
@@ -90,7 +90,7 @@ Module(
|
1 | call(a, b, \\\
| ^ Syntax Error: unexpected character after line continuation character
| ^ Syntax Error: Expected a newline after line continuation character
2 |
3 | def bar():
|

View File

@@ -364,8 +364,7 @@ fn severity(code: &str) -> lsp_types::DiagnosticSeverity {
match code {
// F821: undefined name <name>
// E902: IOError
// E999: SyntaxError
"F821" | "E902" | "E999" => lsp_types::DiagnosticSeverity::ERROR,
"F821" | "E902" => lsp_types::DiagnosticSeverity::ERROR,
_ => lsp_types::DiagnosticSeverity::WARNING,
}
}

View File

@@ -28,7 +28,7 @@ use ruff_workspace::Settings;
#[wasm_bindgen(typescript_custom_section)]
const TYPES: &'static str = r#"
export interface Diagnostic {
code: string;
code: string | null;
message: string;
location: {
row: number;
@@ -57,7 +57,7 @@ export interface Diagnostic {
#[derive(Serialize, Deserialize, Eq, PartialEq, Debug)]
pub struct ExpandedMessage {
pub code: String,
pub code: Option<String>,
pub message: String,
pub location: SourceLocation,
pub end_location: SourceLocation,
@@ -199,17 +199,17 @@ impl Workspace {
let messages: Vec<ExpandedMessage> = diagnostics
.into_iter()
.map(|message| {
let start_location = source_code.source_location(message.start());
let end_location = source_code.source_location(message.end());
.map(|diagnostic| {
let start_location = source_code.source_location(diagnostic.start());
let end_location = source_code.source_location(diagnostic.end());
ExpandedMessage {
code: message.kind.rule().noqa_code().to_string(),
message: message.kind.body,
code: Some(diagnostic.kind.rule().noqa_code().to_string()),
message: diagnostic.kind.body,
location: start_location,
end_location,
fix: message.fix.map(|fix| ExpandedFix {
message: message.kind.suggestion,
fix: diagnostic.fix.map(|fix| ExpandedFix {
message: diagnostic.kind.suggestion,
edits: fix
.edits()
.iter()
@@ -222,6 +222,18 @@ impl Workspace {
}),
}
})
.chain(parsed.errors().iter().map(|parse_error| {
let start_location = source_code.source_location(parse_error.location.start());
let end_location = source_code.source_location(parse_error.location.end());
ExpandedMessage {
code: None,
message: format!("SyntaxError: {}", parse_error.error),
location: start_location,
end_location,
fix: None,
}
}))
.collect();
serde_wasm_bindgen::to_value(&messages).map_err(into_error)

View File

@@ -25,7 +25,7 @@ fn empty_config() {
"if (1, 2):\n pass",
r#"{}"#,
[ExpandedMessage {
code: Rule::IfTuple.noqa_code().to_string(),
code: Some(Rule::IfTuple.noqa_code().to_string()),
message: "If test is a tuple, which is always `True`".to_string(),
location: SourceLocation {
row: OneIndexed::from_zero_indexed(0),
@@ -40,6 +40,27 @@ fn empty_config() {
);
}
#[wasm_bindgen_test]
fn syntax_error() {
check!(
"x =\ny = 1\n",
r#"{}"#,
[ExpandedMessage {
code: None,
message: "SyntaxError: Expected an expression".to_string(),
location: SourceLocation {
row: OneIndexed::from_zero_indexed(0),
column: OneIndexed::from_zero_indexed(3)
},
end_location: SourceLocation {
row: OneIndexed::from_zero_indexed(1),
column: OneIndexed::from_zero_indexed(0)
},
fix: None,
}]
);
}
#[wasm_bindgen_test]
fn partial_config() {
check!("if (1, 2):\n pass", r#"{"ignore": ["F"]}"#, []);

View File

@@ -13,7 +13,22 @@ ruff check # Lint all files in the current directory.
ruff format # Format all files in the current directory.
```
For **macOS Homebrew** and **Linuxbrew** users, Ruff is also available as [`ruff`](https://formulae.brew.sh/formula/ruff)
Starting with version `0.5.0`, Ruff can be installed with our standalone installers:
```shell
# On macOS and Linux.
curl -LsSf https://astral.sh/ruff/install.sh | sh
# On Windows.
powershell -c "irm https://astral.sh/ruff/install.ps1 | iex"
# For a specific version.
curl -LsSf https://astral.sh/ruff/0.5.0/install.sh | sh
powershell -c "irm https://astral.sh/ruff/0.5.0/install.ps1 | iex"
```
For **macOS Homebrew** and **Linuxbrew** users, Ruff is also available
as [`ruff`](https://formulae.brew.sh/formula/ruff)
on Homebrew:
```shell
@@ -60,6 +75,9 @@ the latest release.
```shell
docker run -v .:/io --rm ghcr.io/astral-sh/ruff check
docker run -v .:/io --rm ghcr.io/astral-sh/ruff:0.3.0 check
# Or, for Podman on SELinux.
docker run -v .:/io:Z --rm ghcr.io/astral-sh/ruff check
```
[![Packaging status](https://repology.org/badge/vertical-allrepos/ruff-python-linter.svg?exclude_unsupported=1)](https://repology.org/project/ruff-python-linter/versions)

View File

@@ -304,8 +304,11 @@ Ruff is also available as [`emacs-ruff-format`](https://github.com/scop/emacs-ru
Alternatively, it can be used via the [Apheleia](https://github.com/radian-software/apheleia) formatter library, by setting this configuration:
```emacs-lisp
(add-to-list 'apheleia-mode-alist '(python-mode . ruff))
(add-to-list 'apheleia-mode-alist '(python-ts-mode . ruff))
;; Replace default (black) to use ruff for sorting import and formatting.
(setf (alist-get 'python-mode apheleia-mode-alist)
'(ruff-isort ruff))
(setf (alist-get 'python-ts-mode apheleia-mode-alist)
'(ruff-isort ruff))
```
## TextMate (Unofficial)

View File

@@ -39,7 +39,7 @@ export default function SourceEditor({
startColumn: diagnostic.location.column,
endLineNumber: diagnostic.end_location.row,
endColumn: diagnostic.end_location.column,
message: `${diagnostic.code}: ${diagnostic.message}`,
message: diagnostic.code ? `${diagnostic.code}: ${diagnostic.message}` : diagnostic.message,
severity: MarkerSeverity.Error,
tags:
diagnostic.code === "F401" || diagnostic.code === "F841"