Skip to content

Commit

Permalink
Use NP_COPY_IF_NEEDED for compatibility with new copy semantics
Browse files Browse the repository at this point in the history
With NumPy 2.0.0, `copy=False` now raises a ValueError if the copy
cannot be made. The previous behavior to only copy if needed is provided
with `copy=None`. During the transition period, use this symbol instead.
Remove once NumPy 2.0.0 is the minimal required version [1, 2]

This approach was inspired by astropy [3].

[1] https://numpy.org/devdocs/release/2.0.0-notes.html#new-copy-keyword-meaning-for-array-and-asarray-constructors
[2] https://www.github.com/numpy/numpy/pull/25168
[3] https://github.com/astropy/astropy/blob/2390bf8f8f2a1c5b6beffbd87db9af5aa6538df1/astropy/utils/compat/numpycompat.py#L29
  • Loading branch information
lagru committed Mar 13, 2024
1 parent c3bd672 commit 950c8d6
Show file tree
Hide file tree
Showing 6 changed files with 33 additions and 3 deletions.
2 changes: 2 additions & 0 deletions TODO.txt
Original file line number Diff line number Diff line change
Expand Up @@ -36,3 +36,5 @@ Post numpy 2
dependencies. Also remove temporary assert for NumPy 2.0 in
`nightly_wheel_build.yml`.
- Remove references to `numpy.bool8` once NumPy 2.0 is minimal required version.
- Remove `skimage._shared.compat.NP_COPY_IF_NEEDED` and all usages of it
once NumPy 2.0.0 is minimal required version.
22 changes: 22 additions & 0 deletions skimage/_shared/compat.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
"""Compatibility helpers for dependencies."""

from packaging.version import parse

import numpy as np


__all__ = [
"NUMPY_LT_2_0_0",
"NP_COPY_IF_NEEDED",
]


NUMPY_LT_2_0_0 = parse(np.__version__) < parse('2.0.0.dev0')

# With NumPy 2.0.0, `copy=False` now raises a ValueError if the copy cannot be
# made. The previous behavior to only copy if needed is provided with `copy=None`.
# During the transition period, use this symbol instead.
# Remove once NumPy 2.0.0 is the minimal required version.
# https://numpy.org/devdocs/release/2.0.0-notes.html#new-copy-keyword-meaning-for-array-and-asarray-constructors
# https://github.com/numpy/numpy/pull/25168
NP_COPY_IF_NEEDED = False if NUMPY_LT_2_0_0 else None
1 change: 1 addition & 0 deletions skimage/_shared/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ python_sources = [
'_geometry.py',
'_tempfile.py',
'_warnings.py',
'compat.py',
'coord.py',
'dtype.py',
'filters.py',
Expand Down
3 changes: 2 additions & 1 deletion skimage/draw/draw.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

from .._shared._geometry import polygon_clip
from .._shared.version_requirements import require
from .._shared.compat import NP_COPY_IF_NEEDED
from ._draw import (
_coords_inside_image,
_line,
Expand Down Expand Up @@ -336,7 +337,7 @@ def set_color(image, coords, color, alpha=1):
if image.ndim == 2:
image = image[..., np.newaxis]

color = np.array(color, ndmin=1, copy=False)
color = np.array(color, ndmin=1, copy=NP_COPY_IF_NEEDED)

if image.shape[-1] != color.shape[-1]:
raise ValueError(
Expand Down
5 changes: 4 additions & 1 deletion skimage/feature/orb.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
from .corner import corner_fast, corner_orientations, corner_peaks, corner_harris
from ..transform import pyramid_gaussian
from .._shared.utils import check_nD
from .._shared.compat import NP_COPY_IF_NEEDED

from .orb_cy import _orb_loop

Expand Down Expand Up @@ -226,7 +227,9 @@ def detect(self, image):

def _extract_octave(self, octave_image, keypoints, orientations):
mask = _mask_border_keypoints(octave_image.shape, keypoints, distance=20)
keypoints = np.array(keypoints[mask], dtype=np.intp, order='C', copy=False)
keypoints = np.array(
keypoints[mask], dtype=np.intp, order='C', copy=NP_COPY_IF_NEEDED
)
orientations = np.array(orientations[mask], order='C', copy=False)

descriptors = _orb_loop(octave_image, keypoints, orientations)
Expand Down
3 changes: 2 additions & 1 deletion skimage/transform/_geometric.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
from scipy import spatial

from .._shared.utils import safe_as_int
from .._shared.compat import NP_COPY_IF_NEEDED


def _affine_matrix_from_vector(v):
Expand Down Expand Up @@ -672,7 +673,7 @@ def _inv_matrix(self):

def _apply_mat(self, coords, matrix):
ndim = matrix.shape[0] - 1
coords = np.array(coords, copy=False, ndmin=2)
coords = np.array(coords, copy=NP_COPY_IF_NEEDED, ndmin=2)

src = np.concatenate([coords, np.ones((coords.shape[0], 1))], axis=1)
dst = src @ matrix.T
Expand Down

0 comments on commit 950c8d6

Please sign in to comment.