From cd4f46d10f9b7f70ba02a328e3507c6b93b7bbc5 Mon Sep 17 00:00:00 2001 From: jorenham Date: Mon, 10 Feb 2025 23:26:15 +0100 Subject: [PATCH] =?UTF-8?q?=F0=9F=90=9B=20fix=20typing=20errors=20in=20`?= =?UTF-8?q?=5Fcore.records`?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/ci.yml | 2 + src/numpy-stubs/_core/records.pyi | 354 ++++++++++++++---------------- test/static/accept/rec.pyi | 2 +- test/static/reject/rec.pyi | 2 +- 4 files changed, 171 insertions(+), 189 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 8a9fd2a1..5ea34545 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -49,6 +49,7 @@ jobs: src/numpy-stubs/_core/_ufunc_config.pyi src/numpy-stubs/_core/arrayprint.pyi src/numpy-stubs/_core/numerictypes.pyi + src/numpy-stubs/_core/records.pyi src/numpy-stubs/_core/shape_base.pyi src/numpy-stubs/_core/strings.pyi src/numpy-stubs/_typing @@ -104,6 +105,7 @@ jobs: src/numpy-stubs/_core/_ufunc_config.pyi src/numpy-stubs/_core/arrayprint.pyi src/numpy-stubs/_core/numerictypes.pyi + src/numpy-stubs/_core/records.pyi src/numpy-stubs/_core/shape_base.pyi src/numpy-stubs/_core/strings.pyi src/numpy-stubs/_typing diff --git a/src/numpy-stubs/_core/records.pyi b/src/numpy-stubs/_core/records.pyi index c0dcfc24..da49850f 100644 --- a/src/numpy-stubs/_core/records.pyi +++ b/src/numpy-stubs/_core/records.pyi @@ -1,20 +1,10 @@ -from _typeshed import Incomplete, StrOrBytesPath +from _typeshed import StrOrBytesPath from collections.abc import Iterable, Sequence -from types import EllipsisType -from typing import Any, Literal, Protocol, SupportsIndex, TypeAlias, overload, type_check_only +from typing import IO, Any, Literal, Protocol, SupportsIndex, TypeAlias, overload, type_check_only from typing_extensions import TypeVar import numpy as np -from numpy._typing import ( - ArrayLike, - DTypeLike, - NDArray, - _ArrayLikeInt_co, - _ArrayLikeVoid_co, - _NestedSequence, - _Shape, - _ShapeLike, -) +from numpy._typing import ArrayLike, DTypeLike, NDArray, _ArrayLikeVoid_co, _NestedSequence, _ShapeLike __all__ = [ "array", @@ -30,7 +20,7 @@ __all__ = [ _T = TypeVar("_T") _SCT = TypeVar("_SCT", bound=np.generic) -_DType_co = TypeVar("_DType_co", bound=np.dtype[Any], covariant=True) +_DTypeT_co = TypeVar("_DTypeT_co", bound=np.dtype[Any], covariant=True) _ShapeT_co = TypeVar("_ShapeT_co", bound=tuple[int, ...], covariant=True) _RecArray: TypeAlias = recarray[Any, np.dtype[_SCT]] @@ -41,6 +31,21 @@ class _SupportsReadInto(Protocol): def tell(self, /) -> int: ... def readinto(self, buffer: memoryview, /) -> int: ... +### + +# exported in `numpy.rec` +class format_parser: + dtype: np.dtype[np.void] + def __init__( + self, + /, + formats: DTypeLike, + names: str | Sequence[str] | None, + titles: str | Sequence[str] | None, + aligned: bool = False, + byteorder: np._ByteOrder | None = None, + ) -> None: ... + class record(np.void): def pprint(self) -> str: ... def __getattribute__(self, attr: str, /) -> Any: ... @@ -50,274 +55,249 @@ class record(np.void): @overload def __getitem__(self, key: list[str], /) -> record: ... -class recarray(np.ndarray[_ShapeT_co, _DType_co]): - # NOTE: While not strictly mandatory, we're demanding here that arguments - # for the `format_parser`- and `dtype`-based dtype constructors are - # mutually exclusive +# exported in `numpy.rec` +class recarray(np.ndarray[_ShapeT_co, _DTypeT_co]): @overload def __new__( cls, shape: _ShapeLike, - dtype: None = ..., - buf: np._SupportsBuffer | None = ..., - offset: SupportsIndex = ..., - strides: _ShapeLike | None = ..., + dtype: None = None, + buf: np._SupportsBuffer | None = None, + offset: SupportsIndex = 0, + strides: _ShapeLike | None = None, *, formats: DTypeLike, - names: str | Sequence[str] | None = ..., - titles: str | Sequence[str] | None = ..., - byteorder: np._ByteOrder | None = ..., - aligned: bool = ..., - order: np._OrderKACF = ..., + names: str | Sequence[str] | None = None, + titles: str | Sequence[str] | None = None, + byteorder: np._ByteOrder | None = None, + aligned: bool = False, + order: np._OrderKACF = "C", ) -> _RecArray[record]: ... @overload def __new__( cls, shape: _ShapeLike, dtype: DTypeLike, - buf: np._SupportsBuffer | None = ..., + buf: np._SupportsBuffer | None = None, offset: SupportsIndex = ..., - strides: _ShapeLike | None = ..., - formats: None = ..., - names: None = ..., - titles: None = ..., - byteorder: None = ..., - aligned: Literal[False] = ..., - order: np._OrderKACF = ..., + strides: _ShapeLike | None = None, + formats: None = None, + names: None = None, + titles: None = None, + byteorder: None = None, + aligned: Literal[False] = False, + order: np._OrderKACF = "C", ) -> _RecArray[Any]: ... - def __array_finalize__(self, obj: Incomplete) -> None: ... - def __getattribute__(self, attr: str) -> Any: ... - def __setattr__(self, attr: str, val: ArrayLike) -> None: ... - @overload - def __getitem__(self, indx: (SupportsIndex | _ArrayLikeInt_co | tuple[SupportsIndex | _ArrayLikeInt_co, ...])) -> Any: ... - @overload - def __getitem__( - self: _RecArray[np.void], - indx: slice - | EllipsisType - | SupportsIndex - | _ArrayLikeInt_co - | tuple[slice | EllipsisType | _ArrayLikeInt_co | SupportsIndex | None, ...] - | None, - ) -> recarray[_Shape, _DType_co]: ... - @overload - def __getitem__( - self, - indx: slice - | EllipsisType - | SupportsIndex - | _ArrayLikeInt_co - | tuple[slice | EllipsisType | _ArrayLikeInt_co | SupportsIndex | None, ...] - | None, - ) -> np.ndarray[_Shape, _DType_co]: ... - @overload - def __getitem__(self, indx: str) -> NDArray[Any]: ... - @overload - def __getitem__(self, indx: list[str]) -> recarray[_ShapeT_co, np.dtype[record]]: ... + def __getattr__(self, attr: str, /) -> Any: ... + def __setattr__(self, attr: str, val: ArrayLike, /) -> None: ... + def __array_finalize__(self, /, obj: object) -> None: ... @overload - def field(self, attr: int | str, val: None = ...) -> Any: ... + def field(self, /, attr: int | str, val: None = None) -> Any: ... @overload - def field(self, attr: int | str, val: ArrayLike) -> None: ... + def field(self, /, attr: int | str, val: ArrayLike) -> None: ... -class format_parser: - dtype: np.dtype[np.void] - def __init__( - self, - formats: DTypeLike, - names: str | Sequence[str] | None, - titles: str | Sequence[str] | None, - aligned: bool = ..., - byteorder: np._ByteOrder | None = ..., - ) -> None: ... +# exported in `numpy.rec` +def find_duplicate(list: Iterable[_T]) -> list[_T]: ... +# exported in `numpy.rec` @overload def fromarrays( arrayList: Iterable[ArrayLike], - dtype: DTypeLike = ..., - shape: _ShapeLike | None = ..., - formats: None = ..., - names: None = ..., - titles: None = ..., - aligned: bool = ..., - byteorder: None = ..., + dtype: DTypeLike | None = None, + shape: _ShapeLike | None = None, + formats: None = None, + names: None = None, + titles: None = None, + aligned: bool = False, + byteorder: None = None, ) -> _RecArray[Any]: ... @overload def fromarrays( arrayList: Iterable[ArrayLike], - dtype: None = ..., - shape: _ShapeLike | None = ..., + dtype: None = None, + shape: _ShapeLike | None = None, *, formats: DTypeLike, - names: str | Sequence[str] | None = ..., - titles: str | Sequence[str] | None = ..., - aligned: bool = ..., - byteorder: np._ByteOrder | None = ..., + names: str | Sequence[str] | None = None, + titles: str | Sequence[str] | None = None, + aligned: bool = False, + byteorder: np._ByteOrder | None = None, ) -> _RecArray[record]: ... + +# exported in `numpy.rec` @overload def fromrecords( recList: _ArrayLikeVoid_co | tuple[Any, ...] | _NestedSequence[tuple[Any, ...]], - dtype: DTypeLike = ..., - shape: _ShapeLike | None = ..., - formats: None = ..., - names: None = ..., - titles: None = ..., - aligned: bool = ..., - byteorder: None = ..., + dtype: DTypeLike | None = None, + shape: _ShapeLike | None = None, + formats: None = None, + names: None = None, + titles: None = None, + aligned: bool = False, + byteorder: None = None, ) -> _RecArray[record]: ... @overload def fromrecords( recList: _ArrayLikeVoid_co | tuple[Any, ...] | _NestedSequence[tuple[Any, ...]], - dtype: None = ..., - shape: _ShapeLike | None = ..., + dtype: None = None, + shape: _ShapeLike | None = None, *, - formats: DTypeLike = ..., - names: str | Sequence[str] | None = ..., - titles: str | Sequence[str] | None = ..., - aligned: bool = ..., - byteorder: np._ByteOrder | None = ..., + formats: DTypeLike, + names: str | Sequence[str] | None = None, + titles: str | Sequence[str] | None = None, + aligned: bool = False, + byteorder: np._ByteOrder | None = None, ) -> _RecArray[record]: ... + +# exported in `numpy.rec` @overload def fromstring( datastring: np._SupportsBuffer, dtype: DTypeLike, - shape: _ShapeLike | None = ..., - offset: int = ..., - formats: None = ..., - names: None = ..., - titles: None = ..., - aligned: bool = ..., - byteorder: None = ..., + shape: _ShapeLike | None = None, + offset: int = 0, + formats: None = None, + names: None = None, + titles: None = None, + aligned: bool = False, + byteorder: None = None, ) -> _RecArray[record]: ... @overload def fromstring( datastring: np._SupportsBuffer, - dtype: None = ..., - shape: _ShapeLike | None = ..., - offset: int = ..., + dtype: None = None, + shape: _ShapeLike | None = None, + offset: int = 0, *, formats: DTypeLike, - names: str | Sequence[str] | None = ..., - titles: str | Sequence[str] | None = ..., - aligned: bool = ..., - byteorder: np._ByteOrder | None = ..., + names: str | Sequence[str] | None = None, + titles: str | Sequence[str] | None = None, + aligned: bool = False, + byteorder: np._ByteOrder | None = None, ) -> _RecArray[record]: ... + +# +def get_remaining_size(fd: IO[Any]) -> int: ... # undocumented + +# exported in `numpy.rec` @overload def fromfile( fd: StrOrBytesPath | _SupportsReadInto, dtype: DTypeLike, - shape: _ShapeLike | None = ..., - offset: int = ..., - formats: None = ..., - names: None = ..., - titles: None = ..., - aligned: bool = ..., - byteorder: None = ..., + shape: _ShapeLike | None = None, + offset: int = 0, + formats: None = None, + names: None = None, + titles: None = None, + aligned: bool = False, + byteorder: None = None, ) -> _RecArray[Any]: ... @overload def fromfile( fd: StrOrBytesPath | _SupportsReadInto, - dtype: None = ..., - shape: _ShapeLike | None = ..., - offset: int = ..., + dtype: None = None, + shape: _ShapeLike | None = None, + offset: int = 0, *, formats: DTypeLike, - names: str | Sequence[str] | None = ..., - titles: str | Sequence[str] | None = ..., - aligned: bool = ..., - byteorder: np._ByteOrder | None = ..., + names: str | Sequence[str] | None = None, + titles: str | Sequence[str] | None = None, + aligned: bool = False, + byteorder: np._ByteOrder | None = None, ) -> _RecArray[record]: ... + +# exported in `numpy.rec` @overload def array( obj: _SCT | NDArray[_SCT], - dtype: None = ..., - shape: _ShapeLike | None = ..., - offset: int = ..., - formats: None = ..., - names: None = ..., - titles: None = ..., - aligned: bool = ..., - byteorder: None = ..., - copy: bool = ..., + dtype: None = None, + shape: _ShapeLike | None = None, + offset: int = 0, + formats: None = None, + names: None = None, + titles: None = None, + aligned: bool = False, + byteorder: None = None, + copy: bool = True, ) -> _RecArray[_SCT]: ... @overload def array( obj: ArrayLike, dtype: DTypeLike, - shape: _ShapeLike | None = ..., - offset: int = ..., - formats: None = ..., - names: None = ..., - titles: None = ..., - aligned: bool = ..., - byteorder: None = ..., - copy: bool = ..., + shape: _ShapeLike | None = None, + offset: int = 0, + formats: None = None, + names: None = None, + titles: None = None, + aligned: bool = False, + byteorder: None = None, + copy: bool = True, ) -> _RecArray[Any]: ... @overload def array( obj: ArrayLike, - dtype: None = ..., - shape: _ShapeLike | None = ..., - offset: int = ..., + dtype: None = None, + shape: _ShapeLike | None = None, + offset: int = 0, *, formats: DTypeLike, - names: str | Sequence[str] | None = ..., - titles: str | Sequence[str] | None = ..., - aligned: bool = ..., - byteorder: np._ByteOrder | None = ..., - copy: bool = ..., + names: str | Sequence[str] | None = None, + titles: str | Sequence[str] | None = None, + aligned: bool = False, + byteorder: np._ByteOrder | None = None, + copy: bool = True, ) -> _RecArray[record]: ... @overload def array( obj: None, dtype: DTypeLike, shape: _ShapeLike, - offset: int = ..., - formats: None = ..., - names: None = ..., - titles: None = ..., - aligned: bool = ..., - byteorder: None = ..., - copy: bool = ..., + offset: int = 0, + formats: None = None, + names: None = None, + titles: None = None, + aligned: bool = False, + byteorder: None = None, + copy: bool = True, ) -> _RecArray[Any]: ... @overload def array( obj: None, - dtype: None = ..., + dtype: None = None, *, shape: _ShapeLike, - offset: int = ..., + offset: int = 0, formats: DTypeLike, - names: str | Sequence[str] | None = ..., - titles: str | Sequence[str] | None = ..., - aligned: bool = ..., - byteorder: np._ByteOrder | None = ..., - copy: bool = ..., + names: str | Sequence[str] | None = None, + titles: str | Sequence[str] | None = None, + aligned: bool = False, + byteorder: np._ByteOrder | None = None, + copy: bool = True, ) -> _RecArray[record]: ... @overload def array( obj: _SupportsReadInto, dtype: DTypeLike, - shape: _ShapeLike | None = ..., - offset: int = ..., - formats: None = ..., - names: None = ..., - titles: None = ..., - aligned: bool = ..., - byteorder: None = ..., - copy: bool = ..., + shape: _ShapeLike | None = None, + offset: int = 0, + formats: None = None, + names: None = None, + titles: None = None, + aligned: bool = False, + byteorder: None = None, + copy: bool = True, ) -> _RecArray[Any]: ... @overload def array( obj: _SupportsReadInto, - dtype: None = ..., - shape: _ShapeLike | None = ..., - offset: int = ..., + dtype: None = None, + shape: _ShapeLike | None = None, + offset: int = 0, *, formats: DTypeLike, - names: str | Sequence[str] | None = ..., - titles: str | Sequence[str] | None = ..., - aligned: bool = ..., - byteorder: np._ByteOrder | None = ..., - copy: bool = ..., + names: str | Sequence[str] | None = None, + titles: str | Sequence[str] | None = None, + aligned: bool = False, + byteorder: np._ByteOrder | None = None, + copy: bool = True, ) -> _RecArray[record]: ... -def find_duplicate(list: Iterable[_T]) -> list[_T]: ... diff --git a/test/static/accept/rec.pyi b/test/static/accept/rec.pyi index bea21ac7..455e6f45 100644 --- a/test/static/accept/rec.pyi +++ b/test/static/accept/rec.pyi @@ -6,7 +6,7 @@ import numpy as np import numpy.typing as npt AR_i8: npt.NDArray[np.int64] -REC_AR_V: np.recarray[Any, np.dtype[np.record]] +REC_AR_V: np.recarray[tuple[int, ...], np.dtype[np.record]] AR_LIST: list[npt.NDArray[np.int64]] record: np.record diff --git a/test/static/reject/rec.pyi b/test/static/reject/rec.pyi index c10e7f28..038ff4e2 100644 --- a/test/static/reject/rec.pyi +++ b/test/static/reject/rec.pyi @@ -10,7 +10,7 @@ np.rec.fromarrays( # type: ignore[call-overload] # pyright: ignore[reportCallI formats=["f8", "f8"], # pyright: ignore[reportArgumentType] ) -np.rec.fromrecords(AR_i8) # type: ignore[arg-type] # pyright: ignore[reportCallIssue,reportArgumentType] +np.rec.fromrecords(AR_i8) # type: ignore[arg-type] # pyright: ignore[reportArgumentType] np.rec.fromrecords( # type: ignore[call-overload] # pyright: ignore[reportCallIssue] [(1.5,)], dtype=[("f8", "f8")],