Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Numpy 2.0 compability #6238

Merged
merged 14 commits into from
May 23, 2024
10 changes: 8 additions & 2 deletions .github/workflows/test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -85,15 +85,21 @@ jobs:
run: |
MATRIX=$(jq -nsc '{
"os": ["ubuntu-latest", "macos-latest", "windows-latest"],
"environment": ["test-39", "test-312"]
"environment": ["test-39", "test-312"],
"include": [
{ "os": "ubuntu-latest", "environment": "test-numpy" }
]
}')
echo "MATRIX=$MATRIX" >> $GITHUB_ENV
- name: Set test matrix with 'full' option
if: env.MATRIX_OPTION == 'full'
run: |
MATRIX=$(jq -nsc '{
"os": ["ubuntu-latest", "macos-latest", "windows-latest"],
"environment": ["test-39", "test-310", "test-311", "test-312"]
"environment": ["test-39", "test-310", "test-311", "test-312"],
"include": [
{ "os": "ubuntu-latest", "environment": "test-numpy" }
]
}')
echo "MATRIX=$MATRIX" >> $GITHUB_ENV
- name: Set test matrix with 'downstream' option
Expand Down
17 changes: 17 additions & 0 deletions examples/conftest.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import os
import platform
import sys
from importlib.util import find_spec

import bokeh
import pandas as pd
Expand Down Expand Up @@ -62,6 +63,22 @@
"user_guide/Plotting_with_Matplotlib.ipynb",
]

# 2024-05: Numpy 2.0
if find_spec("datashader") is None:
collect_ignore_glob += [
"reference/elements/matplotlib/ImageStack.ipynb",
"reference/elements/plotly/ImageStack.ipynb",
"user_guide/15-Large_Data.ipynb",
"user_guide/16-Streaming_Data.ipynb",
"user_guide/Linked_Brushing.ipynb",
"user_guide/Network_Graphs.ipynb",
]

if find_spec("scikit-image"):
collect_ignore_glob += [
"user_guide/Network_Graphs.ipynb",
]


def pytest_runtest_makereport(item, call):
"""
Expand Down
2 changes: 1 addition & 1 deletion holoviews/core/sheetcoords.py
Original file line number Diff line number Diff line change
Expand Up @@ -365,7 +365,7 @@ def __new__(cls, bounds, sheet_coordinate_system, force_odd=False,
else:
slicespec=Slice._boundsspec2slicespec(bounds.lbrt(),sheet_coordinate_system)
# Using numpy.int32 for legacy reasons
a = np.array(slicespec, dtype=np.int32, copy=False).view(cls)
a = np.asarray(slicespec, dtype=np.int32).view(cls)
return a


Expand Down
3 changes: 3 additions & 0 deletions holoviews/core/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,9 @@
_PANDAS_ROWS_LARGE = 1_000_000
_PANDAS_SAMPLE_SIZE = 1_000_000

numpy_version = Version(Version(np.__version__).base_version)
NUMPY_GE_200 = numpy_version >= Version("2")

pandas_version = Version(pd.__version__)
try:
if pandas_version >= Version('1.3.0'):
Expand Down
6 changes: 5 additions & 1 deletion holoviews/tests/core/test_dimensions.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import pandas as pd

from holoviews.core import Dimension, Dimensioned
from holoviews.core.util import NUMPY_GE_200
from holoviews.element.comparison import ComparisonTestCase

from ..utils import LoggingComparisonTestCase
Expand Down Expand Up @@ -243,7 +244,10 @@ def test_tuple_clone(self):
class DimensionDefaultTest(ComparisonTestCase):

def test_validate_default_against_values(self):
msg = r"Dimension\('A'\) default 1\.1 not found in declared values: \[0, 1\]"
if NUMPY_GE_200:
msg = r"Dimension\('A'\) default 1\.1 not found in declared values: \[np\.int64\(0\), np\.int64\(1\)\]"
else:
msg = r"Dimension\('A'\) default 1\.1 not found in declared values: \[0, 1\]"
with self.assertRaisesRegex(ValueError, msg):
Dimension('A', values=[0, 1], default=1.1)

Expand Down
7 changes: 6 additions & 1 deletion holoviews/tests/element/test_comparisondimension.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
Test cases for Dimension and Dimensioned object comparison.
"""
from holoviews.core import Dimension, Dimensioned
from holoviews.core.util import NUMPY_GE_200
from holoviews.element.comparison import ComparisonTestCase


Expand Down Expand Up @@ -74,7 +75,11 @@ def test_dimension_comparison_values_unequal(self):
try:
self.assertEqual(self.dimension4, self.dimension8)
except AssertionError as e:
self.assertEqual(str(e), "Dimension parameter 'values' mismatched: [] != ['a', 'b']")
if NUMPY_GE_200:
msg = "Dimension parameter 'values' mismatched: [] != [np.str_('a'), np.str_('b')]"
else:
msg = "Dimension parameter 'values' mismatched: [] != ['a', 'b']"
self.assertEqual(str(e), msg)
hoxbro marked this conversation as resolved.
Show resolved Hide resolved

def test_dimension_comparison_types_unequal(self):
try:
Expand Down
13 changes: 8 additions & 5 deletions holoviews/tests/test_streams.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@

import holoviews as hv
from holoviews.core.spaces import DynamicMap
from holoviews.core.util import Version
from holoviews.core.util import NUMPY_GE_200, Version
from holoviews.element import Curve, Histogram, Points, Polygons, Scatter
from holoviews.element.comparison import ComparisonTestCase
from holoviews.streams import * # noqa (Test all available streams)
Expand Down Expand Up @@ -1421,6 +1421,7 @@ def test_selection_expr_stream_hist_invert_xaxis_yaxis(self):


def test_selection_expr_stream_polygon_index_cols(self):
# TODO: Should test both spatialpandas and shapely
# Create SelectionExpr on element
try: import shapely # noqa
except ImportError:
Expand All @@ -1444,10 +1445,12 @@ def test_selection_expr_stream_polygon_index_cols(self):
self.assertIsNone(expr_stream.bbox)
self.assertIsNone(expr_stream.selection_expr)

fmt = lambda x: list(map(np.str_, x)) if NUMPY_GE_200 else x

expr_stream.input_streams[2].event(index=[0, 1])
self.assertEqual(
repr(expr_stream.selection_expr),
repr(dim('cat').isin(['a', 'b']))
repr(dim('cat').isin(fmt(['a', 'b'])))
)
self.assertEqual(expr_stream.bbox, None)
self.assertEqual(len(events), 1)
Expand All @@ -1456,23 +1459,23 @@ def test_selection_expr_stream_polygon_index_cols(self):
expr_stream.input_streams[0].event(bounds=(0, 0, 4, 1))
self.assertEqual(
repr(expr_stream.selection_expr),
repr(dim('cat').isin(['a', 'b']))
repr(dim('cat').isin(fmt(['a', 'b'])))
)
self.assertEqual(len(events), 1)

# Ensure geometry event does trigger another update
expr_stream.input_streams[1].event(geometry=np.array([(0, 0), (4, 0), (4, 2), (0, 2)]))
self.assertEqual(
repr(expr_stream.selection_expr),
repr(dim('cat').isin(['a', 'b', 'c']))
repr(dim('cat').isin(fmt(['a', 'b', 'c'])))
)
self.assertEqual(len(events), 2)

# Ensure index event does trigger another update
expr_stream.input_streams[2].event(index=[1, 2])
self.assertEqual(
repr(expr_stream.selection_expr),
repr(dim('cat').isin(['b', 'c']))
repr(dim('cat').isin(fmt(['b', 'c'])))
)
self.assertEqual(expr_stream.bbox, None)
self.assertEqual(len(events), 3)
Expand Down
34 changes: 34 additions & 0 deletions pixi.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ test-311 = ["py311", "test-core", "test", "example", "test-example", "test-unit-
test-312 = ["py312", "test-core", "test", "example", "test-example", "test-unit-task"]
test-ui = ["py312", "test-core", "test", "test-ui"]
test-core = ["py312", "test-core", "test-unit-task"]
test-numpy = ["py312", "test-core", "test-unit-task", "numpy2", "test-example"]
test-gpu = ["py311", "test-core", "test", "test-gpu"]
docs = ["py311", "example", "doc"]
build = ["py311", "build"]
Expand Down Expand Up @@ -134,6 +135,39 @@ rmm = { version = "*", channel = "rapidsai" }
[feature.test-gpu.tasks]
test-gpu = { cmd = "pytest holoviews/tests --gpu", env = { NUMBA_CUDA_LOW_OCCUPANCY_WARNINGS = '0' } }

[feature.numpy2]
channels = ["pyviz/label/dev", "conda-forge/label/numpy_rc", "numba/label/dev", "conda-forge"]

[feature.numpy2.dependencies]
numpy = "2.*"
numba = { version = "0.60.*", channel = "numba/label/dev" }
llvmlite = { version = "*", channel = "numba/label/dev" }

# test dependencies
cftime = "*"
contourpy = "*"
dask-core = "*"
datashader = ">=0.11.1"
ffmpeg = "*"
ibis-sqlite = "*"
nbconvert = "*"
networkx = "*"
pillow = "*"
scipy = ">=1.10" # Python 3.9 + Windows downloads 1.9
selenium = "*"
shapely = "*"
# spatialpandas = "*"
xarray = ">=0.10.4"
xyzservices = "*"

# Examples (removed duplicates)
# netcdf4 = "*"
notebook = "*"
pooch = "*"
# pyarrow = "*"
# scikit-image = "*"
streamz = ">=0.5.0"

# =============================================
# =================== DOCS ====================
# =============================================
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ filterwarnings = [
# 2023-01: Sqlalchemy 2.0 warning:
"ignore: Deprecated API features detected:DeprecationWarning:ibis.backends.base.sql.alchemy", # https://github.com/ibis-project/ibis/issues/5048
# 2023-03: Already handling the nested sequence
"ignore:Creating an ndarray from ragged nested sequences:numpy.VisibleDeprecationWarning:holoviews.core.data.spatialpandas",
"ignore:Creating an ndarray from ragged nested sequences::holoviews.core.data.spatialpandas",
# 2023-09: Dash needs to update their code to use the comm module and pkg_resources
"ignore:The `.+?` class has been deprecated:DeprecationWarning:dash._jupyter",
"ignore:pkg_resources is deprecated as an API:DeprecationWarning:dash.dash",
Expand Down