Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Sync typeshed #15165

Merged
merged 6 commits into from
May 1, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions mypy/plugins/ctypes.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,10 @@ def _find_simplecdata_base_arg(

None is returned if _SimpleCData appears nowhere in tp's (direct or indirect) bases.
"""
if tp.type.has_base("ctypes._SimpleCData"):
if tp.type.has_base("_ctypes._SimpleCData"):
simplecdata_base = map_instance_to_supertype(
tp,
api.named_generic_type("ctypes._SimpleCData", [AnyType(TypeOfAny.special_form)]).type,
api.named_generic_type("_ctypes._SimpleCData", [AnyType(TypeOfAny.special_form)]).type,
)
assert len(simplecdata_base.args) == 1, "_SimpleCData takes exactly one type argument"
return get_proper_type(simplecdata_base.args[0])
Expand Down Expand Up @@ -88,7 +88,7 @@ def _autounboxed_cdata(tp: Type) -> ProperType:
return make_simplified_union([_autounboxed_cdata(t) for t in tp.items])
elif isinstance(tp, Instance):
for base in tp.type.bases:
if base.type.fullname == "ctypes._SimpleCData":
if base.type.fullname == "_ctypes._SimpleCData":
# If tp has _SimpleCData as a direct base class,
# the auto-unboxed type is the single type argument of the _SimpleCData type.
assert len(base.args) == 1
Expand All @@ -102,7 +102,7 @@ def _get_array_element_type(tp: Type) -> ProperType | None:
"""Get the element type of the Array type tp, or None if not specified."""
tp = get_proper_type(tp)
if isinstance(tp, Instance):
assert tp.type.fullname == "ctypes.Array"
assert tp.type.fullname == "_ctypes.Array"
if len(tp.args) == 1:
return get_proper_type(tp.args[0])
return None
Expand Down
12 changes: 6 additions & 6 deletions mypy/plugins/default.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ class DefaultPlugin(Plugin):
def get_function_hook(self, fullname: str) -> Callable[[FunctionContext], Type] | None:
from mypy.plugins import ctypes, singledispatch

if fullname == "ctypes.Array":
if fullname == "_ctypes.Array":
return ctypes.array_constructor_callback
elif fullname == "functools.singledispatch":
return singledispatch.create_singledispatch_function_callback
Expand Down Expand Up @@ -69,7 +69,7 @@ def get_method_signature_hook(
return typed_dict_pop_signature_callback
elif fullname in {n + ".update" for n in TPDICT_FB_NAMES}:
return typed_dict_update_signature_callback
elif fullname == "ctypes.Array.__setitem__":
elif fullname == "_ctypes.Array.__setitem__":
return ctypes.array_setitem_callback
elif fullname == singledispatch.SINGLEDISPATCH_CALLABLE_CALL_METHOD:
return singledispatch.call_singledispatch_function_callback
Expand All @@ -92,9 +92,9 @@ def get_method_hook(self, fullname: str) -> Callable[[MethodContext], Type] | No
return typed_dict_pop_callback
elif fullname in {n + ".__delitem__" for n in TPDICT_FB_NAMES}:
return typed_dict_delitem_callback
elif fullname == "ctypes.Array.__getitem__":
elif fullname == "_ctypes.Array.__getitem__":
return ctypes.array_getitem_callback
elif fullname == "ctypes.Array.__iter__":
elif fullname == "_ctypes.Array.__iter__":
return ctypes.array_iter_callback
elif fullname == singledispatch.SINGLEDISPATCH_REGISTER_METHOD:
return singledispatch.singledispatch_register_callback
Expand All @@ -105,9 +105,9 @@ def get_method_hook(self, fullname: str) -> Callable[[MethodContext], Type] | No
def get_attribute_hook(self, fullname: str) -> Callable[[AttributeContext], Type] | None:
from mypy.plugins import ctypes, enums

if fullname == "ctypes.Array.value":
if fullname == "_ctypes.Array.value":
return ctypes.array_value_callback
elif fullname == "ctypes.Array.raw":
elif fullname == "_ctypes.Array.raw":
return ctypes.array_raw_callback
elif fullname in enums.ENUM_NAME_ACCESS:
return enums.enum_name_callback
Expand Down
101 changes: 99 additions & 2 deletions mypy/typeshed/stdlib/_ctypes.pyi
Original file line number Diff line number Diff line change
@@ -1,6 +1,16 @@
import sys
from ctypes import _CArgObject, _PointerLike
from typing_extensions import TypeAlias
from _typeshed import ReadableBuffer, WriteableBuffer
from abc import abstractmethod
from collections.abc import Iterable, Iterator, Mapping, Sequence
from ctypes import CDLL, _CArgObject, _PointerLike
from typing import Any, Generic, TypeVar, overload
from typing_extensions import Self, TypeAlias

if sys.version_info >= (3, 9):
from types import GenericAlias

_T = TypeVar("_T")
_CT = TypeVar("_CT", bound=_CData)

FUNCFLAG_CDECL: int
FUNCFLAG_PYTHONAPI: int
Expand All @@ -27,3 +37,90 @@ if sys.platform == "win32":

FUNCFLAG_HRESULT: int
FUNCFLAG_STDCALL: int

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
# uses _CDataMeta as its metaclass is _CData. So it's safe to ignore the errors here.
def __mul__(cls: type[_CT], other: int) -> type[Array[_CT]]: ... # type: ignore[misc] # pyright: ignore[reportGeneralTypeIssues]
def __rmul__(cls: type[_CT], other: int) -> type[Array[_CT]]: ... # type: ignore[misc] # pyright: ignore[reportGeneralTypeIssues]

class _CData(metaclass=_CDataMeta):
_b_base_: int
_b_needsfree_: bool
_objects: Mapping[Any, int] | None
@classmethod
def from_buffer(cls, source: WriteableBuffer, offset: int = ...) -> Self: ...
@classmethod
def from_buffer_copy(cls, source: ReadableBuffer, offset: int = ...) -> Self: ...
@classmethod
def from_address(cls, address: int) -> Self: ...
@classmethod
def from_param(cls, obj: Any) -> Self | _CArgObject: ...
@classmethod
def in_dll(cls, library: CDLL, name: str) -> Self: ...

class _SimpleCData(Generic[_T], _CData):
value: _T
# The TypeVar can be unsolved here,
# but we can't use overloads without creating many, many mypy false-positive errors
def __init__(self, value: _T = ...) -> None: ... # pyright: ignore[reportInvalidTypeVarUse]

class _CField:
offset: int
size: int

class _StructUnionMeta(_CDataMeta):
_fields_: Sequence[tuple[str, type[_CData]] | tuple[str, type[_CData], int]]
_pack_: int
_anonymous_: Sequence[str]
def __getattr__(self, name: str) -> _CField: ...

class _StructUnionBase(_CData, metaclass=_StructUnionMeta):
def __init__(self, *args: Any, **kw: Any) -> None: ...
def __getattr__(self, name: str) -> Any: ...
def __setattr__(self, name: str, value: Any) -> None: ...

class Union(_StructUnionBase): ...
class Structure(_StructUnionBase): ...

class Array(Generic[_CT], _CData):
@property
@abstractmethod
def _length_(self) -> int: ...
@_length_.setter
def _length_(self, value: int) -> None: ...
@property
@abstractmethod
def _type_(self) -> type[_CT]: ...
@_type_.setter
def _type_(self, value: type[_CT]) -> None: ...
raw: bytes # Note: only available if _CT == c_char
value: Any # Note: bytes if _CT == c_char, str if _CT == c_wchar, unavailable otherwise
# TODO These methods cannot be annotated correctly at the moment.
# All of these "Any"s stand for the array's element type, but it's not possible to use _CT
# here, because of a special feature of ctypes.
# By default, when accessing an element of an Array[_CT], the returned object has type _CT.
# However, when _CT is a "simple type" like c_int, ctypes automatically "unboxes" the object
# and converts it to the corresponding Python primitive. For example, when accessing an element
# of an Array[c_int], a Python int object is returned, not a c_int.
# This behavior does *not* apply to subclasses of "simple types".
# If MyInt is a subclass of c_int, then accessing an element of an Array[MyInt] returns
# a MyInt, not an int.
# This special behavior is not easy to model in a stub, so for now all places where
# the array element type would belong are annotated with Any instead.
def __init__(self, *args: Any) -> None: ...
@overload
def __getitem__(self, __key: int) -> Any: ...
@overload
def __getitem__(self, __key: slice) -> list[Any]: ...
@overload
def __setitem__(self, __key: int, __value: Any) -> None: ...
@overload
def __setitem__(self, __key: slice, __value: Iterable[Any]) -> None: ...
def __iter__(self) -> Iterator[Any]: ...
# Can't inherit from Sized because the metaclass conflict between
# Sized and _CData prevents using _CDataMeta.
def __len__(self) -> int: ...
if sys.version_info >= (3, 9):
def __class_getitem__(cls, item: Any) -> GenericAlias: ...
6 changes: 5 additions & 1 deletion mypy/typeshed/stdlib/builtins.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,8 @@ class object:
def __reduce_ex__(self, __protocol: SupportsIndex) -> str | tuple[Any, ...]: ...
else:
def __reduce_ex__(self, __protocol: int) -> str | tuple[Any, ...]: ...
if sys.version_info >= (3, 11):
def __getstate__(self) -> object: ...

def __dir__(self) -> Iterable[str]: ...
def __init_subclass__(cls) -> None: ...
Expand Down Expand Up @@ -940,10 +942,12 @@ class dict(MutableMapping[_KT, _VT], Generic[_KT, _VT]):
def __init__(self, __iterable: Iterable[tuple[_KT, _VT]]) -> None: ...
@overload
def __init__(self: dict[str, _VT], __iterable: Iterable[tuple[str, _VT]], **kwargs: _VT) -> None: ...
# Next overload is for dict(string.split(sep) for string in iterable)
# Next two overloads are for dict(string.split(sep) for string in iterable)
# Cannot be Iterable[Sequence[_T]] or otherwise dict(["foo", "bar", "baz"]) is not an error
@overload
def __init__(self: dict[str, str], __iterable: Iterable[list[str]]) -> None: ...
@overload
def __init__(self: dict[bytes, bytes], __iterable: Iterable[list[bytes]]) -> None: ...
def __new__(cls, *args: Any, **kwargs: Any) -> Self: ...
def copy(self) -> dict[_KT, _VT]: ...
def keys(self) -> dict_keys[_KT, _VT]: ...
Expand Down
2 changes: 2 additions & 0 deletions mypy/typeshed/stdlib/collections/__init__.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,8 @@ class UserDict(MutableMapping[_KT, _VT], Generic[_KT, _VT]):
def __init__(self: UserDict[str, _VT], __iterable: Iterable[tuple[str, _VT]], **kwargs: _VT) -> None: ...
@overload
def __init__(self: UserDict[str, str], __iterable: Iterable[list[str]]) -> None: ...
@overload
def __init__(self: UserDict[bytes, bytes], __iterable: Iterable[list[bytes]]) -> None: ...
def __len__(self) -> int: ...
def __getitem__(self, key: _KT) -> _VT: ...
def __setitem__(self, key: _KT, item: _VT) -> None: ...
Expand Down
4 changes: 3 additions & 1 deletion mypy/typeshed/stdlib/configparser.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ __all__ = [
"ParsingError",
"MissingSectionHeaderError",
"ConfigParser",
"SafeConfigParser",
"RawConfigParser",
"Interpolation",
"BasicInterpolation",
Expand All @@ -29,6 +28,9 @@ __all__ = [
"MAX_INTERPOLATION_DEPTH",
]

if sys.version_info < (3, 12):
__all__ += ["SafeConfigParser"]

_Section: TypeAlias = Mapping[str, str]
_Parser: TypeAlias = MutableMapping[str, _Section]
_ConverterCallback: TypeAlias = Callable[[str], Any]
Expand Down
107 changes: 15 additions & 92 deletions mypy/typeshed/stdlib/ctypes/__init__.pyi
Original file line number Diff line number Diff line change
@@ -1,10 +1,20 @@
import sys
from _ctypes import RTLD_GLOBAL as RTLD_GLOBAL, RTLD_LOCAL as RTLD_LOCAL
from _typeshed import ReadableBuffer, WriteableBuffer
from abc import abstractmethod
from collections.abc import Callable, Iterable, Iterator, Mapping, Sequence
from _ctypes import (
RTLD_GLOBAL as RTLD_GLOBAL,
RTLD_LOCAL as RTLD_LOCAL,
Array as Array,
Structure as Structure,
Union as Union,
_CData as _CData,
_CDataMeta as _CDataMeta,
_CField as _CField,
_SimpleCData as _SimpleCData,
_StructUnionBase as _StructUnionBase,
_StructUnionMeta as _StructUnionMeta,
)
from collections.abc import Callable, Sequence
from typing import Any, ClassVar, Generic, TypeVar, overload
from typing_extensions import Self, TypeAlias
from typing_extensions import TypeAlias

if sys.version_info >= (3, 9):
from types import GenericAlias
Expand Down Expand Up @@ -65,28 +75,6 @@ if sys.platform == "win32":
pydll: LibraryLoader[PyDLL]
pythonapi: PyDLL

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
# uses _CDataMeta as its metaclass is _CData. So it's safe to ignore the errors here.
def __mul__(cls: type[_CT], other: int) -> type[Array[_CT]]: ... # type: ignore[misc] # pyright: ignore[reportGeneralTypeIssues]
def __rmul__(cls: type[_CT], other: int) -> type[Array[_CT]]: ... # type: ignore[misc] # pyright: ignore[reportGeneralTypeIssues]

class _CData(metaclass=_CDataMeta):
_b_base_: int
_b_needsfree_: bool
_objects: Mapping[Any, int] | None
@classmethod
def from_buffer(cls, source: WriteableBuffer, offset: int = ...) -> Self: ...
@classmethod
def from_buffer_copy(cls, source: ReadableBuffer, offset: int = ...) -> Self: ...
@classmethod
def from_address(cls, address: int) -> Self: ...
@classmethod
def from_param(cls, obj: Any) -> Self | _CArgObject: ...
@classmethod
def in_dll(cls, library: CDLL, name: str) -> Self: ...

class _CanCastTo(_CData): ...
class _PointerLike(_CanCastTo): ...

Expand Down Expand Up @@ -190,12 +178,6 @@ if sys.platform == "win32":

def wstring_at(address: _CVoidConstPLike, size: int = -1) -> str: ...

class _SimpleCData(Generic[_T], _CData):
value: _T
# The TypeVar can be unsolved here,
# but we can't use overloads without creating many, many mypy false-positive errors
def __init__(self, value: _T = ...) -> None: ... # pyright: ignore[reportInvalidTypeVarUse]

class c_byte(_SimpleCData[int]): ...

class c_char(_SimpleCData[bytes]):
Expand Down Expand Up @@ -239,64 +221,5 @@ if sys.platform == "win32":
class HRESULT(_SimpleCData[int]): ... # TODO undocumented

class py_object(_CanCastTo, _SimpleCData[_T]): ...

class _CField:
offset: int
size: int

class _StructUnionMeta(_CDataMeta):
_fields_: Sequence[tuple[str, type[_CData]] | tuple[str, type[_CData], int]]
_pack_: int
_anonymous_: Sequence[str]
def __getattr__(self, name: str) -> _CField: ...

class _StructUnionBase(_CData, metaclass=_StructUnionMeta):
def __init__(self, *args: Any, **kw: Any) -> None: ...
def __getattr__(self, name: str) -> Any: ...
def __setattr__(self, name: str, value: Any) -> None: ...

class Union(_StructUnionBase): ...
class Structure(_StructUnionBase): ...
class BigEndianStructure(Structure): ...
class LittleEndianStructure(Structure): ...

class Array(Generic[_CT], _CData):
@property
@abstractmethod
def _length_(self) -> int: ...
@_length_.setter
def _length_(self, value: int) -> None: ...
@property
@abstractmethod
def _type_(self) -> type[_CT]: ...
@_type_.setter
def _type_(self, value: type[_CT]) -> None: ...
raw: bytes # Note: only available if _CT == c_char
value: Any # Note: bytes if _CT == c_char, str if _CT == c_wchar, unavailable otherwise
# TODO These methods cannot be annotated correctly at the moment.
# All of these "Any"s stand for the array's element type, but it's not possible to use _CT
# here, because of a special feature of ctypes.
# By default, when accessing an element of an Array[_CT], the returned object has type _CT.
# However, when _CT is a "simple type" like c_int, ctypes automatically "unboxes" the object
# and converts it to the corresponding Python primitive. For example, when accessing an element
# of an Array[c_int], a Python int object is returned, not a c_int.
# This behavior does *not* apply to subclasses of "simple types".
# If MyInt is a subclass of c_int, then accessing an element of an Array[MyInt] returns
# a MyInt, not an int.
# This special behavior is not easy to model in a stub, so for now all places where
# the array element type would belong are annotated with Any instead.
def __init__(self, *args: Any) -> None: ...
@overload
def __getitem__(self, __key: int) -> Any: ...
@overload
def __getitem__(self, __key: slice) -> list[Any]: ...
@overload
def __setitem__(self, __key: int, __value: Any) -> None: ...
@overload
def __setitem__(self, __key: slice, __value: Iterable[Any]) -> None: ...
def __iter__(self) -> Iterator[Any]: ...
# Can't inherit from Sized because the metaclass conflict between
# Sized and _CData prevents using _CDataMeta.
def __len__(self) -> int: ...
if sys.version_info >= (3, 9):
def __class_getitem__(cls, item: Any) -> GenericAlias: ...
Loading