From e1043e3a3e6ad8c90ff616bba52c64d4de7727de Mon Sep 17 00:00:00 2001 From: Kumar Anirudha Date: Wed, 28 Oct 2026 00:30:38 +0530 Subject: [PATCH] Mark the Any trick with `MaybeNone` in third-party stubs - No change for type checkers, `MaybeNone` is an alias for `Any` - `regex`: match groups and `split()` results, matching stdlib `re` - `shapely`: indexed getters, `STRtree.nearest()` and `boundary` - `PyYAML`, `requests`, `pyserial`, `docutils`: attributes that can be `None` - `yt-dlp`: `read_stdin()`, matching `sys.stdin` Closes #12822 Refs #12855 --- stubs/PyYAML/yaml/nodes.pyi | 12 +++++------ stubs/docutils/docutils/nodes.pyi | 4 ++-- .../serial/tools/list_ports_common.pyi | 8 ++++---- stubs/regex/regex/_main.pyi | 20 +++++++++---------- stubs/regex/regex/_regex.pyi | 7 ++++--- stubs/requests/requests/exceptions.pyi | 6 +++--- stubs/shapely/shapely/_geometry.pyi | 15 +++++++------- stubs/shapely/shapely/constructive.pyi | 5 +++-- stubs/shapely/shapely/geometry/base.pyi | 3 ++- stubs/shapely/shapely/strtree.pyi | 7 ++++--- stubs/yt-dlp/yt_dlp/utils/_utils.pyi | 3 ++- 11 files changed, 48 insertions(+), 42 deletions(-) diff --git a/stubs/PyYAML/yaml/nodes.pyi b/stubs/PyYAML/yaml/nodes.pyi index d97634fd5fa3..8d283527e328 100644 --- a/stubs/PyYAML/yaml/nodes.pyi +++ b/stubs/PyYAML/yaml/nodes.pyi @@ -1,5 +1,5 @@ -from _typeshed import Incomplete -from typing import Any, ClassVar +from _typeshed import Incomplete, MaybeNone +from typing import ClassVar from yaml.error import Mark @@ -9,19 +9,19 @@ from yaml.error import Mark class Node: tag: str value: Incomplete - start_mark: Mark | Any - end_mark: Mark | Any + start_mark: Mark | MaybeNone + end_mark: Mark | MaybeNone def __init__(self, tag: str, value, start_mark: Mark | None, end_mark: Mark | None) -> None: ... class ScalarNode(Node): id: ClassVar[str] - style: str | Any + style: str | MaybeNone def __init__( self, tag: str, value, start_mark: Mark | None = None, end_mark: Mark | None = None, style: str | None = None ) -> None: ... class CollectionNode(Node): - flow_style: bool | Any + flow_style: bool | MaybeNone def __init__( self, tag: str, value, start_mark: Mark | None = None, end_mark: Mark | None = None, flow_style: bool | None = None ) -> None: ... diff --git a/stubs/docutils/docutils/nodes.pyi b/stubs/docutils/docutils/nodes.pyi index 56b49e584f2b..f8a06dd40a1a 100644 --- a/stubs/docutils/docutils/nodes.pyi +++ b/stubs/docutils/docutils/nodes.pyi @@ -1,6 +1,6 @@ import sys import xml.dom.minidom -from _typeshed import Incomplete, StrPath +from _typeshed import Incomplete, MaybeNone, StrPath from abc import abstractmethod from collections import Counter from collections.abc import Callable, Generator, Iterable, Iterator, Mapping, Sequence @@ -32,7 +32,7 @@ class Node: # TODO: `parent` is actually `Element | None``, but `None`` only happens rarely, # i.e. for synthetic nodes (or `document`, where it is overridden). # See https://github.com/python/typeshed/blob/main/CONTRIBUTING.md#the-any-trick - parent: Element | Any + parent: Element | MaybeNone source: str | None line: int | None diff --git a/stubs/pyserial/serial/tools/list_ports_common.pyi b/stubs/pyserial/serial/tools/list_ports_common.pyi index 465bb04062aa..7f296cbd6c04 100644 --- a/stubs/pyserial/serial/tools/list_ports_common.pyi +++ b/stubs/pyserial/serial/tools/list_ports_common.pyi @@ -1,5 +1,5 @@ +from _typeshed import MaybeNone from collections.abc import Collection -from typing import Any def numsplit(text: str) -> list[str | int]: ... @@ -11,13 +11,13 @@ class ListPortInfo: # USB specific data: the vid and pid attributes below are specific to USB devices only and # should be marked as Optional. Since the majority of the serial devices nowadays are USB # devices, typing them as Optional will be unnecessarily annoying. We type them with as - # `int | Any` so that obvious typing errors like ListPortInfo.pid + "str" are flagged. + # `int | MaybeNone` so that obvious typing errors like ListPortInfo.pid + "str" are flagged. # As desired, this will cause a false negative if the value is ever None, but may also cause # other false negatives from the Any proliferating. The other USB attributes are correctly # typed as Optional because they may be `None` even for USB devices # Original discussion at https://github.com/python/typeshed/pull/9347#issuecomment-1358245865. - vid: int | Any - pid: int | Any + vid: int | MaybeNone + pid: int | MaybeNone serial_number: str | None location: str | None manufacturer: str | None diff --git a/stubs/regex/regex/_main.pyi b/stubs/regex/regex/_main.pyi index 0e38ec3cad27..2a1d693e8ffb 100644 --- a/stubs/regex/regex/_main.pyi +++ b/stubs/regex/regex/_main.pyi @@ -1,4 +1,4 @@ -from _typeshed import ReadableBuffer, Unused +from _typeshed import MaybeNone, ReadableBuffer, Unused from collections.abc import Callable, Mapping from types import GenericAlias from typing import Any, AnyStr, Generic, Literal, TypeVar, final, overload @@ -176,7 +176,7 @@ def split( timeout: float | None = None, ignore_unused: bool = False, **kwargs: Any, -) -> list[str | Any]: ... +) -> list[str | MaybeNone]: ... @overload def split( pattern: bytes | Pattern[bytes], @@ -187,7 +187,7 @@ def split( timeout: float | None = None, ignore_unused: bool = False, **kwargs: Any, -) -> list[bytes | Any]: ... +) -> list[bytes | MaybeNone]: ... @overload def splititer( @@ -480,7 +480,7 @@ class Pattern(Generic[AnyStr]): @overload def split( self: Pattern[str], string: str, maxsplit: int = 0, concurrent: bool | None = None, timeout: float | None = None - ) -> list[str | Any]: ... + ) -> list[str | MaybeNone]: ... @overload def split( self: Pattern[bytes], @@ -488,7 +488,7 @@ class Pattern(Generic[AnyStr]): maxsplit: int = 0, concurrent: bool | None = None, timeout: float | None = None, - ) -> list[bytes | Any]: ... + ) -> list[bytes | MaybeNone]: ... @overload def splititer( @@ -692,17 +692,17 @@ class Match(Generic[AnyStr]): @overload def group(self, group: Literal[0] = 0, /) -> AnyStr: ... @overload - def group(self, group: int | str = ..., /) -> AnyStr | Any: ... + def group(self, group: int | str = ..., /) -> AnyStr | MaybeNone: ... @overload - def group(self, group1: int | str, group2: int | str, /, *groups: int | str) -> tuple[AnyStr | Any, ...]: ... + def group(self, group1: int | str, group2: int | str, /, *groups: int | str) -> tuple[AnyStr | MaybeNone, ...]: ... @overload - def groups(self, default: None = None) -> tuple[AnyStr | Any, ...]: ... + def groups(self, default: None = None) -> tuple[AnyStr | MaybeNone, ...]: ... @overload def groups(self, default: _T) -> tuple[AnyStr | _T, ...]: ... @overload - def groupdict(self, default: None = None) -> dict[str, AnyStr | Any]: ... + def groupdict(self, default: None = None) -> dict[str, AnyStr | MaybeNone]: ... @overload def groupdict(self, default: _T) -> dict[str, AnyStr | _T]: ... @@ -752,7 +752,7 @@ class Match(Generic[AnyStr]): @overload def __getitem__(self, key: Literal[0], /) -> AnyStr: ... @overload - def __getitem__(self, key: int | str, /) -> AnyStr | Any: ... + def __getitem__(self, key: int | str, /) -> AnyStr | MaybeNone: ... def __copy__(self) -> Self: ... def __deepcopy__(self, memo: Unused, /) -> Self: ... diff --git a/stubs/regex/regex/_regex.pyi b/stubs/regex/regex/_regex.pyi index c80e1662c33d..557ba9e27515 100644 --- a/stubs/regex/regex/_regex.pyi +++ b/stubs/regex/regex/_regex.pyi @@ -3,7 +3,8 @@ # For example: `Pattern` and `Match` are not exported # and are redefined in `regex.regex module. -from typing import Any, AnyStr, Generic, final +from _typeshed import MaybeNone +from typing import AnyStr, Generic, final from typing_extensions import Self from ._main import Match, Pattern @@ -13,8 +14,8 @@ class Splitter(Generic[AnyStr]): @property def pattern(self) -> Pattern[AnyStr]: ... def __iter__(self) -> Self: ... - def __next__(self) -> AnyStr | Any: ... - def split(self) -> AnyStr | Any: ... + def __next__(self) -> AnyStr | MaybeNone: ... + def split(self) -> AnyStr | MaybeNone: ... @final class Scanner(Generic[AnyStr]): diff --git a/stubs/requests/requests/exceptions.pyi b/stubs/requests/requests/exceptions.pyi index c76e78d4f52c..66591d32aadd 100644 --- a/stubs/requests/requests/exceptions.pyi +++ b/stubs/requests/requests/exceptions.pyi @@ -1,4 +1,4 @@ -from typing import Any +from _typeshed import MaybeNone from urllib3.exceptions import HTTPError as BaseHTTPError @@ -17,8 +17,8 @@ class InvalidJSONError(RequestException): ... class JSONDecodeError(InvalidJSONError, CompatJSONDecodeError): ... class HTTPError(RequestException): - request: Request | PreparedRequest | Any - response: Response | Any + request: Request | PreparedRequest | MaybeNone + response: Response | MaybeNone class ConnectionError(RequestException): ... class ProxyError(ConnectionError): ... diff --git a/stubs/shapely/shapely/_geometry.pyi b/stubs/shapely/shapely/_geometry.pyi index 7e9b64f1a71d..a72fae12865f 100644 --- a/stubs/shapely/shapely/_geometry.pyi +++ b/stubs/shapely/shapely/_geometry.pyi @@ -1,5 +1,6 @@ +from _typeshed import MaybeNone from enum import IntEnum -from typing import Any, Literal, SupportsIndex, TypeAlias, overload +from typing import Literal, SupportsIndex, TypeAlias, overload import numpy as np from numpy.typing import NDArray @@ -103,7 +104,7 @@ def get_m(point: Geometry | None, **kwargs) -> np.float64: ... def get_m(point: OptGeoArrayLikeSeq, **kwargs) -> NDArray[np.float64]: ... @overload -def get_point(geometry: LineString, index: SupportsIndex, **kwargs) -> Point | Any: ... +def get_point(geometry: LineString, index: SupportsIndex, **kwargs) -> Point | MaybeNone: ... @overload def get_point(geometry: Point | Polygon | BaseMultipartGeometry | None, index: SupportsIndex, **kwargs) -> None: ... @overload @@ -128,7 +129,7 @@ def get_exterior_ring(geometry: Geometry, **kwargs) -> LinearRing | None: ... def get_exterior_ring(geometry: OptGeoArrayLikeSeq, **kwargs) -> GeoArray: ... @overload -def get_interior_ring(geometry: Polygon, index: SupportsIndex, **kwargs) -> LinearRing | Any: ... +def get_interior_ring(geometry: Polygon, index: SupportsIndex, **kwargs) -> LinearRing | MaybeNone: ... @overload def get_interior_ring(geometry: Point | LineString | BaseMultipartGeometry | None, index: SupportsIndex, **kwargs) -> None: ... @overload @@ -144,13 +145,13 @@ def get_num_interior_rings(geometry: Geometry | None, **kwargs) -> np.int32: ... def get_num_interior_rings(geometry: OptGeoArrayLikeSeq, **kwargs) -> NDArray[np.int32]: ... @overload -def get_geometry(geometry: MultiPoint, index: SupportsIndex, **kwargs) -> Point | Any: ... +def get_geometry(geometry: MultiPoint, index: SupportsIndex, **kwargs) -> Point | MaybeNone: ... @overload -def get_geometry(geometry: MultiLineString, index: SupportsIndex, **kwargs) -> LineString | Any: ... +def get_geometry(geometry: MultiLineString, index: SupportsIndex, **kwargs) -> LineString | MaybeNone: ... @overload -def get_geometry(geometry: MultiPolygon, index: SupportsIndex, **kwargs) -> Polygon | Any: ... +def get_geometry(geometry: MultiPolygon, index: SupportsIndex, **kwargs) -> Polygon | MaybeNone: ... @overload -def get_geometry(geometry: BaseMultipartGeometry, index: SupportsIndex, **kwargs) -> BaseGeometry | Any: ... +def get_geometry(geometry: BaseMultipartGeometry, index: SupportsIndex, **kwargs) -> BaseGeometry | MaybeNone: ... @overload def get_geometry(geometry: None, index: SupportsIndex, **kwargs) -> None: ... @overload diff --git a/stubs/shapely/shapely/constructive.pyi b/stubs/shapely/shapely/constructive.pyi index e3d21dedb46d..db28acd35b30 100644 --- a/stubs/shapely/shapely/constructive.pyi +++ b/stubs/shapely/shapely/constructive.pyi @@ -1,5 +1,6 @@ +from _typeshed import MaybeNone from collections.abc import Sequence -from typing import Any, Literal, SupportsIndex, overload +from typing import Literal, SupportsIndex, overload from typing_extensions import Unpack from ._enum import ParamEnum @@ -62,7 +63,7 @@ def boundary(geometry: Polygon | MultiPolygon, **kwargs: Unpack[UFuncKwargs]) -> @overload def boundary(geometry: GeometryCollection | None, **kwargs: Unpack[UFuncKwargs]) -> None: ... @overload -def boundary(geometry: Geometry, **kwargs: Unpack[UFuncKwargs]) -> BaseMultipartGeometry | Any: ... +def boundary(geometry: Geometry, **kwargs: Unpack[UFuncKwargs]) -> BaseMultipartGeometry | MaybeNone: ... @overload def boundary(geometry: OptGeoArrayLikeSeq, **kwargs: Unpack[UFuncKwargs]) -> GeoArray: ... diff --git a/stubs/shapely/shapely/geometry/base.pyi b/stubs/shapely/shapely/geometry/base.pyi index e4138123166b..379c911c9428 100644 --- a/stubs/shapely/shapely/geometry/base.pyi +++ b/stubs/shapely/shapely/geometry/base.pyi @@ -1,3 +1,4 @@ +from _typeshed import MaybeNone from array import array from collections.abc import Iterator from typing import Any, Generic, Literal, overload @@ -111,7 +112,7 @@ class BaseGeometry(Geometry): @property def minimum_clearance(self) -> float: ... @property - def boundary(self) -> BaseMultipartGeometry | Any: ... # is None for GeometryCollection + def boundary(self) -> BaseMultipartGeometry | MaybeNone: ... # is None for GeometryCollection @property def bounds(self) -> tuple[float, float, float, float]: ... @property diff --git a/stubs/shapely/shapely/strtree.pyi b/stubs/shapely/shapely/strtree.pyi index c9728d0f687c..0dede9dbcedf 100644 --- a/stubs/shapely/shapely/strtree.pyi +++ b/stubs/shapely/shapely/strtree.pyi @@ -1,4 +1,5 @@ -from typing import Any, Literal, SupportsIndex, TypeAlias, overload +from _typeshed import MaybeNone +from typing import Literal, SupportsIndex, TypeAlias, overload import numpy as np from numpy.typing import NDArray @@ -41,9 +42,9 @@ class STRtree: # nearest may return `None` if the tree is empty, use the "Any trick" @overload - def nearest(self, geometry: Geometry) -> np.int64 | Any: ... + def nearest(self, geometry: Geometry) -> np.int64 | MaybeNone: ... @overload - def nearest(self, geometry: GeoArrayLikeSeq) -> NDArray[np.int64] | Any: ... + def nearest(self, geometry: GeoArrayLikeSeq) -> NDArray[np.int64] | MaybeNone: ... @overload # return_distance=False def query_nearest( diff --git a/stubs/yt-dlp/yt_dlp/utils/_utils.pyi b/stubs/yt-dlp/yt_dlp/utils/_utils.pyi index 93530c593a0f..6a4c6c1ad708 100644 --- a/stubs/yt-dlp/yt_dlp/utils/_utils.pyi +++ b/stubs/yt-dlp/yt_dlp/utils/_utils.pyi @@ -10,6 +10,7 @@ from _typeshed import ( ExcInfo, FileDescriptorLike, FileDescriptorOrPath, + MaybeNone, OpenBinaryMode, OpenTextMode, ReadableBuffer, @@ -590,7 +591,7 @@ def scale_thumbnails_to_max_format_width( formats: Iterable[Mapping[str, Any]], thumbnails: Iterable[Mapping[str, Any]], url_width_re: str | Pattern[str] ) -> list[dict[str, Any]]: ... def parse_http_range(range: str | None) -> tuple[int | None, int | None, int | None]: ... -def read_stdin(what: str) -> TextIO | Any: ... +def read_stdin(what: str) -> TextIO | MaybeNone: ... def determine_file_encoding(data: bytes) -> tuple[str | None, int]: ... class Config: