Skip to content

Commit 03b347f

Browse files
authored
Merge pull request #265 from numpy/tox
πŸ”§πŸ› configure tox & fix python-specific issues
2 parents f7e4333 + b180f63 commit 03b347f

14 files changed

+99
-77
lines changed

β€Žpyproject.toml

Lines changed: 45 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ dev = [
5252
"ruff>=0.9.9",
5353
]
5454
numpy = ["numtype[numpy]"]
55-
orjson = ["orjson>=3.10.15"] # speeds up mypy cache, but is missing 3.13t wheels
55+
orjson = ["orjson>=3.10.15"] # speeds up mypy cache, but is missing 3.13t wheels
5656

5757
[tool.uv]
5858
default-groups = ["dev", "numpy", "orjson"]
@@ -82,7 +82,6 @@ packages = [
8282

8383

8484
[tool.mypy]
85-
python_version = "3.10"
8685
mypy_path = "src"
8786
explicit_package_bases = true
8887

@@ -124,7 +123,6 @@ stubPath = "src"
124123
venvPath = "."
125124
venv = ".venv"
126125
pythonPlatform = "All"
127-
pythonVersion = "3.10"
128126
typeCheckingMode = "strict"
129127

130128
deprecateTypingAliases = true
@@ -246,6 +244,50 @@ preview = true
246244
allow-dunder-method-names = ["__array__", "__array_ufunc__"]
247245

248246

247+
[tool.tox]
248+
min_version = "4"
249+
requires = ["tox-uv>=1"]
250+
env_list = ["lint", "test", "pyright", "3.13", "3.12", "3.11", "3.10"]
251+
252+
[tool.tox.env_run_base]
253+
description = "Run stubtest under {base_python}"
254+
commands = [
255+
["uv", "run", "-q", "-p={base_python}", "--active", "tool/stubtest.py", "--concise"],
256+
]
257+
258+
[tool.tox.env.pre-commit]
259+
description = "pre-commit"
260+
skip_install = true
261+
commands = [["uvx", "pre-commit", "run", "-a", "--show-diff-on-failure"]]
262+
263+
[tool.tox.env.lint]
264+
description = "lint"
265+
runner = "uv-venv-lock-runner"
266+
dependency_groups = ["dev"]
267+
commands = [
268+
["ruff", "check", "--show-fixes"],
269+
["ruff", "format", "--check"],
270+
]
271+
272+
[tool.tox.env.test]
273+
description = "pytest"
274+
runner = "uv-venv-lock-runner"
275+
dependency_groups = ["dev", "numpy"]
276+
commands = [["pytest"]]
277+
278+
[tool.tox.env.pyright]
279+
description = "basedpyright"
280+
runner = "uv-venv-lock-runner"
281+
dependency_groups = ["dev"]
282+
commands = [["basedpyright", "--threads=3"]]
283+
284+
[tool.tox.env.mypy]
285+
description = "mypy"
286+
runner = "uv-venv-lock-runner"
287+
dependency_groups = ["dev", "orjson"]
288+
commands = [["mypy", {replace = "posargs", default = ["."], extend = true}]]
289+
290+
249291
[tool.typos.default]
250292
extend-ignore-identifiers-re = ['ND|nd']
251293

β€Žsrc/numpy-stubs/__init__.pyi

Lines changed: 6 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,9 @@ from typing import (
2323
TypedDict,
2424
final,
2525
overload,
26-
runtime_checkable,
2726
type_check_only,
2827
)
29-
from typing_extensions import CapsuleType, LiteralString, Never, Protocol, Self, TypeVar, Unpack, deprecated, override
28+
from typing_extensions import Buffer, CapsuleType, LiteralString, Never, Protocol, Self, TypeVar, Unpack, deprecated, override
3029

3130
from . import (
3231
__config__ as __config__,
@@ -463,22 +462,6 @@ from .lib._utils_impl import get_include, info, show_runtime
463462
from .matrixlib import asmatrix, bmat, matrix
464463
from .version import __version__
465464

466-
@runtime_checkable
467-
class _Buffer(Protocol):
468-
def __buffer__(self, flags: int, /) -> memoryview: ...
469-
470-
if sys.version_info >= (3, 12):
471-
_SupportsBuffer: TypeAlias = _Buffer
472-
else:
473-
import array as _array
474-
import mmap as _mmap
475-
476-
from numpy import distutils as distutils # noqa: ICN003
477-
478-
_SupportsBuffer: TypeAlias = (
479-
_Buffer | bytes | bytearray | memoryview | _array.array[Any] | _mmap.mmap | NDArray[Any] | generic
480-
)
481-
482465
__all__ = [ # noqa: RUF022
483466
# __numpy_submodules__
484467
"char", "core", "ctypeslib", "dtypes", "exceptions", "f2py", "fft", "lib", "linalg", "ma", "polynomial", "random", "rec",
@@ -1561,8 +1544,8 @@ class _ArrayOrScalarCommon:
15611544
@property
15621545
def device(self) -> _Device: ...
15631546

1564-
if sys.version_info >= (3, 12):
1565-
def __buffer__(self, flags: int, /) -> memoryview: ...
1547+
# typeshed forces us to lie about this on python<3.12
1548+
def __buffer__(self, flags: int, /) -> memoryview: ...
15661549

15671550
#
15681551
@property
@@ -1993,7 +1976,7 @@ class ndarray(_ArrayOrScalarCommon, Generic[_ShapeT_co, _DTypeT_co]):
19931976
cls,
19941977
shape: _ShapeLike,
19951978
dtype: DTypeLike = float, # noqa: PYI011
1996-
buffer: _SupportsBuffer | None = None,
1979+
buffer: Buffer | None = None,
19971980
offset: CanIndex = 0,
19981981
strides: _ShapeLike | None = None,
19991982
order: _OrderKACF | None = None,
@@ -2107,7 +2090,7 @@ class ndarray(_ArrayOrScalarCommon, Generic[_ShapeT_co, _DTypeT_co]):
21072090
@overload # == 1-d
21082091
def __iter__(self: ndarray[tuple[int], dtype[_ScalarT]], /) -> Iterator[_ScalarT]: ...
21092092
@overload # >= 2-d
2110-
def __iter__(self: ndarray[tuple[int, int, *tuple[int, ...]], dtype[_ScalarT]], /) -> Iterator[NDArray[_ScalarT]]: ...
2093+
def __iter__(self: ndarray[tuple[int, int, Unpack[tuple[int, ...]]], dtype[_ScalarT]], /) -> Iterator[NDArray[_ScalarT]]: ...
21112094
@overload # ?-d
21122095
def __iter__(self, /) -> Iterator[Any]: ...
21132096

@@ -3836,9 +3819,6 @@ class generic(_ArrayOrScalarCommon, Generic[_ItemT_co]):
38363819
@abc.abstractmethod
38373820
def __init__(self, /, *args: Any, **kwargs: Any) -> None: ...
38383821

3839-
if sys.version_info >= (3, 12):
3840-
def __buffer__(self, flags: int, /) -> memoryview: ...
3841-
38423822
#
38433823
@overload
38443824
def __array__(self, dtype: None = None, /) -> ndarray[tuple[()], dtype[Self]]: ...
@@ -4083,7 +4063,7 @@ class generic(_ArrayOrScalarCommon, Generic[_ItemT_co]):
40834063
*sizes6_: CanIndex,
40844064
order: _OrderACF = "C",
40854065
copy: py_bool | None = None,
4086-
) -> ndarray[tuple[L[1], L[1], L[1], L[1], L[1], *tuple[L[1], ...]], dtype[Self]]: ...
4066+
) -> ndarray[tuple[L[1], L[1], L[1], L[1], L[1], Unpack[tuple[L[1], ...]]], dtype[Self]]: ...
40874067

40884068
#
40894069
@overload
@@ -6557,9 +6537,6 @@ class bytes_(character[bytes], bytes): # type: ignore[misc]
65576537
@overload
65586538
def __init__(self, s: str, /, encoding: str, errors: str = ...) -> None: ...
65596539

6560-
#
6561-
def __bytes__(self, /) -> bytes: ...
6562-
65636540
class str_(character[str], str): # type: ignore[misc]
65646541
@overload
65656542
def __new__(cls, value: object = ..., /) -> Self: ...

β€Žsrc/numpy-stubs/_core/_multiarray_umath.pyi

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ from typing import (
1919
overload,
2020
type_check_only,
2121
)
22-
from typing_extensions import CapsuleType, Self, TypeAliasType, TypeVar, Unpack, deprecated
22+
from typing_extensions import Buffer, CapsuleType, Self, TypeAliasType, TypeVar, Unpack, deprecated
2323

2424
import numpy as np
2525
import numpy.typing as npt
@@ -30,7 +30,6 @@ from numpy import ( # noqa: ICN003
3030
_ModeKind,
3131
_OrderCF,
3232
_OrderKACF,
33-
_SupportsBuffer,
3433
# NOTE: These implicitly re-exported ufuncs are defined in this ext-module at runtime
3534
absolute as absolute,
3635
add as add,
@@ -1165,23 +1164,23 @@ def fromiter(
11651164
#
11661165
@overload
11671166
def frombuffer(
1168-
buffer: _SupportsBuffer,
1167+
buffer: Buffer,
11691168
*,
11701169
count: SupportsIndex = -1,
11711170
offset: SupportsIndex = 0,
11721171
**kwargs: Unpack[_KwargsL],
11731172
) -> _Array[np.float64]: ...
11741173
@overload
11751174
def frombuffer(
1176-
buffer: _SupportsBuffer,
1175+
buffer: Buffer,
11771176
dtype: _DTypeLike[_ScalarT],
11781177
count: SupportsIndex = -1,
11791178
offset: SupportsIndex = 0,
11801179
**kwargs: Unpack[_KwargsL],
11811180
) -> _Array[_ScalarT]: ...
11821181
@overload
11831182
def frombuffer(
1184-
buffer: _SupportsBuffer,
1183+
buffer: Buffer,
11851184
dtype: npt.DTypeLike,
11861185
count: SupportsIndex = -1,
11871186
offset: SupportsIndex = 0,

β€Žsrc/numpy-stubs/_core/defchararray.pyi

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
from _typeshed import ConvertibleToInt
22
from typing import Any, Literal as L, SupportsIndex, TypeAlias, overload
3-
from typing_extensions import Never, Self, TypeVar, override
3+
from typing_extensions import Buffer, Never, Self, TypeVar, override
44

55
import numpy as np
6-
from numpy import _OrderKACF as _Order, _SortKind, _SupportsBuffer # noqa: ICN003
6+
from numpy import _OrderKACF as _Order, _SortKind # noqa: ICN003
77
from numpy._typing import (
88
NDArray,
99
_ArrayLikeAnyString_co as _ToAnyCharND,
@@ -158,7 +158,7 @@ class chararray(np.ndarray[_ShapeT_co, _DTypeT_co]):
158158
shape: _ToShape,
159159
itemsize: ConvertibleToInt = 1,
160160
unicode: L[False] = False,
161-
buffer: _SupportsBuffer | None = None,
161+
buffer: Buffer | None = None,
162162
offset: SupportsIndex = 0,
163163
strides: _ToShape | None = None,
164164
order: _Order = "C",
@@ -169,7 +169,7 @@ class chararray(np.ndarray[_ShapeT_co, _DTypeT_co]):
169169
shape: _ToShape,
170170
itemsize: ConvertibleToInt,
171171
unicode: L[True],
172-
buffer: _SupportsBuffer | None = None,
172+
buffer: Buffer | None = None,
173173
offset: SupportsIndex = 0,
174174
strides: _ToShape | None = None,
175175
order: _Order = "C",
@@ -181,7 +181,7 @@ class chararray(np.ndarray[_ShapeT_co, _DTypeT_co]):
181181
itemsize: ConvertibleToInt = 1,
182182
*,
183183
unicode: L[True],
184-
buffer: _SupportsBuffer | None = None,
184+
buffer: Buffer | None = None,
185185
offset: SupportsIndex = 0,
186186
strides: _ToShape | None = None,
187187
order: _Order = "C",

β€Žsrc/numpy-stubs/_core/fromnumeric.pyi

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -208,7 +208,7 @@ def reshape(
208208
copy: bool | None = None,
209209
) -> np.ndarray[tuple[int], np.dtype[_ScalarT]]: ...
210210
@overload # shape: _AnyShape
211-
def reshape(
211+
def reshape( # type: ignore[overload-overlap]
212212
a: _ToArray1_nd[_ScalarT],
213213
/,
214214
shape: _AnyShapeT,
@@ -218,7 +218,7 @@ def reshape(
218218
copy: bool | None = None,
219219
) -> Array[_ScalarT, _AnyShapeT]: ...
220220
@overload # shape: Sequence[index]
221-
def reshape(
221+
def reshape( # type: ignore[overload-overlap]
222222
a: _ToArray1_nd[_ScalarT],
223223
/,
224224
shape: Sequence[CanIndex],
@@ -486,9 +486,9 @@ def searchsorted(
486486
@overload
487487
def resize(a: _ToArray1_nd[_ScalarT], new_shape: CanIndex) -> Array_1d[_ScalarT]: ...
488488
@overload
489-
def resize(a: _ToArray1_nd[_ScalarT], new_shape: _AnyShapeT) -> Array[_ScalarT, _AnyShapeT]: ...
489+
def resize(a: _ToArray1_nd[_ScalarT], new_shape: _AnyShapeT) -> Array[_ScalarT, _AnyShapeT]: ... # type: ignore[overload-overlap]
490490
@overload
491-
def resize(a: _ToArray1_nd[_ScalarT], new_shape: Sequence[CanIndex]) -> Array[_ScalarT]: ...
491+
def resize(a: _ToArray1_nd[_ScalarT], new_shape: Sequence[CanIndex]) -> Array[_ScalarT]: ... # type: ignore[overload-overlap]
492492
@overload
493493
def resize(a: ArrayLike, new_shape: CanIndex) -> Array_1d[Any]: ...
494494
@overload

β€Žsrc/numpy-stubs/_core/records.pyi

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
from _typeshed import StrOrBytesPath
22
from collections.abc import Iterable, Sequence
33
from typing import IO, Any, ClassVar, Literal as L, Protocol, SupportsIndex, TypeAlias, overload, type_check_only
4-
from typing_extensions import TypeVar
4+
from typing_extensions import Buffer, TypeVar
55

66
import numpy as np
7-
from numpy import _ByteOrder, _OrderKACF, _SupportsBuffer # noqa: ICN003
7+
from numpy import _ByteOrder, _OrderKACF # noqa: ICN003
88
from numpy._typing import ArrayLike, DTypeLike, NDArray, _ArrayLikeVoid_co, _NestedSequence, _ShapeLike
99

1010
__all__ = [
@@ -66,7 +66,7 @@ class recarray(np.ndarray[_ShapeT_co, _DTypeT_co]):
6666
subtype,
6767
shape: _ShapeLike,
6868
dtype: None = None,
69-
buf: _SupportsBuffer | None = None,
69+
buf: Buffer | None = None,
7070
offset: SupportsIndex = 0,
7171
strides: _ShapeLike | None = None,
7272
*,
@@ -82,7 +82,7 @@ class recarray(np.ndarray[_ShapeT_co, _DTypeT_co]):
8282
subtype,
8383
shape: _ShapeLike,
8484
dtype: DTypeLike,
85-
buf: _SupportsBuffer | None = None,
85+
buf: Buffer | None = None,
8686
offset: SupportsIndex = ...,
8787
strides: _ShapeLike | None = None,
8888
formats: None = None,
@@ -158,7 +158,7 @@ def fromrecords(
158158
# exported in `numpy.rec`
159159
@overload
160160
def fromstring(
161-
datastring: _SupportsBuffer,
161+
datastring: Buffer,
162162
dtype: DTypeLike,
163163
shape: _ShapeLike | None = None,
164164
offset: int = 0,
@@ -170,7 +170,7 @@ def fromstring(
170170
) -> _RecArray[record]: ...
171171
@overload
172172
def fromstring(
173-
datastring: _SupportsBuffer,
173+
datastring: Buffer,
174174
dtype: None = None,
175175
shape: _ShapeLike | None = None,
176176
offset: int = 0,
@@ -214,7 +214,7 @@ def fromfile(
214214

215215
# exported in `numpy.rec`
216216
@overload
217-
def array(
217+
def array( # type: ignore[overload-overlap]
218218
obj: _SCT | NDArray[_SCT],
219219
dtype: None = None,
220220
shape: _ShapeLike | None = None,

β€Žsrc/numpy-stubs/_core/shape_base.pyi

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ def atleast_1d(a0: _Array1T, /) -> _Array1T: ...
3939
@overload
4040
def atleast_1d(a0: _Array1T0, a1: _Array1T1, /) -> tuple[_Array1T0, _Array1T1]: ...
4141
@overload
42-
def atleast_1d(a0: _Array1T, a1: _Array1T, /, *arys: _Array1T) -> tuple[_Array1T, ...]: ...
42+
def atleast_1d(a0: _Array1T, a1: _Array1T, /, *arys: _Array1T) -> tuple[_Array1T, ...]: ... # type: ignore[overload-overlap]
4343
@overload
4444
def atleast_1d(a0: _ArrayLike[_SCT], /) -> NDArray[_SCT]: ...
4545
@overload
@@ -59,7 +59,7 @@ def atleast_2d(a0: _Array2T, /) -> _Array2T: ...
5959
@overload
6060
def atleast_2d(a0: _Array2T0, a1: _Array2T1, /) -> tuple[_Array2T0, _Array2T1]: ...
6161
@overload
62-
def atleast_2d(a0: _Array2T, a1: _Array2T, /, *arys: _Array2T) -> tuple[_Array2T, ...]: ...
62+
def atleast_2d(a0: _Array2T, a1: _Array2T, /, *arys: _Array2T) -> tuple[_Array2T, ...]: ... # type: ignore[overload-overlap]
6363
@overload
6464
def atleast_2d(a0: _ArrayLike[_SCT], /) -> NDArray[_SCT]: ...
6565
@overload
@@ -79,7 +79,7 @@ def atleast_3d(a0: _Array3T, /) -> _Array3T: ...
7979
@overload
8080
def atleast_3d(a0: _Array3T0, a1: _Array3T1, /) -> tuple[_Array3T0, _Array3T1]: ...
8181
@overload
82-
def atleast_3d(a0: _Array3T, a1: _Array3T, /, *arys: _Array3T) -> tuple[_Array3T, ...]: ...
82+
def atleast_3d(a0: _Array3T, a1: _Array3T, /, *arys: _Array3T) -> tuple[_Array3T, ...]: ... # type: ignore[overload-overlap]
8383
@overload
8484
def atleast_3d(a0: _ArrayLike[_SCT], /) -> NDArray[_SCT]: ...
8585
@overload

β€Žsrc/numpy-stubs/_typing/_array_like.pyi

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
1-
import sys
21
from collections.abc import Callable, Collection, Sequence
32
from typing import Any, Protocol, TypeAlias, runtime_checkable
4-
from typing_extensions import TypeVar
3+
from typing_extensions import Buffer, TypeVar
54

65
import numpy as np
76
from numpy.dtypes import StringDType
@@ -10,12 +9,6 @@ from ._nbit_base import _64Bit
109
from ._nested_sequence import _NestedSequence
1110
from ._shape import _Shape
1211

13-
if sys.version_info >= (3, 12):
14-
from collections.abc import Buffer as _Buffer
15-
else:
16-
class _Buffer(Protocol):
17-
def __buffer__(self, flags: int, /) -> memoryview: ...
18-
1912
_T = TypeVar("_T")
2013
_ScalarType = TypeVar("_ScalarType", bound=np.generic)
2114
_ScalarType_co = TypeVar("_ScalarType_co", bound=np.generic, covariant=True)
@@ -55,7 +48,7 @@ _ArrayLike: TypeAlias = _SupportsArray[np.dtype[_ScalarType]] | _NestedSequence[
5548
# and another one for the rest
5649
_DualArrayLike: TypeAlias = _SupportsArray[_DType] | _T | _NestedSequence[_T] | _NestedSequence[_SupportsArray[_DType]]
5750

58-
ArrayLike: TypeAlias = _Buffer | _DualArrayLike[np.dtype[Any], complex | str | bytes]
51+
ArrayLike: TypeAlias = _DualArrayLike[np.dtype[Any], complex | str | bytes] | Buffer
5952

6053
# `ArrayLike<X>_co`: array-like objects that can be coerced into `X`
6154
# given the casting rules `same_kind`

0 commit comments

Comments
Β (0)