Update NPY001 rule for NumPy 2.0 (#11735)

Hi!

This PR addresses https://github.com/astral-sh/ruff/issues/11093.

It skips `np.bool` and `np.long` replacements as both of these names
were reintroduced in NumPy 2.0 with a different meaning
(https://github.com/numpy/numpy/pull/24922,
https://github.com/numpy/numpy/pull/25080).
With this change `NPY001` will no longer conflict with `NPY201`. For
projects using NumPy 1.x `np.bool` and `np.long` has been deprecated and
removed long time ago, and accessing them yields an informative error
message.
This commit is contained in:
Mateusz Sokół 2024-06-04 21:23:42 +02:00 committed by GitHub
parent 2c865023ac
commit 1645be018d
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 30 additions and 36 deletions

View file

@ -3,13 +3,13 @@ import numpy as np
import numpy
# Error
npy.bool
npy.float
npy.int
if dtype == np.object:
...
result = result.select_dtypes([np.byte, np.ubyte, np.short, np.ushort, np.int, np.long])
result = result.select_dtypes([np.byte, np.ubyte, np.short, np.ushort, np.int, np.complex])
pdf = pd.DataFrame(
data=[[1, 2, 3]],

View file

@ -10,23 +10,25 @@ use crate::checkers::ast::Checker;
/// Checks for deprecated NumPy type aliases.
///
/// ## Why is this bad?
/// NumPy's `np.int` has long been an alias of the builtin `int`. The same
/// goes for `np.float`, `np.bool`, and others. These aliases exist
/// primarily for historic reasons, and have been a cause of
/// frequent confusion for newcomers.
/// NumPy's `np.int` has long been an alias of the builtin `int`; the same
/// is true of `np.float` and others. These aliases exist primarily
/// for historic reasons, and have been a cause of frequent confusion
/// for newcomers.
///
/// These aliases were deprecated in 1.20, and removed in 1.24.
/// Note, however, that `np.bool` and `np.long` were reintroduced in 2.0 with
/// different semantics, and are thus omitted from this rule.
///
/// ## Examples
/// ```python
/// import numpy as np
///
/// np.bool
/// np.int
/// ```
///
/// Use instead:
/// ```python
/// bool
/// int
/// ```
#[violation]
pub struct NumpyDeprecatedTypeAlias {
@ -63,14 +65,7 @@ pub(crate) fn deprecated_type_alias(checker: &mut Checker, expr: &Expr) {
qualified_name.segments(),
[
"numpy",
"bool"
| "int"
| "float"
| "complex"
| "object"
| "str"
| "long"
| "unicode"
"int" | "float" | "complex" | "object" | "str" | "unicode"
]
) {
Some(qualified_name.segments()[1])
@ -87,7 +82,6 @@ pub(crate) fn deprecated_type_alias(checker: &mut Checker, expr: &Expr) {
);
let type_name = match type_name {
"unicode" => "str",
"long" => "int",
_ => type_name,
};
diagnostic.try_set_fix(|| {

View file

@ -1,21 +1,21 @@
---
source: crates/ruff_linter/src/rules/numpy/mod.rs
---
NPY001.py:6:1: NPY001 [*] Type alias `np.bool` is deprecated, replace with builtin type
NPY001.py:6:1: NPY001 [*] Type alias `np.float` is deprecated, replace with builtin type
|
5 | # Error
6 | npy.bool
| ^^^^^^^^ NPY001
6 | npy.float
| ^^^^^^^^^ NPY001
7 | npy.int
|
= help: Replace `np.bool` with builtin type
= help: Replace `np.float` with builtin type
Safe fix
3 3 | import numpy
4 4 |
5 5 | # Error
6 |-npy.bool
6 |+bool
6 |-npy.float
6 |+float
7 7 | npy.int
8 8 |
9 9 | if dtype == np.object:
@ -23,7 +23,7 @@ NPY001.py:6:1: NPY001 [*] Type alias `np.bool` is deprecated, replace with built
NPY001.py:7:1: NPY001 [*] Type alias `np.int` is deprecated, replace with builtin type
|
5 | # Error
6 | npy.bool
6 | npy.float
7 | npy.int
| ^^^^^^^ NPY001
8 |
@ -34,7 +34,7 @@ NPY001.py:7:1: NPY001 [*] Type alias `np.int` is deprecated, replace with builti
Safe fix
4 4 |
5 5 | # Error
6 6 | npy.bool
6 6 | npy.float
7 |-npy.int
7 |+int
8 8 |
@ -52,20 +52,20 @@ NPY001.py:9:13: NPY001 [*] Type alias `np.object` is deprecated, replace with bu
= help: Replace `np.object` with builtin type
Safe fix
6 6 | npy.bool
6 6 | npy.float
7 7 | npy.int
8 8 |
9 |-if dtype == np.object:
9 |+if dtype == object:
10 10 | ...
11 11 |
12 12 | result = result.select_dtypes([np.byte, np.ubyte, np.short, np.ushort, np.int, np.long])
12 12 | result = result.select_dtypes([np.byte, np.ubyte, np.short, np.ushort, np.int, np.complex])
NPY001.py:12:72: NPY001 [*] Type alias `np.int` is deprecated, replace with builtin type
|
10 | ...
11 |
12 | result = result.select_dtypes([np.byte, np.ubyte, np.short, np.ushort, np.int, np.long])
12 | result = result.select_dtypes([np.byte, np.ubyte, np.short, np.ushort, np.int, np.complex])
| ^^^^^^ NPY001
13 |
14 | pdf = pd.DataFrame(
@ -76,29 +76,29 @@ NPY001.py:12:72: NPY001 [*] Type alias `np.int` is deprecated, replace with buil
9 9 | if dtype == np.object:
10 10 | ...
11 11 |
12 |-result = result.select_dtypes([np.byte, np.ubyte, np.short, np.ushort, np.int, np.long])
12 |+result = result.select_dtypes([np.byte, np.ubyte, np.short, np.ushort, int, np.long])
12 |-result = result.select_dtypes([np.byte, np.ubyte, np.short, np.ushort, np.int, np.complex])
12 |+result = result.select_dtypes([np.byte, np.ubyte, np.short, np.ushort, int, np.complex])
13 13 |
14 14 | pdf = pd.DataFrame(
15 15 | data=[[1, 2, 3]],
NPY001.py:12:80: NPY001 [*] Type alias `np.long` is deprecated, replace with builtin type
NPY001.py:12:80: NPY001 [*] Type alias `np.complex` is deprecated, replace with builtin type
|
10 | ...
11 |
12 | result = result.select_dtypes([np.byte, np.ubyte, np.short, np.ushort, np.int, np.long])
| ^^^^^^^ NPY001
12 | result = result.select_dtypes([np.byte, np.ubyte, np.short, np.ushort, np.int, np.complex])
| ^^^^^^^^^^ NPY001
13 |
14 | pdf = pd.DataFrame(
|
= help: Replace `np.long` with builtin type
= help: Replace `np.complex` with builtin type
Safe fix
9 9 | if dtype == np.object:
10 10 | ...
11 11 |
12 |-result = result.select_dtypes([np.byte, np.ubyte, np.short, np.ushort, np.int, np.long])
12 |+result = result.select_dtypes([np.byte, np.ubyte, np.short, np.ushort, np.int, int])
12 |-result = result.select_dtypes([np.byte, np.ubyte, np.short, np.ushort, np.int, np.complex])
12 |+result = result.select_dtypes([np.byte, np.ubyte, np.short, np.ushort, np.int, complex])
13 13 |
14 14 | pdf = pd.DataFrame(
15 15 | data=[[1, 2, 3]],