Implement NumPy 2.0 migration rule (#7702)

## Summary

<!-- What's the purpose of the change? What does it do, and why? -->

Hi! Currently NumPy Python API is undergoing a cleanup process that will
be delivered in NumPy 2.0 (release is planned for the end of the year).
Most changes are rather simple (renaming, removing or moving a member of
the main namespace to a new place), and they could be flagged/fixed by
an additional ruff rule for numpy (e.g. changing occurrences of
`np.float_` to `np.float64`).

Would you accept such rule?  

I named it `NPY201` in the existing group, so people will receive a
heads-up for changes arriving in 2.0 before actually migrating to it.

~~This is still a draft PR.~~ I'm not an expert in rust so if any part
of code can be done better please share!

NumPy 2.0 migration guide:
https://numpy.org/devdocs/numpy_2_0_migration_guide.html
NEP 52: https://numpy.org/neps/nep-0052-python-api-cleanup.html
NumPy cleanup tracking issue:
https://github.com/numpy/numpy/issues/23999


## Test Plan

A unit test is provided that checks all rule's fix cases.
This commit is contained in:
Mateusz Sokół
2023-11-03 04:47:01 +01:00
committed by GitHub
parent f64c389654
commit d04d964ace
8 changed files with 1460 additions and 0 deletions

View File

@@ -0,0 +1,106 @@
def func():
import numpy as np
np.add_docstring
np.add_newdoc
np.add_newdoc_ufunc
np.asfarray([1,2,3])
np.byte_bounds(np.array([1,2,3]))
np.cast
np.cfloat(12+34j)
np.clongfloat(12+34j)
np.compat
np.complex_(12+34j)
np.DataSource
np.deprecate
np.deprecate_with_doc
np.disp(10)
np.fastCopyAndTranspose
np.find_common_type
np.get_array_wrap
np.float_
np.geterrobj
np.Inf
np.Infinity
np.infty
np.issctype
np.issubclass_(np.int32, np.integer)
np.issubsctype
np.mat
np.maximum_sctype
np.NaN
np.nbytes[np.int64]
np.NINF
np.NZERO
np.longcomplex(12+34j)
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()

View File

@@ -158,6 +158,9 @@ pub(crate) fn expression(expr: &Expr, checker: &mut Checker) {
if checker.enabled(Rule::NumpyDeprecatedFunction) {
numpy::rules::deprecated_function(checker, expr);
}
if checker.enabled(Rule::Numpy2Deprecation) {
numpy::rules::numpy_2_0_deprecation(checker, expr);
}
if checker.enabled(Rule::CollectionsNamedTuple) {
flake8_pyi::rules::collections_named_tuple(checker, expr);
}
@@ -314,6 +317,9 @@ pub(crate) fn expression(expr: &Expr, checker: &mut Checker) {
if checker.enabled(Rule::NumpyDeprecatedFunction) {
numpy::rules::deprecated_function(checker, expr);
}
if checker.enabled(Rule::Numpy2Deprecation) {
numpy::rules::numpy_2_0_deprecation(checker, expr);
}
if checker.enabled(Rule::DeprecatedMockImport) {
pyupgrade::rules::deprecated_mock_attribute(checker, expr);
}

View File

@@ -859,6 +859,7 @@ pub fn code_to_rule(linter: Linter, code: &str) -> Option<(RuleGroup, Rule)> {
(Numpy, "001") => (RuleGroup::Stable, rules::numpy::rules::NumpyDeprecatedTypeAlias),
(Numpy, "002") => (RuleGroup::Stable, rules::numpy::rules::NumpyLegacyRandom),
(Numpy, "003") => (RuleGroup::Stable, rules::numpy::rules::NumpyDeprecatedFunction),
(Numpy, "201") => (RuleGroup::Preview, rules::numpy::rules::Numpy2Deprecation),
// ruff
(Ruff, "001") => (RuleGroup::Stable, rules::ruff::rules::AmbiguousUnicodeCharacterString),

View File

@@ -16,6 +16,7 @@ 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"))]
#[test_case(Rule::Numpy2Deprecation, Path::new("NPY201.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

@@ -1,7 +1,9 @@
pub(crate) use deprecated_function::*;
pub(crate) use deprecated_type_alias::*;
pub(crate) use legacy_random::*;
pub(crate) use numpy_2_0_deprecation::*;
mod deprecated_function;
mod deprecated_type_alias;
mod legacy_random;
mod numpy_2_0_deprecation;

View File

@@ -0,0 +1,476 @@
use ruff_diagnostics::{Diagnostic, Edit, Fix, FixAvailability, Violation};
use ruff_macros::{derive_message_formats, violation};
use ruff_python_ast::Expr;
use ruff_text_size::Ranged;
use crate::checkers::ast::Checker;
use crate::importer::ImportRequest;
/// ## What it does
/// Checks for uses of NumPy functions and constants that were removed from
/// the main namespace in NumPy 2.0.
///
/// ## Why is this bad?
/// NumPy 2.0 includes an overhaul of NumPy's Python API, intended to remove
/// redundant aliases and routines, and establish unambiguous mechanisms for
/// accessing constants, dtypes, and functions.
///
/// As part of this overhaul, a variety of deprecated NumPy functions and
/// constants were removed from the main namespace.
///
/// The majority of these functions and constants can be automatically replaced
/// by other members of the NumPy API, even prior to NumPy 2.0, or by
/// equivalents from the Python standard library. This rule flags all uses of
/// removed members, along with automatic fixes for any backwards-compatible
/// replacements.
///
/// ## Examples
/// ```python
/// import numpy as np
///
/// arr1 = [np.Infinity, np.NaN, np.nan, np.PINF, np.inf]
/// arr2 = [np.float_(1.5), np.float64(5.1)]
/// np.round_(arr2)
/// ```
///
/// Use instead:
/// ```python
/// import numpy as np
///
/// arr1 = [np.inf, np.nan, np.nan, np.inf, np.inf]
/// arr2 = [np.float64(1.5), np.float64(5.1)]
/// np.round(arr2)
/// ```
#[violation]
pub struct Numpy2Deprecation {
existing: String,
migration_guide: Option<String>,
}
impl Violation for Numpy2Deprecation {
const FIX_AVAILABILITY: FixAvailability = FixAvailability::Sometimes;
#[derive_message_formats]
fn message(&self) -> String {
let Numpy2Deprecation {
existing,
migration_guide,
} = self;
match migration_guide {
Some(migration_guide) => {
format!("`np.{existing}` will be removed in NumPy 2.0. {migration_guide}",)
}
None => format!("`np.{existing}` will be removed without replacement in NumPy 2.0."),
}
}
fn fix_title(&self) -> Option<String> {
let Numpy2Deprecation {
existing: _,
migration_guide,
} = self;
migration_guide.clone()
}
}
#[derive(Debug)]
struct Replacement<'a> {
existing: &'a str,
details: Details<'a>,
}
#[derive(Debug)]
enum Details<'a> {
/// The deprecated member can be replaced by another member in the NumPy API.
AutoImport { path: &'a str, name: &'a str },
/// The deprecated member can be replaced by a member of the Python standard library.
AutoPurePython { python_expr: &'a str },
/// The deprecated member can be replaced by a manual migration.
Manual { guideline: Option<&'a str> },
}
impl Details<'_> {
fn guideline(&self) -> Option<String> {
match self {
Details::AutoImport { path, name } => Some(format!("Use `{path}.{name}` instead.")),
Details::AutoPurePython { python_expr } => {
Some(format!("Use `{python_expr}` instead."))
}
Details::Manual { guideline } => guideline.map(ToString::to_string),
}
}
}
/// NPY201
pub(crate) fn numpy_2_0_deprecation(checker: &mut Checker, expr: &Expr) {
let maybe_replacement = checker
.semantic()
.resolve_call_path(expr)
.and_then(|call_path| match call_path.as_slice() {
// NumPy's main namespace np.* members removed in 2.0
["numpy", "add_docstring"] => Some(Replacement {
existing: "add_docstring",
details: Details::AutoImport {
path: "numpy.lib",
name: "add_docstring",
},
}),
["numpy", "add_newdoc"] => Some(Replacement {
existing: "add_newdoc",
details: Details::AutoImport {
path: "numpy.lib",
name: "add_newdoc",
},
}),
["numpy", "add_newdoc_ufunc"] => Some(Replacement {
existing: "add_newdoc_ufunc",
details: Details::Manual {
guideline: Some("`add_newdoc_ufunc` is an internal function."),
},
}),
["numpy", "asfarray"] => Some(Replacement {
existing: "asfarray",
details: Details::Manual {
guideline: Some("Use `np.asarray` with a `float` dtype instead."),
},
}),
["numpy", "byte_bounds"] => Some(Replacement {
existing: "byte_bounds",
details: Details::AutoImport {
path: "numpy.lib.array_utils",
name: "byte_bounds",
},
}),
["numpy", "cast"] => Some(Replacement {
existing: "cast",
details: Details::Manual {
guideline: Some("Use `np.asarray(arr, dtype=dtype)` instead."),
},
}),
["numpy", "cfloat"] => Some(Replacement {
existing: "cfloat",
details: Details::AutoImport {
path: "numpy",
name: "complex128",
},
}),
["numpy", "clongfloat"] => Some(Replacement {
existing: "clongfloat",
details: Details::AutoImport {
path: "numpy",
name: "clongdouble",
},
}),
["numpy", "compat"] => Some(Replacement {
existing: "compat",
details: Details::Manual {
guideline: Some("Python 2 is no longer supported."),
},
}),
["numpy", "complex_"] => Some(Replacement {
existing: "complex_",
details: Details::AutoImport {
path: "numpy",
name: "complex128",
},
}),
["numpy", "DataSource"] => Some(Replacement {
existing: "DataSource",
details: Details::AutoImport {
path: "numpy.lib.npyio",
name: "DataSource",
},
}),
["numpy", "deprecate"] => Some(Replacement {
existing: "deprecate",
details: Details::Manual {
guideline: Some("Emit `DeprecationWarning` with `warnings.warn` directly, or use `typing.deprecated`."),
},
}),
["numpy", "deprecate_with_doc"] => Some(Replacement {
existing: "deprecate_with_doc",
details: Details::Manual {
guideline: Some("Emit `DeprecationWarning` with `warnings.warn` directly, or use `typing.deprecated`."),
},
}),
["numpy", "disp"] => Some(Replacement {
existing: "disp",
details: Details::Manual {
guideline: Some("Use a dedicated print function instead."),
},
}),
["numpy", "fastCopyAndTranspose"] => Some(Replacement {
existing: "fastCopyAndTranspose",
details: Details::Manual {
guideline: Some("Use `arr.T.copy()` instead."),
},
}),
["numpy", "find_common_type"] => Some(Replacement {
existing: "find_common_type",
details: Details::Manual {
guideline: Some("Use `numpy.promote_types` or `numpy.result_type` instead. To achieve semantics for the `scalar_types` argument, use `numpy.result_type` and pass the Python values `0`, `0.0`, or `0j`."),
},
}),
["numpy", "get_array_wrap"] => Some(Replacement {
existing: "get_array_wrap",
details: Details::Manual {
guideline: None,
},
}),
["numpy", "float_"] => Some(Replacement {
existing: "float_",
details: Details::AutoImport {
path: "numpy",
name: "float64",
},
}),
["numpy", "geterrobj"] => Some(Replacement {
existing: "geterrobj",
details: Details::Manual {
guideline: Some("Use the `np.errstate` context manager instead."),
},
}),
["numpy", "INF"] => Some(Replacement {
existing: "INF",
details: Details::AutoImport {
path: "numpy",
name: "inf",
},
}),
["numpy", "Inf"] => Some(Replacement {
existing: "Inf",
details: Details::AutoImport {
path: "numpy",
name: "inf",
},
}),
["numpy", "Infinity"] => Some(Replacement {
existing: "Infinity",
details: Details::AutoImport {
path: "numpy",
name: "inf",
},
}),
["numpy", "infty"] => Some(Replacement {
existing: "infty",
details: Details::AutoImport {
path: "numpy",
name: "inf",
},
}),
["numpy", "issctype"] => Some(Replacement {
existing: "issctype",
details: Details::Manual {
guideline: None,
},
}),
["numpy", "issubclass_"] => Some(Replacement {
existing: "issubclass_",
details: Details::AutoPurePython {
python_expr: "issubclass",
},
}),
["numpy", "issubsctype"] => Some(Replacement {
existing: "issubsctype",
details: Details::AutoImport {
path: "numpy",
name: "issubdtype",
},
}),
["numpy", "mat"] => Some(Replacement {
existing: "mat",
details: Details::AutoImport {
path: "numpy",
name: "asmatrix",
},
}),
["numpy", "maximum_sctype"] => Some(Replacement {
existing: "maximum_sctype",
details: Details::Manual {
guideline: None,
},
}),
["numpy", "NaN"] => Some(Replacement {
existing: "NaN",
details: Details::AutoImport {
path: "numpy",
name: "nan",
},
}),
["numpy", "nbytes"] => Some(Replacement {
existing: "nbytes",
details: Details::Manual {
guideline: Some("Use `np.dtype(<dtype>).itemsize` instead."),
},
}),
["numpy", "NINF"] => Some(Replacement {
existing: "NINF",
details: Details::AutoPurePython {
python_expr: "-np.inf",
},
}),
["numpy", "NZERO"] => Some(Replacement {
existing: "NZERO",
details: Details::AutoPurePython {
python_expr: "-0.0",
},
}),
["numpy", "longcomplex"] => Some(Replacement {
existing: "longcomplex",
details: Details::AutoImport {
path: "numpy",
name: "clongdouble",
},
}),
["numpy", "longfloat"] => Some(Replacement {
existing: "longfloat",
details: Details::AutoImport {
path: "numpy",
name: "longdouble",
},
}),
["numpy", "lookfor"] => Some(Replacement {
existing: "lookfor",
details: Details::Manual {
guideline: Some("Search NumPys documentation directly."),
},
}),
["numpy", "obj2sctype"] => Some(Replacement {
existing: "obj2sctype",
details: Details::Manual {
guideline: None,
},
}),
["numpy", "PINF"] => Some(Replacement {
existing: "PINF",
details: Details::AutoImport {
path: "numpy",
name: "inf",
},
}),
["numpy", "PZERO"] => Some(Replacement {
existing: "PZERO",
details: Details::AutoPurePython { python_expr: "0.0" },
}),
["numpy", "recfromcsv"] => Some(Replacement {
existing: "recfromcsv",
details: Details::Manual {
guideline: Some("Use `np.genfromtxt` with comma delimiter instead."),
},
}),
["numpy", "recfromtxt"] => Some(Replacement {
existing: "recfromtxt",
details: Details::Manual {
guideline: Some("Use `np.genfromtxt` instead."),
},
}),
["numpy", "round_"] => Some(Replacement {
existing: "round_",
details: Details::AutoImport {
path: "numpy",
name: "round",
},
}),
["numpy", "safe_eval"] => Some(Replacement {
existing: "safe_eval",
details: Details::AutoImport {
path: "ast",
name: "literal_eval",
},
}),
["numpy", "sctype2char"] => Some(Replacement {
existing: "sctype2char",
details: Details::Manual {
guideline: None,
},
}),
["numpy", "sctypes"] => Some(Replacement {
existing: "sctypes",
details: Details::Manual {
guideline: None,
},
}),
["numpy", "seterrobj"] => Some(Replacement {
existing: "seterrobj",
details: Details::Manual {
guideline: Some("Use the `np.errstate` context manager instead."),
},
}),
["numpy", "set_string_function"] => Some(Replacement {
existing: "set_string_function",
details: Details::Manual {
guideline: Some("Use `np.set_printoptions` for custom printing of NumPy objects."),
},
}),
["numpy", "singlecomplex"] => Some(Replacement {
existing: "singlecomplex",
details: Details::AutoImport {
path: "numpy",
name: "complex64",
},
}),
["numpy", "string_"] => Some(Replacement {
existing: "string_",
details: Details::AutoImport {
path: "numpy",
name: "bytes_",
},
}),
["numpy", "source"] => Some(Replacement {
existing: "source",
details: Details::AutoImport {
path: "inspect",
name: "getsource",
},
}),
["numpy", "tracemalloc_domain"] => Some(Replacement {
existing: "tracemalloc_domain",
details: Details::AutoImport {
path: "numpy.lib",
name: "tracemalloc_domain",
},
}),
["numpy", "unicode_"] => Some(Replacement {
existing: "unicode_",
details: Details::AutoImport {
path: "numpy",
name: "str_",
},
}),
["numpy", "who"] => Some(Replacement {
existing: "who",
details: Details::Manual {
guideline: Some("Use an IDE variable explorer or `locals()` instead."),
},
}),
_ => None,
});
if let Some(replacement) = maybe_replacement {
let mut diagnostic = Diagnostic::new(
Numpy2Deprecation {
existing: replacement.existing.to_string(),
migration_guide: replacement.details.guideline(),
},
expr.range(),
);
match replacement.details {
Details::AutoImport { path, name } => {
diagnostic.try_set_fix(|| {
let (import_edit, binding) = checker.importer().get_or_import_symbol(
&ImportRequest::import_from(path, name),
expr.start(),
checker.semantic(),
)?;
let replacement_edit = Edit::range_replacement(binding, expr.range());
Ok(Fix::safe_edits(import_edit, [replacement_edit]))
});
}
Details::AutoPurePython { python_expr } => diagnostic.set_fix(Fix::safe_edit(
Edit::range_replacement(python_expr.to_string(), expr.range()),
)),
Details::Manual { guideline: _ } => {}
};
checker.diagnostics.push(diagnostic);
}
}

View File

@@ -0,0 +1,865 @@
---
source: crates/ruff_linter/src/rules/numpy/mod.rs
---
NPY201.py:4:5: NPY201 [*] `np.add_docstring` will be removed in NumPy 2.0. Use `numpy.lib.add_docstring` instead.
|
2 | import numpy as np
3 |
4 | np.add_docstring
| ^^^^^^^^^^^^^^^^ NPY201
5 |
6 | np.add_newdoc
|
= help: Use `numpy.lib.add_docstring` instead.
Fix
1 |+from numpy.lib import add_docstring
1 2 | def func():
2 3 | import numpy as np
3 4 |
4 |- np.add_docstring
5 |+ add_docstring
5 6 |
6 7 | np.add_newdoc
7 8 |
NPY201.py:6:5: NPY201 [*] `np.add_newdoc` will be removed in NumPy 2.0. Use `numpy.lib.add_newdoc` instead.
|
4 | np.add_docstring
5 |
6 | np.add_newdoc
| ^^^^^^^^^^^^^ NPY201
7 |
8 | np.add_newdoc_ufunc
|
= help: Use `numpy.lib.add_newdoc` instead.
Fix
1 |+from numpy.lib import add_newdoc
1 2 | def func():
2 3 | import numpy as np
3 4 |
4 5 | np.add_docstring
5 6 |
6 |- np.add_newdoc
7 |+ add_newdoc
7 8 |
8 9 | np.add_newdoc_ufunc
9 10 |
NPY201.py:8:5: NPY201 `np.add_newdoc_ufunc` will be removed in NumPy 2.0. `add_newdoc_ufunc` is an internal function.
|
6 | np.add_newdoc
7 |
8 | np.add_newdoc_ufunc
| ^^^^^^^^^^^^^^^^^^^ NPY201
9 |
10 | np.asfarray([1,2,3])
|
= help: `add_newdoc_ufunc` is an internal function.
NPY201.py:10:5: NPY201 `np.asfarray` will be removed in NumPy 2.0. Use `np.asarray` with a `float` dtype instead.
|
8 | np.add_newdoc_ufunc
9 |
10 | np.asfarray([1,2,3])
| ^^^^^^^^^^^ NPY201
11 |
12 | np.byte_bounds(np.array([1,2,3]))
|
= help: Use `np.asarray` with a `float` dtype instead.
NPY201.py:12:5: NPY201 [*] `np.byte_bounds` will be removed in NumPy 2.0. Use `numpy.lib.array_utils.byte_bounds` instead.
|
10 | np.asfarray([1,2,3])
11 |
12 | np.byte_bounds(np.array([1,2,3]))
| ^^^^^^^^^^^^^^ NPY201
13 |
14 | np.cast
|
= help: Use `numpy.lib.array_utils.byte_bounds` instead.
Fix
1 |+from numpy.lib.array_utils import byte_bounds
1 2 | def func():
2 3 | import numpy as np
3 4 |
--------------------------------------------------------------------------------
9 10 |
10 11 | np.asfarray([1,2,3])
11 12 |
12 |- np.byte_bounds(np.array([1,2,3]))
13 |+ byte_bounds(np.array([1,2,3]))
13 14 |
14 15 | np.cast
15 16 |
NPY201.py:14:5: NPY201 `np.cast` will be removed in NumPy 2.0. Use `np.asarray(arr, dtype=dtype)` instead.
|
12 | np.byte_bounds(np.array([1,2,3]))
13 |
14 | np.cast
| ^^^^^^^ NPY201
15 |
16 | np.cfloat(12+34j)
|
= help: Use `np.asarray(arr, dtype=dtype)` instead.
NPY201.py:16:5: NPY201 [*] `np.cfloat` will be removed in NumPy 2.0. Use `numpy.complex128` instead.
|
14 | np.cast
15 |
16 | np.cfloat(12+34j)
| ^^^^^^^^^ NPY201
17 |
18 | np.clongfloat(12+34j)
|
= help: Use `numpy.complex128` instead.
Fix
13 13 |
14 14 | np.cast
15 15 |
16 |- np.cfloat(12+34j)
16 |+ np.complex128(12+34j)
17 17 |
18 18 | np.clongfloat(12+34j)
19 19 |
NPY201.py:18:5: NPY201 [*] `np.clongfloat` will be removed in NumPy 2.0. Use `numpy.clongdouble` instead.
|
16 | np.cfloat(12+34j)
17 |
18 | np.clongfloat(12+34j)
| ^^^^^^^^^^^^^ NPY201
19 |
20 | np.compat
|
= help: Use `numpy.clongdouble` instead.
Fix
15 15 |
16 16 | np.cfloat(12+34j)
17 17 |
18 |- np.clongfloat(12+34j)
18 |+ np.clongdouble(12+34j)
19 19 |
20 20 | np.compat
21 21 |
NPY201.py:20:5: NPY201 `np.compat` will be removed in NumPy 2.0. Python 2 is no longer supported.
|
18 | np.clongfloat(12+34j)
19 |
20 | np.compat
| ^^^^^^^^^ NPY201
21 |
22 | np.complex_(12+34j)
|
= help: Python 2 is no longer supported.
NPY201.py:22:5: NPY201 [*] `np.complex_` will be removed in NumPy 2.0. Use `numpy.complex128` instead.
|
20 | np.compat
21 |
22 | np.complex_(12+34j)
| ^^^^^^^^^^^ NPY201
23 |
24 | np.DataSource
|
= help: Use `numpy.complex128` instead.
Fix
19 19 |
20 20 | np.compat
21 21 |
22 |- np.complex_(12+34j)
22 |+ np.complex128(12+34j)
23 23 |
24 24 | np.DataSource
25 25 |
NPY201.py:24:5: NPY201 [*] `np.DataSource` will be removed in NumPy 2.0. Use `numpy.lib.npyio.DataSource` instead.
|
22 | np.complex_(12+34j)
23 |
24 | np.DataSource
| ^^^^^^^^^^^^^ NPY201
25 |
26 | np.deprecate
|
= help: Use `numpy.lib.npyio.DataSource` instead.
Fix
1 |+from numpy.lib.npyio import DataSource
1 2 | def func():
2 3 | import numpy as np
3 4 |
--------------------------------------------------------------------------------
21 22 |
22 23 | np.complex_(12+34j)
23 24 |
24 |- np.DataSource
25 |+ DataSource
25 26 |
26 27 | np.deprecate
27 28 |
NPY201.py:26:5: NPY201 `np.deprecate` will be removed in NumPy 2.0. Emit `DeprecationWarning` with `warnings.warn` directly, or use `typing.deprecated`.
|
24 | np.DataSource
25 |
26 | np.deprecate
| ^^^^^^^^^^^^ NPY201
27 |
28 | np.deprecate_with_doc
|
= help: Emit `DeprecationWarning` with `warnings.warn` directly, or use `typing.deprecated`.
NPY201.py:28:5: NPY201 `np.deprecate_with_doc` will be removed in NumPy 2.0. Emit `DeprecationWarning` with `warnings.warn` directly, or use `typing.deprecated`.
|
26 | np.deprecate
27 |
28 | np.deprecate_with_doc
| ^^^^^^^^^^^^^^^^^^^^^ NPY201
29 |
30 | np.disp(10)
|
= help: Emit `DeprecationWarning` with `warnings.warn` directly, or use `typing.deprecated`.
NPY201.py:30:5: NPY201 `np.disp` will be removed in NumPy 2.0. Use a dedicated print function instead.
|
28 | np.deprecate_with_doc
29 |
30 | np.disp(10)
| ^^^^^^^ NPY201
31 |
32 | np.fastCopyAndTranspose
|
= help: Use a dedicated print function instead.
NPY201.py:32:5: NPY201 `np.fastCopyAndTranspose` will be removed in NumPy 2.0. Use `arr.T.copy()` instead.
|
30 | np.disp(10)
31 |
32 | np.fastCopyAndTranspose
| ^^^^^^^^^^^^^^^^^^^^^^^ NPY201
33 |
34 | np.find_common_type
|
= help: Use `arr.T.copy()` instead.
NPY201.py:34:5: NPY201 `np.find_common_type` will be removed in NumPy 2.0. Use `numpy.promote_types` or `numpy.result_type` instead. To achieve semantics for the `scalar_types` argument, use `numpy.result_type` and pass the Python values `0`, `0.0`, or `0j`.
|
32 | np.fastCopyAndTranspose
33 |
34 | np.find_common_type
| ^^^^^^^^^^^^^^^^^^^ NPY201
35 |
36 | np.get_array_wrap
|
= help: Use `numpy.promote_types` or `numpy.result_type` instead. To achieve semantics for the `scalar_types` argument, use `numpy.result_type` and pass the Python values `0`, `0.0`, or `0j`.
NPY201.py:36:5: NPY201 `np.get_array_wrap` will be removed without replacement in NumPy 2.0.
|
34 | np.find_common_type
35 |
36 | np.get_array_wrap
| ^^^^^^^^^^^^^^^^^ NPY201
37 |
38 | np.float_
|
NPY201.py:38:5: NPY201 [*] `np.float_` will be removed in NumPy 2.0. Use `numpy.float64` instead.
|
36 | np.get_array_wrap
37 |
38 | np.float_
| ^^^^^^^^^ NPY201
39 |
40 | np.geterrobj
|
= help: Use `numpy.float64` instead.
Fix
35 35 |
36 36 | np.get_array_wrap
37 37 |
38 |- np.float_
38 |+ np.float64
39 39 |
40 40 | np.geterrobj
41 41 |
NPY201.py:40:5: NPY201 `np.geterrobj` will be removed in NumPy 2.0. Use the `np.errstate` context manager instead.
|
38 | np.float_
39 |
40 | np.geterrobj
| ^^^^^^^^^^^^ NPY201
41 |
42 | np.Inf
|
= help: Use the `np.errstate` context manager instead.
NPY201.py:42:5: NPY201 [*] `np.Inf` will be removed in NumPy 2.0. Use `numpy.inf` instead.
|
40 | np.geterrobj
41 |
42 | np.Inf
| ^^^^^^ NPY201
43 |
44 | np.Infinity
|
= help: Use `numpy.inf` instead.
Fix
39 39 |
40 40 | np.geterrobj
41 41 |
42 |- np.Inf
42 |+ np.inf
43 43 |
44 44 | np.Infinity
45 45 |
NPY201.py:44:5: NPY201 [*] `np.Infinity` will be removed in NumPy 2.0. Use `numpy.inf` instead.
|
42 | np.Inf
43 |
44 | np.Infinity
| ^^^^^^^^^^^ NPY201
45 |
46 | np.infty
|
= help: Use `numpy.inf` instead.
Fix
41 41 |
42 42 | np.Inf
43 43 |
44 |- np.Infinity
44 |+ np.inf
45 45 |
46 46 | np.infty
47 47 |
NPY201.py:46:5: NPY201 [*] `np.infty` will be removed in NumPy 2.0. Use `numpy.inf` instead.
|
44 | np.Infinity
45 |
46 | np.infty
| ^^^^^^^^ NPY201
47 |
48 | np.issctype
|
= help: Use `numpy.inf` instead.
Fix
43 43 |
44 44 | np.Infinity
45 45 |
46 |- np.infty
46 |+ np.inf
47 47 |
48 48 | np.issctype
49 49 |
NPY201.py:48:5: NPY201 `np.issctype` will be removed without replacement in NumPy 2.0.
|
46 | np.infty
47 |
48 | np.issctype
| ^^^^^^^^^^^ NPY201
49 |
50 | np.issubclass_(np.int32, np.integer)
|
NPY201.py:50:5: NPY201 [*] `np.issubclass_` will be removed in NumPy 2.0. Use `issubclass` instead.
|
48 | np.issctype
49 |
50 | np.issubclass_(np.int32, np.integer)
| ^^^^^^^^^^^^^^ NPY201
51 |
52 | np.issubsctype
|
= help: Use `issubclass` instead.
Fix
47 47 |
48 48 | np.issctype
49 49 |
50 |- np.issubclass_(np.int32, np.integer)
50 |+ issubclass(np.int32, np.integer)
51 51 |
52 52 | np.issubsctype
53 53 |
NPY201.py:52:5: NPY201 [*] `np.issubsctype` will be removed in NumPy 2.0. Use `numpy.issubdtype` instead.
|
50 | np.issubclass_(np.int32, np.integer)
51 |
52 | np.issubsctype
| ^^^^^^^^^^^^^^ NPY201
53 |
54 | np.mat
|
= help: Use `numpy.issubdtype` instead.
Fix
49 49 |
50 50 | np.issubclass_(np.int32, np.integer)
51 51 |
52 |- np.issubsctype
52 |+ np.issubdtype
53 53 |
54 54 | np.mat
55 55 |
NPY201.py:54:5: NPY201 [*] `np.mat` will be removed in NumPy 2.0. Use `numpy.asmatrix` instead.
|
52 | np.issubsctype
53 |
54 | np.mat
| ^^^^^^ NPY201
55 |
56 | np.maximum_sctype
|
= help: Use `numpy.asmatrix` instead.
Fix
51 51 |
52 52 | np.issubsctype
53 53 |
54 |- np.mat
54 |+ np.asmatrix
55 55 |
56 56 | np.maximum_sctype
57 57 |
NPY201.py:56:5: NPY201 `np.maximum_sctype` will be removed without replacement in NumPy 2.0.
|
54 | np.mat
55 |
56 | np.maximum_sctype
| ^^^^^^^^^^^^^^^^^ NPY201
57 |
58 | np.NaN
|
NPY201.py:58:5: NPY201 [*] `np.NaN` will be removed in NumPy 2.0. Use `numpy.nan` instead.
|
56 | np.maximum_sctype
57 |
58 | np.NaN
| ^^^^^^ NPY201
59 |
60 | np.nbytes[np.int64]
|
= help: Use `numpy.nan` instead.
Fix
55 55 |
56 56 | np.maximum_sctype
57 57 |
58 |- np.NaN
58 |+ np.nan
59 59 |
60 60 | np.nbytes[np.int64]
61 61 |
NPY201.py:60:5: NPY201 `np.nbytes` will be removed in NumPy 2.0. Use `np.dtype(<dtype>).itemsize` instead.
|
58 | np.NaN
59 |
60 | np.nbytes[np.int64]
| ^^^^^^^^^ NPY201
61 |
62 | np.NINF
|
= help: Use `np.dtype(<dtype>).itemsize` instead.
NPY201.py:62:5: NPY201 [*] `np.NINF` will be removed in NumPy 2.0. Use `-np.inf` instead.
|
60 | np.nbytes[np.int64]
61 |
62 | np.NINF
| ^^^^^^^ NPY201
63 |
64 | np.NZERO
|
= help: Use `-np.inf` instead.
Fix
59 59 |
60 60 | np.nbytes[np.int64]
61 61 |
62 |- np.NINF
62 |+ -np.inf
63 63 |
64 64 | np.NZERO
65 65 |
NPY201.py:64:5: NPY201 [*] `np.NZERO` will be removed in NumPy 2.0. Use `-0.0` instead.
|
62 | np.NINF
63 |
64 | np.NZERO
| ^^^^^^^^ NPY201
65 |
66 | np.longcomplex(12+34j)
|
= help: Use `-0.0` instead.
Fix
61 61 |
62 62 | np.NINF
63 63 |
64 |- np.NZERO
64 |+ -0.0
65 65 |
66 66 | np.longcomplex(12+34j)
67 67 |
NPY201.py:66:5: NPY201 [*] `np.longcomplex` will be removed in NumPy 2.0. Use `numpy.clongdouble` instead.
|
64 | np.NZERO
65 |
66 | np.longcomplex(12+34j)
| ^^^^^^^^^^^^^^ NPY201
67 |
68 | np.longfloat(12+34j)
|
= help: Use `numpy.clongdouble` instead.
Fix
63 63 |
64 64 | np.NZERO
65 65 |
66 |- np.longcomplex(12+34j)
66 |+ np.clongdouble(12+34j)
67 67 |
68 68 | np.longfloat(12+34j)
69 69 |
NPY201.py:68:5: NPY201 [*] `np.longfloat` will be removed in NumPy 2.0. Use `numpy.longdouble` instead.
|
66 | np.longcomplex(12+34j)
67 |
68 | np.longfloat(12+34j)
| ^^^^^^^^^^^^ NPY201
69 |
70 | np.lookfor
|
= help: Use `numpy.longdouble` instead.
Fix
65 65 |
66 66 | np.longcomplex(12+34j)
67 67 |
68 |- np.longfloat(12+34j)
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.
|
68 | np.longfloat(12+34j)
69 |
70 | np.lookfor
| ^^^^^^^^^^ NPY201
71 |
72 | np.obj2sctype(int)
|
= help: Search NumPys documentation directly.
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: Use `numpy.inf` instead.
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: Use `0.0` instead.
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
|
= help: Use `np.genfromtxt` with comma delimiter instead.
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)
|
= help: Use `np.genfromtxt` instead.
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: Use `numpy.round` instead.
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: Use `ast.literal_eval` instead.
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
|
= help: Use the `np.errstate` context manager instead.
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)
|
= help: Use `np.set_printoptions` for custom printing of NumPy objects.
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: Use `numpy.complex64` instead.
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: Use `numpy.bytes_` instead.
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: Use `inspect.getsource` instead.
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: Use `numpy.lib.tracemalloc_domain` instead.
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: Use `numpy.str_` instead.
Fix
101 101 |
102 102 | np.tracemalloc_domain
103 103 |
104 |- np.unicode_("asf")
104 |+ np.str_("asf")
105 105 |
106 106 | np.who()
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
|
= help: Use an IDE variable explorer or `locals()` instead.

3
ruff.schema.json generated
View File

@@ -2903,6 +2903,9 @@
"NPY001",
"NPY002",
"NPY003",
"NPY2",
"NPY20",
"NPY201",
"NURSERY",
"PD",
"PD0",