Skip to content

Commit 5373748

Browse files
authored
Merge pull request #5573 from plotly/ekl-migrate-ci-uv-lock-upgrade
Upgrade dependency versions in `uv.lock`, test with Pandas 3 in CI
2 parents c9d7330 + 319bc28 commit 5373748

File tree

7 files changed

+8433
-2830
lines changed

7 files changed

+8433
-2830
lines changed

.github/workflows/check-js-build.yml

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,13 @@
1-
on: push
1+
on:
2+
push:
3+
branches:
4+
- main
5+
pull_request:
6+
types: [opened, reopened]
7+
paths:
8+
- 'js/**'
9+
- 'plotly/labextension/**'
10+
211
name: Check JS build
312

413
jobs:

.github/workflows/run-pytest.yml

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ jobs:
5656
run: |
5757
uv venv
5858
source .venv/bin/activate
59-
uv sync --extra dev_optional
59+
uv sync --extra dev_optional --extra dev_pandas3
6060
python --version
6161
- name: Test core
6262
run: |
@@ -84,14 +84,22 @@ jobs:
8484
python -m pytest -x test_init/test_lazy_imports.py
8585
8686
test-optional-legacy-pandas:
87-
name: Optional tests, Pandas 1 (Python 3.9, Pandas 1.2.4)
87+
name: Optional tests (Python ${{ matrix.python-version }}, pandas ${{ matrix.pandas-version }})
8888
runs-on: ubuntu-latest
89+
strategy:
90+
fail-fast: false
91+
matrix:
92+
include:
93+
- python-version: "3.9"
94+
pandas-version: "1"
95+
- python-version: "3.11"
96+
pandas-version: "2"
8997
steps:
9098
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
9199
- name: Set up Python
92100
uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
93101
with:
94-
python-version: "3.9"
102+
python-version: ${{ matrix.python-version }}
95103
- name: Set up Chrome for browser tests
96104
uses: ./.github/actions/setup-chrome-for-pytest
97105
- name: Set up uv
@@ -100,8 +108,7 @@ jobs:
100108
run: |
101109
uv venv
102110
source .venv/bin/activate
103-
uv sync --extra dev_optional
104-
uv pip install pandas==1.2.4 numpy==1.26.4
111+
uv sync --extra dev_optional --extra dev_pandas${{ matrix.pandas-version }}
105112
- name: Test core
106113
run: |
107114
source .venv/bin/activate
@@ -128,7 +135,7 @@ jobs:
128135
python -m pytest -x test_init/test_lazy_imports.py
129136
130137
test-kaleido-v0:
131-
name: Optional tests (Kaleido only), Kaleido v0 (Python 3.12, Kaleido v0.2.1)
138+
name: Optional tests (Kaleido only), Kaleido v0 (Python 3.12, kaleido 0.2.1)
132139
runs-on: ubuntu-latest
133140
steps:
134141
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@ This project adheres to [Semantic Versioning](http://semver.org/).
44

55
## Unreleased
66

7+
### Fixed
8+
- Update tests to be compatible with numpy 2.4 [[#5522](https://github.com/plotly/plotly.py/pull/5522)], with thanks to @thunze for the contribution!
9+
710

811
## [6.7.0] - 2026-04-09
912

pyproject.toml

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,8 +83,26 @@ dev = [
8383
"plotly[dev_optional]"
8484
]
8585

86+
# The following extras are intended for use in CI only
87+
dev_pandas1 = [
88+
"pandas>=1,<2",
89+
"numpy>=1,<2",
90+
"setuptools<82"
91+
]
92+
dev_pandas2 = [
93+
"pandas>=2,<3",
94+
]
95+
dev_pandas3 = [
96+
"pandas>=3;python_version>='3.11'",
97+
]
98+
8699
[tool.uv]
87100
exclude-newer = "72 hours"
101+
conflicts = [
102+
[{ extra = "dev_pandas1" }, { extra = "dev_pandas2" }],
103+
[{ extra = "dev_pandas1" }, { extra = "dev_pandas3" }],
104+
[{ extra = "dev_pandas2" }, { extra = "dev_pandas3" }],
105+
]
88106

89107
[project.scripts]
90108
plotly_get_chrome = "plotly.io._kaleido:plotly_get_chrome"

tests/test_optional/test_px/test_px_functions.py

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,19 @@
1-
import plotly.express as px
2-
import plotly.graph_objects as go
3-
from numpy.testing import assert_array_equal
41
import narwhals.stable.v1 as nw
52
import numpy as np
3+
from numpy.testing import assert_array_equal
4+
from packaging.version import Version
5+
import pandas
6+
import plotly.express as px
7+
import plotly.graph_objects as go
68
from polars.exceptions import InvalidOperationError
79
import pytest
810

11+
from .conftest import pandas_pyarrow_constructor
12+
13+
14+
def _pandas_version_at_least(version: str) -> bool:
15+
return Version(pandas.__version__) >= Version(version)
16+
917

1018
def _compare_figures(go_trace, px_fig):
1119
"""Compare a figure created with a go trace and a figure created with
@@ -153,6 +161,11 @@ def test_sunburst_treemap_colorscales():
153161

154162

155163
def test_sunburst_treemap_with_path(constructor):
164+
if _pandas_version_at_least("3.0.0") and constructor == pandas_pyarrow_constructor:
165+
pytest.skip(
166+
"known issue with pandas 3 + pandas_pyarrow_constructor + px.sunburst() (https://github.com/plotly/plotly.py/issues/5571)"
167+
)
168+
156169
vendors = ["A", "B", "C", "D", "E", "F", "G", "H"]
157170
sectors = [
158171
"Tech",
@@ -249,6 +262,11 @@ def test_sunburst_treemap_with_path_and_hover(backend):
249262

250263

251264
def test_sunburst_treemap_with_path_color(constructor):
265+
if _pandas_version_at_least("3.0.0") and constructor == pandas_pyarrow_constructor:
266+
pytest.skip(
267+
"known issue with pandas 3 + pandas_pyarrow_constructor + px.sunburst() (https://github.com/plotly/plotly.py/issues/5571)"
268+
)
269+
252270
vendors = ["A", "B", "C", "D", "E", "F", "G", "H"]
253271
sectors = [
254272
"Tech",
@@ -327,6 +345,11 @@ def test_sunburst_treemap_with_path_color(constructor):
327345

328346

329347
def test_sunburst_treemap_column_parent(constructor):
348+
if _pandas_version_at_least("3.0.0") and constructor == pandas_pyarrow_constructor:
349+
pytest.skip(
350+
"known issue with pandas 3 + pandas_pyarrow_constructor + px.sunburst() (https://github.com/plotly/plotly.py/issues/5571)"
351+
)
352+
330353
vendors = ["A", "B", "C", "D", "E", "F", "G", "H"]
331354
sectors = [
332355
"Tech",
@@ -354,6 +377,11 @@ def test_sunburst_treemap_column_parent(constructor):
354377

355378

356379
def test_sunburst_treemap_with_path_non_rectangular(constructor):
380+
if _pandas_version_at_least("3.0.0") and constructor == pandas_pyarrow_constructor:
381+
pytest.skip(
382+
"known issue with pandas 3 + pandas_pyarrow_constructor + px.sunburst() (https://github.com/plotly/plotly.py/issues/5571)"
383+
)
384+
357385
vendors = ["A", "B", "C", "D", None, "E", "F", "G", "H", None]
358386
sectors = [
359387
"Tech",

tests/test_optional/test_utils/test_utils.py

Lines changed: 54 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -311,11 +311,24 @@ def test_encode_customdata_datetime_series(self):
311311
fig_json = _json.dumps(
312312
fig, cls=utils.PlotlyJSONEncoder, separators=(",", ":"), sort_keys=True
313313
)
314-
self.assertTrue(
315-
fig_json.startswith(
316-
'{"data":[{"customdata":["2010-01-01T00:00:00.000000000","2010-01-02T00:00:00.000000000"]'
314+
315+
fig_from_json = Figure(_json.loads(fig_json))
316+
317+
import pandas
318+
319+
if Version(pandas.__version__) >= Version("3.0.0"):
320+
# Starting in pandas 3, datetimes have ms precision by default
321+
# https://pandas.pydata.org/docs/whatsnew/v3.0.0.html#datetime-timedelta-resolution-inference
322+
assert fig_from_json.data[0].customdata == (
323+
"2010-01-01T00:00:00.000000",
324+
"2010-01-02T00:00:00.000000",
325+
)
326+
else:
327+
# Before pandas 3, datetimes have ns precision by default
328+
assert fig_from_json.data[0].customdata == (
329+
"2010-01-01T00:00:00.000000000",
330+
"2010-01-02T00:00:00.000000000",
317331
)
318-
)
319332

320333
def test_encode_customdata_datetime_homogeneous_dataframe(self):
321334
df = pd.DataFrame(
@@ -332,13 +345,24 @@ def test_encode_customdata_datetime_homogeneous_dataframe(self):
332345
fig_json = _json.dumps(
333346
fig, cls=utils.PlotlyJSONEncoder, separators=(",", ":"), sort_keys=True
334347
)
335-
self.assertTrue(
336-
fig_json.startswith(
337-
'{"data":[{"customdata":'
338-
'[["2010-01-01T00:00:00.000000000","2011-01-01T00:00:00.000000000"],'
339-
'["2010-01-02T00:00:00.000000000","2011-01-02T00:00:00.000000000"]'
348+
349+
fig_from_json = Figure(_json.loads(fig_json))
350+
351+
import pandas
352+
353+
if Version(pandas.__version__) >= Version("3.0.0"):
354+
# Starting in pandas 3, datetimes have ms precision by default
355+
# https://pandas.pydata.org/docs/whatsnew/v3.0.0.html#datetime-timedelta-resolution-inference
356+
assert fig_from_json.data[0].customdata == (
357+
["2010-01-01T00:00:00.000000", "2011-01-01T00:00:00.000000"],
358+
["2010-01-02T00:00:00.000000", "2011-01-02T00:00:00.000000"],
359+
)
360+
else:
361+
# Before pandas 3, datetimes have ns precision by default
362+
assert fig_from_json.data[0].customdata == (
363+
["2010-01-01T00:00:00.000000000", "2011-01-01T00:00:00.000000000"],
364+
["2010-01-02T00:00:00.000000000", "2011-01-02T00:00:00.000000000"],
340365
)
341-
)
342366

343367
def test_encode_customdata_datetime_inhomogeneous_dataframe(self):
344368
df = pd.DataFrame(
@@ -384,11 +408,26 @@ def test_datetime_dot_date(self):
384408
def test_numpy_datetime64(self):
385409
a = pd.date_range("2011-07-11", "2011-07-13", freq="D").values
386410
j1 = _json.dumps(a, cls=utils.PlotlyJSONEncoder)
387-
assert (
388-
j1 == '["2011-07-11T00:00:00.000000000", '
389-
'"2011-07-12T00:00:00.000000000", '
390-
'"2011-07-13T00:00:00.000000000"]'
391-
)
411+
412+
from_json = _json.loads(j1)
413+
414+
import pandas
415+
416+
if Version(pandas.__version__) >= Version("3.0.0"):
417+
# Starting in pandas 3, datetimes have ms precision by default
418+
# https://pandas.pydata.org/docs/whatsnew/v3.0.0.html#datetime-timedelta-resolution-inference
419+
assert from_json == [
420+
"2011-07-11T00:00:00.000000",
421+
"2011-07-12T00:00:00.000000",
422+
"2011-07-13T00:00:00.000000",
423+
]
424+
else:
425+
# Before pandas 3, datetimes have ns precision by default
426+
assert from_json == [
427+
"2011-07-11T00:00:00.000000000",
428+
"2011-07-12T00:00:00.000000000",
429+
"2011-07-13T00:00:00.000000000",
430+
]
392431

393432
def test_pil_image_encoding(self):
394433
img_path = os.path.join(

0 commit comments

Comments
 (0)