From 9b2a355accd4461ee63a6ffd9f996dfb56c4a5a0 Mon Sep 17 00:00:00 2001 From: Alba Mendez Date: Fri, 20 Mar 2026 06:35:41 +0100 Subject: [PATCH 1/4] [_cffi_backend] Improve CField, CType, _CDataBase, buffer --- stubs/cffi/_cffi_backend.pyi | 101 +++++++++++++++++++---------------- 1 file changed, 54 insertions(+), 47 deletions(-) diff --git a/stubs/cffi/_cffi_backend.pyi b/stubs/cffi/_cffi_backend.pyi index f2856bb90213..0e3b03588eb6 100644 --- a/stubs/cffi/_cffi_backend.pyi +++ b/stubs/cffi/_cffi_backend.pyi @@ -2,7 +2,7 @@ import sys import types from _typeshed import Incomplete, ReadableBuffer, WriteableBuffer from collections.abc import Callable, Hashable -from typing import Any, ClassVar, Literal, Protocol, SupportsIndex, TypeVar, final, overload, type_check_only +from typing import Any, ClassVar, Literal, Optional, Protocol, Self, SupportsIndex, TypeVar, final, overload, type_check_only from typing_extensions import Self, TypeAlias, disjoint_base _T = TypeVar("_T") @@ -27,11 +27,11 @@ if sys.platform != "win32": @final class CField: - bitshift: Incomplete - bitsize: Incomplete - flags: Incomplete - offset: Incomplete - type: Incomplete + bitshift: int + bitsize: int + flags: int + offset: int + type: 'CType' @final class CLibrary: @@ -42,18 +42,21 @@ class CLibrary: @final class CType: - abi: Incomplete - args: Incomplete - cname: Incomplete - elements: Incomplete - ellipsis: Incomplete - fields: Incomplete - item: Incomplete - kind: Incomplete - length: Incomplete - relements: Incomplete - result: Incomplete - def __dir__(self): ... + cname: str + kind: Literal['enum', 'primitive', 'pointer', 'array', 'void', 'struct', 'union', 'function'] + + abi: int + args: tuple['CType', ...] + ellipsis: bool + result: 'CType' + + item: 'CType' + length: Optional[int] + + fields: Optional[list[tuple[str, CField]]] + + relements: dict[str, int] + elements: dict[int, str] @final class Lib: @@ -62,48 +65,52 @@ class Lib: @final class _CDataBase: __name__: ClassVar[str] - def __add__(self, other, /): ... - def __bool__(self) -> bool: ... - def __call__(self, *args, **kwargs): ... - def __complex__(self) -> complex: ... - def __delitem__(self, other, /) -> None: ... def __dir__(self): ... - def __enter__(self): ... - def __eq__(self, other, /): ... + + def __enter__(self) -> Self: ... def __exit__( self, type: type[BaseException] | None, value: BaseException | None, traceback: types.TracebackType | None, / ): ... + + def __add__(self, other, /): ... + def __sub__(self, other, /): ... + def __radd__(self, other, /): ... + def __rsub__(self, other, /): ... + + def __call__(self, *args): ... + + def __hash__(self) -> int: ... + def __bool__(self) -> bool: ... + def __int__(self) -> int: ... def __float__(self) -> float: ... + def __complex__(self) -> complex: ... + + def __eq__(self, other, /): ... + def __ne__(self, other, /): ... def __ge__(self, other, /): ... - def __getitem__(self, index: SupportsIndex | slice, /): ... def __gt__(self, other, /): ... - def __hash__(self) -> int: ... - def __int__(self) -> int: ... - def __iter__(self): ... def __le__(self, other, /): ... - def __len__(self) -> int: ... def __lt__(self, other, /): ... - def __ne__(self, other, /): ... - def __radd__(self, other, /): ... - def __rsub__(self, other, /): ... + + def __iter__(self): ... + def __len__(self) -> int: ... + def __getitem__(self, index: SupportsIndex | slice, /): ... def __setitem__(self, index: SupportsIndex | slice, object, /) -> None: ... - def __sub__(self, other, /): ... @final class buffer: - __hash__: ClassVar[None] # type: ignore[assignment] - def __new__(cls, *args, **kwargs) -> Self: ... - def __buffer__(self, flags: int, /) -> memoryview: ... - def __delitem__(self, other, /) -> None: ... - def __eq__(self, other, /): ... - def __ge__(self, other, /): ... - def __getitem__(self, index, /): ... - def __gt__(self, other, /): ... - def __le__(self, other, /): ... - def __len__(self) -> int: ... - def __lt__(self, other, /): ... - def __ne__(self, other, /): ... - def __setitem__(self, index, object, /) -> None: ... + __hash__: ClassVar[None] # type: ignore[assignment] + def __new__(cls, cdata: _CDataBase, size: int = -1) -> Self: ... + def __buffer__(self, flags: int, /) -> memoryview: ... + def __eq__(self, other: ReadableBuffer, /) -> bool: ... + def __ne__(self, other: ReadableBuffer, /) -> bool: ... + def __ge__(self, other: ReadableBuffer, /) -> bool: ... + def __gt__(self, other: ReadableBuffer, /) -> bool: ... + def __le__(self, other: ReadableBuffer, /) -> bool: ... + def __lt__(self, other: ReadableBuffer, /) -> bool: ... + def __len__(self) -> int: ... + def __getitem__(self, index: SupportsIndex | slice, /) -> bytes: ... + def __setitem__(self, index: SupportsIndex | slice, value: bytes, /) -> None: ... # These aliases are to work around pyright complaints. # Pyright doesn't like it when a class object is defined as an alias From 7e0fa695a47df1da023fe68af72039984cea627f Mon Sep 17 00:00:00 2001 From: Alba Mendez Date: Fri, 20 Mar 2026 07:01:15 +0100 Subject: [PATCH 2/4] fix style issues --- stubs/cffi/_cffi_backend.pyi | 54 ++++++++++++++++++------------------ 1 file changed, 27 insertions(+), 27 deletions(-) diff --git a/stubs/cffi/_cffi_backend.pyi b/stubs/cffi/_cffi_backend.pyi index 0e3b03588eb6..910f1f399528 100644 --- a/stubs/cffi/_cffi_backend.pyi +++ b/stubs/cffi/_cffi_backend.pyi @@ -1,8 +1,8 @@ import sys import types -from _typeshed import Incomplete, ReadableBuffer, WriteableBuffer +from _typeshed import ReadableBuffer, WriteableBuffer from collections.abc import Callable, Hashable -from typing import Any, ClassVar, Literal, Optional, Protocol, Self, SupportsIndex, TypeVar, final, overload, type_check_only +from typing import Any, ClassVar, Literal, Protocol, SupportsIndex, TypeVar, final, overload, type_check_only from typing_extensions import Self, TypeAlias, disjoint_base _T = TypeVar("_T") @@ -27,11 +27,11 @@ if sys.platform != "win32": @final class CField: - bitshift: int - bitsize: int - flags: int - offset: int - type: 'CType' + bitshift: int + bitsize: int + flags: int + offset: int + type: 'CType' @final class CLibrary: @@ -45,18 +45,18 @@ class CType: cname: str kind: Literal['enum', 'primitive', 'pointer', 'array', 'void', 'struct', 'union', 'function'] - abi: int - args: tuple['CType', ...] - ellipsis: bool - result: 'CType' + abi: int + args: tuple['CType', ...] + ellipsis: bool + result: 'CType' item: 'CType' - length: Optional[int] + length: int | None - fields: Optional[list[tuple[str, CField]]] + fields: list[tuple[str, CField]] | None - relements: dict[str, int] - elements: dict[int, str] + relements: dict[str, int] + elements: dict[int, str] @final class Lib: @@ -99,18 +99,18 @@ class _CDataBase: @final class buffer: - __hash__: ClassVar[None] # type: ignore[assignment] - def __new__(cls, cdata: _CDataBase, size: int = -1) -> Self: ... - def __buffer__(self, flags: int, /) -> memoryview: ... - def __eq__(self, other: ReadableBuffer, /) -> bool: ... - def __ne__(self, other: ReadableBuffer, /) -> bool: ... - def __ge__(self, other: ReadableBuffer, /) -> bool: ... - def __gt__(self, other: ReadableBuffer, /) -> bool: ... - def __le__(self, other: ReadableBuffer, /) -> bool: ... - def __lt__(self, other: ReadableBuffer, /) -> bool: ... - def __len__(self) -> int: ... - def __getitem__(self, index: SupportsIndex | slice, /) -> bytes: ... - def __setitem__(self, index: SupportsIndex | slice, value: bytes, /) -> None: ... + __hash__: ClassVar[None] # type: ignore[assignment] + def __new__(cls, cdata: _CDataBase, size: int = -1) -> Self: ... + def __buffer__(self, flags: int, /) -> memoryview: ... + def __eq__(self, other: ReadableBuffer, /) -> bool: ... + def __ne__(self, other: ReadableBuffer, /) -> bool: ... + def __ge__(self, other: ReadableBuffer, /) -> bool: ... + def __gt__(self, other: ReadableBuffer, /) -> bool: ... + def __le__(self, other: ReadableBuffer, /) -> bool: ... + def __lt__(self, other: ReadableBuffer, /) -> bool: ... + def __len__(self) -> int: ... + def __getitem__(self, index: SupportsIndex | slice, /) -> bytes: ... + def __setitem__(self, index: SupportsIndex | slice, value: bytes, /) -> None: ... # These aliases are to work around pyright complaints. # Pyright doesn't like it when a class object is defined as an alias From 4d81041d48167cb197748b39e3e0a849940e777a Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Fri, 20 Mar 2026 06:03:16 +0000 Subject: [PATCH 3/4] [pre-commit.ci] auto fixes from pre-commit.com hooks --- stubs/cffi/_cffi_backend.pyi | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/stubs/cffi/_cffi_backend.pyi b/stubs/cffi/_cffi_backend.pyi index 910f1f399528..6d545b6ddd8e 100644 --- a/stubs/cffi/_cffi_backend.pyi +++ b/stubs/cffi/_cffi_backend.pyi @@ -31,7 +31,7 @@ class CField: bitsize: int flags: int offset: int - type: 'CType' + type: CType @final class CLibrary: @@ -43,14 +43,14 @@ class CLibrary: @final class CType: cname: str - kind: Literal['enum', 'primitive', 'pointer', 'array', 'void', 'struct', 'union', 'function'] + kind: Literal["enum", "primitive", "pointer", "array", "void", "struct", "union", "function"] abi: int - args: tuple['CType', ...] + args: tuple[CType, ...] ellipsis: bool - result: 'CType' + result: CType - item: 'CType' + item: CType length: int | None fields: list[tuple[str, CField]] | None @@ -66,32 +66,26 @@ class Lib: class _CDataBase: __name__: ClassVar[str] def __dir__(self): ... - def __enter__(self) -> Self: ... def __exit__( self, type: type[BaseException] | None, value: BaseException | None, traceback: types.TracebackType | None, / ): ... - def __add__(self, other, /): ... def __sub__(self, other, /): ... def __radd__(self, other, /): ... def __rsub__(self, other, /): ... - def __call__(self, *args): ... - def __hash__(self) -> int: ... def __bool__(self) -> bool: ... def __int__(self) -> int: ... def __float__(self) -> float: ... def __complex__(self) -> complex: ... - def __eq__(self, other, /): ... def __ne__(self, other, /): ... def __ge__(self, other, /): ... def __gt__(self, other, /): ... def __le__(self, other, /): ... def __lt__(self, other, /): ... - def __iter__(self): ... def __len__(self) -> int: ... def __getitem__(self, index: SupportsIndex | slice, /): ... From f2191b666545ae02f666a169bdebe768c3bc2c98 Mon Sep 17 00:00:00 2001 From: Alba Mendez Date: Fri, 20 Mar 2026 07:11:40 +0100 Subject: [PATCH 4/4] ignore __eq__ / __ne__ incompatible overrides the implementation really doesn't allow other objects being passed, and I see other stubs doing this, so I presume it's okay? --- stubs/cffi/_cffi_backend.pyi | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/stubs/cffi/_cffi_backend.pyi b/stubs/cffi/_cffi_backend.pyi index 6d545b6ddd8e..eb74d9ddbd0e 100644 --- a/stubs/cffi/_cffi_backend.pyi +++ b/stubs/cffi/_cffi_backend.pyi @@ -96,8 +96,8 @@ class buffer: __hash__: ClassVar[None] # type: ignore[assignment] def __new__(cls, cdata: _CDataBase, size: int = -1) -> Self: ... def __buffer__(self, flags: int, /) -> memoryview: ... - def __eq__(self, other: ReadableBuffer, /) -> bool: ... - def __ne__(self, other: ReadableBuffer, /) -> bool: ... + def __eq__(self, other: ReadableBuffer, /) -> bool: ... # type: ignore[override] + def __ne__(self, other: ReadableBuffer, /) -> bool: ... # type: ignore[override] def __ge__(self, other: ReadableBuffer, /) -> bool: ... def __gt__(self, other: ReadableBuffer, /) -> bool: ... def __le__(self, other: ReadableBuffer, /) -> bool: ...