diff --git a/stdlib/2and3/ctypes/__init__.pyi b/stdlib/2and3/ctypes/__init__.pyi index 87707b771366..e4cd6b48fc18 100644 --- a/stdlib/2and3/ctypes/__init__.pyi +++ b/stdlib/2and3/ctypes/__init__.pyi @@ -1,5 +1,6 @@ # Stubs for ctypes +from array import array from typing import ( Any, Callable, ClassVar, Iterator, Iterable, List, Mapping, Optional, Sequence, Sized, Text, Tuple, Type, Generic, TypeVar, overload, @@ -45,6 +46,13 @@ if sys.platform == 'win32': pydll: LibraryLoader[PyDLL] = ... pythonapi: PyDLL = ... +# Anything that implements the read-write buffer interface. +# The buffer interface is defined purely on the C level, so we cannot define a normal Protocol +# for it. Instead we have to list the most common stdlib buffer classes in a Union. +_WritableBuffer = _UnionT[bytearray, memoryview, array, _CData] +# Same as _WritableBuffer, but also includes read-only buffer types (like bytes). +_ReadOnlyBuffer = _UnionT[_WritableBuffer, bytes] + class _CDataMeta(type): # By default mypy complains about the following two methods, because strictly speaking cls # might not be a Type[_CT]. However this can never actually happen, because the only class that @@ -56,9 +64,9 @@ class _CData(metaclass=_CDataMeta): _b_needsfree_: bool = ... _objects: Optional[Mapping[Any, int]] = ... @classmethod - def from_buffer(cls: Type[_CT], source: bytearray, offset: int = ...) -> _CT: ... + def from_buffer(cls: Type[_CT], source: _WritableBuffer, offset: int = ...) -> _CT: ... @classmethod - def from_buffer_copy(cls: Type[_CT], source: bytearray, offset: int = ...) -> _CT: ... + def from_buffer_copy(cls: Type[_CT], source: _ReadOnlyBuffer, offset: int = ...) -> _CT: ... @classmethod def from_address(cls: Type[_CT], address: int) -> _CT: ... @classmethod