Skip to content

Commit 56ddb6f

Browse files
authored
Support numpy 2.0 in tests (#943)
* change np.float_ to np.double * changes to support numpy 2.0
1 parent ab31818 commit 56ddb6f

File tree

11 files changed

+140
-97
lines changed

11 files changed

+140
-97
lines changed

pandas-stubs/_typing.pyi

+4-4
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ BooleanDtypeArg: TypeAlias = (
115115
# Numpy bool type
116116
# https://numpy.org/doc/stable/reference/arrays.scalars.html#numpy.bool_
117117
| type[np.bool_]
118-
| Literal["?", "b1", "bool8", "bool_"]
118+
| Literal["?", "b1", "bool_"]
119119
# PyArrow boolean type and its string alias
120120
| Literal["bool[pyarrow]", "boolean[pyarrow]"]
121121
)
@@ -147,7 +147,7 @@ IntDtypeArg: TypeAlias = (
147147
| Literal["q", "longlong"] # NOTE: int128 not assigned
148148
# https://numpy.org/doc/stable/reference/arrays.scalars.html#numpy.intp
149149
| type[np.intp] # signed pointer (=`intptr_t`, platform dependent)
150-
| Literal["p", "intp", "int0"]
150+
| Literal["p", "intp"]
151151
# PyArrow integer types and their string aliases
152152
| Literal["int8[pyarrow]", "int16[pyarrow]", "int32[pyarrow]", "int64[pyarrow]"]
153153
)
@@ -176,7 +176,7 @@ UIntDtypeArg: TypeAlias = (
176176
| Literal["Q", "ulonglong"] # NOTE: uint128 not assigned
177177
# https://numpy.org/doc/stable/reference/arrays.scalars.html#numpy.uintp
178178
| type[np.uintp] # unsigned pointer (=`uintptr_t`, platform dependent)
179-
| Literal["P", "uintp", "uint0"]
179+
| Literal["P", "uintp"]
180180
# PyArrow unsigned integer types and their string aliases
181181
| Literal["uint8[pyarrow]", "uint16[pyarrow]", "uint32[pyarrow]", "uint64[pyarrow]"]
182182
)
@@ -361,7 +361,7 @@ BytesDtypeArg: TypeAlias = (
361361
# Numpy bytes type and its string alias
362362
# https://numpy.org/doc/stable/reference/arrays.scalars.html#numpy.bytes_
363363
| type[np.bytes_]
364-
| Literal["S", "a", "bytes_", "bytes0", "string_"]
364+
| Literal["S", "bytes_", "bytes0", "string_"]
365365
# PyArrow binary type and its string alias
366366
| Literal["binary[pyarrow]"]
367367
)

pandas-stubs/core/resample.pyi

+1-1
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,7 @@ class Resampler(BaseGroupBy[NDFrameT]):
163163
def count(self: Resampler[DataFrame]) -> DataFrame: ...
164164
def quantile(
165165
self,
166-
q: float | list[float] | npt.NDArray[np.float_] | Series[float] = ...,
166+
q: float | list[float] | npt.NDArray[np.double] | Series[float] = ...,
167167
**kwargs,
168168
) -> NDFrameT: ...
169169

pandas-stubs/core/reshape/tile.pyi

+3-3
Original file line numberDiff line numberDiff line change
@@ -250,7 +250,7 @@ def qcut(
250250
retbins: Literal[True],
251251
precision: int = ...,
252252
duplicates: Literal["raise", "drop"] = ...,
253-
) -> tuple[npt.NDArray[np.intp], npt.NDArray[np.float_]]: ...
253+
) -> tuple[npt.NDArray[np.intp], npt.NDArray[np.double]]: ...
254254
@overload
255255
def qcut(
256256
x: Series,
@@ -260,7 +260,7 @@ def qcut(
260260
retbins: Literal[True],
261261
precision: int = ...,
262262
duplicates: Literal["raise", "drop"] = ...,
263-
) -> tuple[Series, npt.NDArray[np.float_]]: ...
263+
) -> tuple[Series, npt.NDArray[np.double]]: ...
264264
@overload
265265
def qcut(
266266
x: Index | npt.NDArray | Sequence[int] | Sequence[float],
@@ -270,4 +270,4 @@ def qcut(
270270
retbins: Literal[True],
271271
precision: int = ...,
272272
duplicates: Literal["raise", "drop"] = ...,
273-
) -> tuple[Categorical, npt.NDArray[np.float_]]: ...
273+
) -> tuple[Categorical, npt.NDArray[np.double]]: ...

pandas-stubs/core/series.pyi

+10
Original file line numberDiff line numberDiff line change
@@ -230,6 +230,16 @@ _ListLike: TypeAlias = (
230230
class Series(IndexOpsMixin[S1], NDFrame):
231231
__hash__: ClassVar[None]
232232

233+
@overload
234+
def __new__( # type: ignore[overload-overlap]
235+
cls,
236+
data: npt.NDArray[np.float64],
237+
index: Axes | None = ...,
238+
*,
239+
dtype: Dtype = ...,
240+
name: Hashable = ...,
241+
copy: bool = ...,
242+
) -> Series[float]: ...
233243
@overload
234244
def __new__( # type: ignore[overload-overlap]
235245
cls,

pandas-stubs/plotting/_core.pyi

+2-2
Original file line numberDiff line numberDiff line change
@@ -340,7 +340,7 @@ class PlotAccessor:
340340
| Callable[[gaussian_kde], float]
341341
| None
342342
) = ...,
343-
ind: npt.NDArray[np.float_] | int | None = ...,
343+
ind: npt.NDArray[np.double] | int | None = ...,
344344
*,
345345
subplots: Literal[False] | None = ...,
346346
**kwargs,
@@ -354,7 +354,7 @@ class PlotAccessor:
354354
| Callable[[gaussian_kde], float]
355355
| None
356356
) = ...,
357-
ind: npt.NDArray[np.float_] | int | None = ...,
357+
ind: npt.NDArray[np.double] | int | None = ...,
358358
*,
359359
subplots: Literal[True],
360360
**kwargs,

pyproject.toml

+60-38
Original file line numberDiff line numberDiff line change
@@ -8,22 +8,20 @@ readme = "README.md"
88
homepage = "https://pandas.pydata.org"
99
repository = "https://github.com/pandas-dev/pandas-stubs"
1010
classifiers = [
11-
"Development Status :: 5 - Production/Stable",
12-
"Environment :: Console",
13-
"Intended Audience :: Science/Research",
14-
"License :: OSI Approved :: BSD License",
15-
"Operating System :: OS Independent",
16-
"Programming Language :: Python",
17-
"Programming Language :: Python :: 3",
18-
"Programming Language :: Python :: 3 :: Only",
19-
"Programming Language :: Python :: 3.9",
20-
"Programming Language :: Python :: 3.10",
21-
"Programming Language :: Python :: 3.11",
22-
"Topic :: Scientific/Engineering"
23-
]
24-
packages = [
25-
{ "include" = "pandas-stubs"}
11+
"Development Status :: 5 - Production/Stable",
12+
"Environment :: Console",
13+
"Intended Audience :: Science/Research",
14+
"License :: OSI Approved :: BSD License",
15+
"Operating System :: OS Independent",
16+
"Programming Language :: Python",
17+
"Programming Language :: Python :: 3",
18+
"Programming Language :: Python :: 3 :: Only",
19+
"Programming Language :: Python :: 3.9",
20+
"Programming Language :: Python :: 3.10",
21+
"Programming Language :: Python :: 3.11",
22+
"Topic :: Scientific/Engineering",
2623
]
24+
packages = [{ "include" = "pandas-stubs" }]
2725

2826
[tool.poetry.urls]
2927
"Bug Tracker" = "https://github.com/pandas-dev/pandas-stubs/issues"
@@ -33,26 +31,26 @@ packages = [
3331
python = ">=3.9"
3432
types-pytz = ">= 2022.1.1"
3533
numpy = [
36-
{ version = ">=1.23.5", python = ">=3.9,<3.12" },
37-
{ version = ">=1.26.0", python = ">=3.12,<3.13" }
34+
{ version = ">=1.23.5,<2.0.0", python = ">=3.9,<3.12" },
35+
{ version = ">=2.0.0", python = ">=3.12,<3.13" },
3836
]
3937

4038
[tool.poetry.group.dev.dependencies]
41-
mypy = "1.10.0"
39+
mypy = "1.10.1"
4240
pandas = "2.2.2"
4341
pyarrow = ">=10.0.1"
4442
pytest = ">=7.1.2"
45-
pyright = ">=1.1.365"
43+
pyright = ">=1.1.369"
4644
poethepoet = ">=0.16.5"
4745
loguru = ">=0.6.0"
4846
typing-extensions = ">=4.4.0"
49-
matplotlib = ">=3.5.1,<3.9.0" # TODO https://github.com/pandas-dev/pandas/issues/58851
47+
matplotlib = ">=3.5.1,<3.9.0" # TODO https://github.com/pandas-dev/pandas/issues/58851
5048
pre-commit = ">=2.19.0"
5149
black = ">=23.3.0"
5250
isort = ">=5.12.0"
5351
openpyxl = ">=3.0.10"
5452
# for tables, MacOS gives random CI failures on 3.9.2
55-
tables = { version = "==3.9.2", python = "<4"} # 3.8.0 depends on blosc2 which caps python to <4
53+
tables = { version = "==3.9.2", python = "<4" } # 3.8.0 depends on blosc2 which caps python to <4
5654
lxml = ">=4.9.1"
5755
pyreadstat = ">=1.2.0"
5856
xlrd = ">=2.0.1"
@@ -88,15 +86,19 @@ script = "scripts.test:test(dist=True)"
8886
[tool.poe.tasks.pytest]
8987
help = "Run pytest"
9088
script = "scripts.test:pytest(nightly)"
91-
args = [{name = "nightly", positional = false, default = false, type = "boolean", required = false, help= "Use pandas nightly (off by default)"}]
89+
args = [
90+
{ name = "nightly", positional = false, default = false, type = "boolean", required = false, help = "Use pandas nightly (off by default)" },
91+
]
9292

9393
[tool.poe.tasks.style]
9494
help = "Run pre-commit"
9595
script = "scripts.test.run:style"
9696

9797
[tool.poe.tasks.mypy]
9898
help = "Run mypy on 'tests' (using the local stubs) and on the local stubs"
99-
args = [{name = "mypy_nightly", positional = false, default = false, type = "boolean", required = false, help= "Use mypy nightly (off by default)"}]
99+
args = [
100+
{ name = "mypy_nightly", positional = false, default = false, type = "boolean", required = false, help = "Use mypy nightly (off by default)" },
101+
]
100102
script = "scripts.test:mypy_src(mypy_nightly)"
101103

102104
[tool.poe.tasks.mypy_dist]
@@ -114,18 +116,38 @@ script = "scripts.test:test(dist=True, type_checker='pyright')"
114116
[tool.poe.tasks.stubtest]
115117
script = "scripts.test:stubtest(allowlist, check_missing, nightly)"
116118
help = "Run stubtest to compare the installed stubs against pandas"
117-
args = [{ name = "allowlist", positional = true, default = "", required = false, help= "Path to an allowlist (optional)" }, {name = "check_missing", positional = false, default = false, type = "boolean", required = false, help= "Report errors when the stubs are incomplete (off by default)"}, {name = "nightly", positional = false, default = false, type = "boolean", required = false, help= "Compare against pandas nightly (off by default)"}]
119+
args = [
120+
{ name = "allowlist", positional = true, default = "", required = false, help = "Path to an allowlist (optional)" },
121+
{ name = "check_missing", positional = false, default = false, type = "boolean", required = false, help = "Report errors when the stubs are incomplete (off by default)" },
122+
{ name = "nightly", positional = false, default = false, type = "boolean", required = false, help = "Compare against pandas nightly (off by default)" },
123+
]
118124

119125

120126
[tool.black]
121127
target-version = ['py39']
122128

123129
[tool.isort]
124130
known_pre_libs = "pandas._config"
125-
known_pre_core = ["pandas._libs", "pandas._typing", "pandas.util._*", "pandas.compat", "pandas.errors"]
131+
known_pre_core = [
132+
"pandas._libs",
133+
"pandas._typing",
134+
"pandas.util._*",
135+
"pandas.compat",
136+
"pandas.errors",
137+
]
126138
known_dtypes = "pandas.core.dtypes"
127139
known_post_core = ["pandas.tseries", "pandas.io", "pandas.plotting"]
128-
sections = ["FUTURE", "STDLIB", "THIRDPARTY" ,"PRE_LIBS" , "PRE_CORE", "DTYPES", "FIRSTPARTY", "POST_CORE", "LOCALFOLDER"]
140+
sections = [
141+
"FUTURE",
142+
"STDLIB",
143+
"THIRDPARTY",
144+
"PRE_LIBS",
145+
"PRE_CORE",
146+
"DTYPES",
147+
"FIRSTPARTY",
148+
"POST_CORE",
149+
"LOCALFOLDER",
150+
]
129151
profile = "black"
130152
combine_as_imports = true
131153
force_grid_wrap = 2
@@ -142,16 +164,16 @@ follow_imports_for_stubs = false
142164
no_site_packages = false
143165
no_silence_site_packages = false
144166
# Disallow dynamic typing
145-
disallow_any_unimported = false # TODO
146-
disallow_any_expr = false # TODO
147-
disallow_any_decorated = false # TODO
148-
disallow_any_explicit = false # TODO
149-
disallow_any_generics = false # TODO
167+
disallow_any_unimported = false # TODO
168+
disallow_any_expr = false # TODO
169+
disallow_any_decorated = false # TODO
170+
disallow_any_explicit = false # TODO
171+
disallow_any_generics = false # TODO
150172
disallow_subclassing_any = false # TODO
151173
# Untyped definitions and calls
152-
disallow_untyped_calls = false # TODO
153-
disallow_untyped_defs = false # TODO
154-
disallow_incomplete_defs = false # TODO
174+
disallow_untyped_calls = false # TODO
175+
disallow_untyped_defs = false # TODO
176+
disallow_incomplete_defs = false # TODO
155177
check_untyped_defs = true
156178
disallow_untyped_decorators = true
157179
# None and Optional handling
@@ -161,16 +183,16 @@ strict_optional = true
161183
warn_redundant_casts = true
162184
warn_unused_ignores = true
163185
warn_no_return = true
164-
warn_return_any = false # TODO
165-
warn_unreachable = false # GH#27396
186+
warn_return_any = false # TODO
187+
warn_unreachable = false # GH#27396
166188
# Suppressing errors
167189
ignore_errors = false
168190
enable_error_code = "ignore-without-code" # same as in pandas
169191
# Miscellaneous strictness flags
170192
allow_untyped_globals = false
171193
allow_redefinition = false
172194
local_partial_types = false
173-
implicit_reexport = false # pyright behaves the same
195+
implicit_reexport = false # pyright behaves the same
174196
strict_equality = true
175197
# Configuring error messages
176198
show_error_context = false
@@ -181,7 +203,7 @@ show_error_codes = true
181203
typeCheckingMode = "strict"
182204
stubPath = "."
183205
include = ["tests", "pandas-stubs"]
184-
enableTypeIgnoreComments = false # use pyright-specific ignores
206+
enableTypeIgnoreComments = false # use pyright-specific ignores
185207
# disable subset of strict
186208
reportMissingParameterType = false
187209
reportMissingTypeArgument = false

tests/__init__.py

+3-1
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
Literal,
1414
)
1515

16+
import numpy as np
1617
import pandas as pd
1718
from pandas.core.groupby.groupby import BaseGroupBy
1819
from pandas.util.version import Version
@@ -23,6 +24,7 @@
2324
TYPE_CHECKING_INVALID_USAGE: Final = TYPE_CHECKING
2425
WINDOWS = os.name == "nt" or "cygwin" in platform.system().lower()
2526
PD_LTE_22 = Version(pd.__version__) < Version("2.2.999")
27+
NUMPY20 = np.lib.NumpyVersion(np.__version__) >= "2.0.0"
2628

2729

2830
def check(
@@ -40,7 +42,7 @@ def check(
4042
if isinstance(actual, pd.Series):
4143
value = actual.iloc[index_to_check_for_type]
4244
elif isinstance(actual, pd.Index):
43-
value = actual[index_to_check_for_type] # type: ignore[assignment]
45+
value = actual[index_to_check_for_type]
4446
elif isinstance(actual, BaseGroupBy):
4547
value = actual.obj
4648
elif hasattr(actual, "__iter__"):

tests/test_io.py

+6
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@
5353
WINDOWS,
5454
check,
5555
)
56+
from tests import NUMPY20 # See https://github.com/PyTables/PyTables/issues/1172
5657

5758
from pandas.io.api import to_pickle
5859
from pandas.io.json._json import JsonReader
@@ -347,12 +348,14 @@ def test_sas_xport() -> None:
347348
pass
348349

349350

351+
@pytest.mark.skipif(NUMPY20, reason="numpy 2.0 not compatible with Pytables")
350352
def test_hdf():
351353
with ensure_clean() as path:
352354
check(assert_type(DF.to_hdf(path, key="df"), None), type(None))
353355
check(assert_type(read_hdf(path), Union[DataFrame, Series]), DataFrame)
354356

355357

358+
@pytest.mark.skipif(NUMPY20, reason="numpy 2.0 not compatible with Pytables")
356359
def test_hdfstore() -> None:
357360
with ensure_clean() as path:
358361
store = HDFStore(path, model="w")
@@ -396,6 +399,7 @@ def test_hdfstore() -> None:
396399
store.close()
397400

398401

402+
@pytest.mark.skipif(NUMPY20, reason="numpy 2.0 not compatible with Pytables")
399403
def test_read_hdf_iterator() -> None:
400404
with ensure_clean() as path:
401405
check(assert_type(DF.to_hdf(path, key="df", format="table"), None), type(None))
@@ -410,6 +414,7 @@ def test_read_hdf_iterator() -> None:
410414
ti.close()
411415

412416

417+
@pytest.mark.skipif(NUMPY20, reason="numpy 2.0 not compatible with Pytables")
413418
def test_hdf_context_manager() -> None:
414419
with ensure_clean() as path:
415420
check(assert_type(DF.to_hdf(path, key="df", format="table"), None), type(None))
@@ -418,6 +423,7 @@ def test_hdf_context_manager() -> None:
418423
check(assert_type(store.get("df"), Union[DataFrame, Series]), DataFrame)
419424

420425

426+
@pytest.mark.skipif(NUMPY20, reason="numpy 2.0 not compatible with Pytables")
421427
def test_hdf_series():
422428
s = DF["a"]
423429
with ensure_clean() as path:

tests/test_pandas.py

+10-10
Original file line numberDiff line numberDiff line change
@@ -1004,10 +1004,10 @@ def test_qcut() -> None:
10041004
check(assert_type(c0, pd.Categorical), pd.Categorical)
10051005
check(assert_type(d0, pd.Series), pd.Series)
10061006

1007-
check(assert_type(a1, npt.NDArray[np.float_]), np.ndarray)
1008-
check(assert_type(b1, npt.NDArray[np.float_]), np.ndarray)
1009-
check(assert_type(c1, npt.NDArray[np.float_]), np.ndarray)
1010-
check(assert_type(d1, npt.NDArray[np.float_]), np.ndarray)
1007+
check(assert_type(a1, npt.NDArray[np.double]), np.ndarray)
1008+
check(assert_type(b1, npt.NDArray[np.double]), np.ndarray)
1009+
check(assert_type(c1, npt.NDArray[np.double]), np.ndarray)
1010+
check(assert_type(d1, npt.NDArray[np.double]), np.ndarray)
10111011

10121012
e0, e1 = pd.qcut(val_list, [0.25, 0.5, 0.75], retbins=True)
10131013
f0, f1 = pd.qcut(val_arr, np.array([0.25, 0.5, 0.75]), retbins=True)
@@ -1023,12 +1023,12 @@ def test_qcut() -> None:
10231023
check(assert_type(i0, npt.NDArray[np.intp]), np.ndarray)
10241024
check(assert_type(j0, npt.NDArray[np.intp]), np.ndarray)
10251025

1026-
check(assert_type(e1, npt.NDArray[np.float_]), np.ndarray)
1027-
check(assert_type(f1, npt.NDArray[np.float_]), np.ndarray)
1028-
check(assert_type(g1, npt.NDArray[np.float_]), np.ndarray)
1029-
check(assert_type(h1, npt.NDArray[np.float_]), np.ndarray)
1030-
check(assert_type(i1, npt.NDArray[np.float_]), np.ndarray)
1031-
check(assert_type(j1, npt.NDArray[np.float_]), np.ndarray)
1026+
check(assert_type(e1, npt.NDArray[np.double]), np.ndarray)
1027+
check(assert_type(f1, npt.NDArray[np.double]), np.ndarray)
1028+
check(assert_type(g1, npt.NDArray[np.double]), np.ndarray)
1029+
check(assert_type(h1, npt.NDArray[np.double]), np.ndarray)
1030+
check(assert_type(i1, npt.NDArray[np.double]), np.ndarray)
1031+
check(assert_type(j1, npt.NDArray[np.double]), np.ndarray)
10321032

10331033

10341034
def test_merge() -> None:

0 commit comments

Comments
 (0)