diff --git a/pyrightconfig.stricter.json b/pyrightconfig.stricter.json index 71fd7855e179..05e6455833a1 100644 --- a/pyrightconfig.stricter.json +++ b/pyrightconfig.stricter.json @@ -82,6 +82,7 @@ "stubs/PyMySQL", "stubs/python-crontab", "stubs/python-dateutil", + "stubs/python-http-client", "stubs/python-jose", "stubs/pywin32", "stubs/pyxdg", diff --git a/stdlib/@tests/stubtest_allowlists/darwin-py311.txt b/stdlib/@tests/stubtest_allowlists/darwin-py311.txt index 10b3f11eeeec..07cf781fa263 100644 --- a/stdlib/@tests/stubtest_allowlists/darwin-py311.txt +++ b/stdlib/@tests/stubtest_allowlists/darwin-py311.txt @@ -18,3 +18,11 @@ ossaudiodev fcntl.F_OFD_GETLK fcntl.F_OFD_SETLK fcntl.F_OFD_SETLKW + +# Incompatible changes introduced in Python 3.11.10 +# (Remove once 3.11.10 becomes available for MacOS) +email._header_value_parser.NLSET +email._header_value_parser.SPECIALSNL +email.errors.HeaderWriteError +email.utils.getaddresses +email.utils.parseaddr diff --git a/stdlib/@tests/stubtest_allowlists/py312.txt b/stdlib/@tests/stubtest_allowlists/py312.txt index 3dd734de9de7..8b02abd9621c 100644 --- a/stdlib/@tests/stubtest_allowlists/py312.txt +++ b/stdlib/@tests/stubtest_allowlists/py312.txt @@ -202,8 +202,3 @@ ctypes._endian.SIZEOF_TIME_T # Incompatible changes introduced in Python 3.12.5 concurrent.futures.__all__ -email._header_value_parser.NLSET -email._header_value_parser.SPECIALSNL -email._policybase.Policy.verify_generated_headers -email.errors.HeaderWriteError -email.policy.Policy.verify_generated_headers diff --git a/stdlib/@tests/stubtest_allowlists/py313.txt b/stdlib/@tests/stubtest_allowlists/py313.txt index 7a96b4b2b9f3..a3265d0fa587 100644 --- a/stdlib/@tests/stubtest_allowlists/py313.txt +++ b/stdlib/@tests/stubtest_allowlists/py313.txt @@ -4,8 +4,6 @@ # TODO: triage these new errors _tkinter.create -doctest.TestResults.__doc__ -doctest.TestResults.__new__ importlib.resources.Anchor importlib.resources.Resource importlib.resources.__all__ @@ -119,6 +117,8 @@ ast.ImportFrom.level # None on the class, but never None on instances builtins.property.__set_name__ # Doesn't actually exist collections\.UserList\.index # ignoring pos-or-keyword parameter dataclasses.KW_ONLY # white lies around defaults +doctest.TestResults.__match_args__ # Stubtest doesn't pick up override +doctest.TestResults._fields # Stubtest doesn't pick up override enum.auto.__init__ # The stub for enum.auto is nothing like the implementation enum.auto.value # The stub for enum.auto is nothing like the implementation functools._lru_cache_wrapper.cache_parameters # Cannot be detected statically @@ -191,9 +191,3 @@ codecs.xmlcharrefreplace_errors # To match `dict`, we lie about the runtime, but use overloads to match the correct behavior types.MappingProxyType.get - -# logging.warn() was restored after the 3.13 release candidate, which is what CI is using -logging.__all__ -logging.Logger.warn -logging.LoggerAdapter.warn -logging.warn diff --git a/stdlib/@tests/stubtest_allowlists/py38.txt b/stdlib/@tests/stubtest_allowlists/py38.txt index 7866e8c822b0..e66b499714df 100644 --- a/stdlib/@tests/stubtest_allowlists/py38.txt +++ b/stdlib/@tests/stubtest_allowlists/py38.txt @@ -250,3 +250,11 @@ tkinter.EventType.__new__ ctypes._endian.DEFAULT_MODE ctypes._endian.RTLD_GLOBAL ctypes._endian.RTLD_LOCAL + +# Incompatible changes introduced in Python 3.8.20 +# (Remove once 3.8.20 becomes available for GitHub Actions) +email._header_value_parser.NLSET +email._header_value_parser.SPECIALSNL +email.errors.HeaderWriteError +email.utils.getaddresses +email.utils.parseaddr diff --git a/stdlib/@tests/stubtest_allowlists/win32-py310.txt b/stdlib/@tests/stubtest_allowlists/win32-py310.txt index 059fb6dd3457..e9b0b2d5c29b 100644 --- a/stdlib/@tests/stubtest_allowlists/win32-py310.txt +++ b/stdlib/@tests/stubtest_allowlists/win32-py310.txt @@ -14,3 +14,11 @@ crypt nis ossaudiodev spwd + +# Incompatible changes introduced in Python 3.10.15 +# (Remove once 3.10.15 becomes available for Windows) +email._header_value_parser.NLSET +email._header_value_parser.SPECIALSNL +email.errors.HeaderWriteError +email.utils.getaddresses +email.utils.parseaddr diff --git a/stdlib/@tests/stubtest_allowlists/win32-py311.txt b/stdlib/@tests/stubtest_allowlists/win32-py311.txt index 6699bd76ad64..f6587fc54094 100644 --- a/stdlib/@tests/stubtest_allowlists/win32-py311.txt +++ b/stdlib/@tests/stubtest_allowlists/win32-py311.txt @@ -12,3 +12,11 @@ crypt nis ossaudiodev spwd + +# Incompatible changes introduced in Python 3.11.10 +# (Remove once 3.11.10 becomes available for Windows) +email._header_value_parser.NLSET +email._header_value_parser.SPECIALSNL +email.errors.HeaderWriteError +email.utils.getaddresses +email.utils.parseaddr diff --git a/stdlib/@tests/stubtest_allowlists/win32-py39.txt b/stdlib/@tests/stubtest_allowlists/win32-py39.txt index 059fb6dd3457..e1154c3e6c9b 100644 --- a/stdlib/@tests/stubtest_allowlists/win32-py39.txt +++ b/stdlib/@tests/stubtest_allowlists/win32-py39.txt @@ -14,3 +14,11 @@ crypt nis ossaudiodev spwd + +# Incompatible changes introduced in Python 3.9.20 +# (Remove once 3.9.20 becomes available for Windows) +email._header_value_parser.NLSET +email._header_value_parser.SPECIALSNL +email.errors.HeaderWriteError +email.utils.getaddresses +email.utils.parseaddr diff --git a/stdlib/distutils/dist.pyi b/stdlib/distutils/dist.pyi index 7013167dddbf..75fc7dbb388d 100644 --- a/stdlib/distutils/dist.pyi +++ b/stdlib/distutils/dist.pyi @@ -270,7 +270,7 @@ class Distribution: def has_data_files(self) -> bool: ... def is_pure(self) -> bool: ... - # Getter methods generated in __init__ + # Default getter methods generated in __init__ from self.metadata._METHOD_BASENAMES def get_name(self) -> str: ... def get_version(self) -> str: ... def get_fullname(self) -> str: ... @@ -292,3 +292,26 @@ class Distribution: def get_requires(self) -> list[str]: ... def get_provides(self) -> list[str]: ... def get_obsoletes(self) -> list[str]: ... + + # Default attributes generated in __init__ from self.display_option_names + help_commands: bool | Literal[0] + name: str | Literal[0] + version: str | Literal[0] + fullname: str | Literal[0] + author: str | Literal[0] + author_email: str | Literal[0] + maintainer: str | Literal[0] + maintainer_email: str | Literal[0] + contact: str | Literal[0] + contact_email: str | Literal[0] + url: str | Literal[0] + license: str | Literal[0] + licence: str | Literal[0] + description: str | Literal[0] + long_description: str | Literal[0] + platforms: str | list[str] | Literal[0] + classifiers: str | list[str] | Literal[0] + keywords: str | list[str] | Literal[0] + provides: list[str] | Literal[0] + requires: list[str] | Literal[0] + obsoletes: list[str] | Literal[0] diff --git a/stdlib/doctest.pyi b/stdlib/doctest.pyi index 7e334ef0c504..4380083027a6 100644 --- a/stdlib/doctest.pyi +++ b/stdlib/doctest.pyi @@ -1,9 +1,10 @@ +import sys import types import unittest from _typeshed import ExcInfo from collections.abc import Callable -from typing import Any, NamedTuple -from typing_extensions import TypeAlias +from typing import Any, ClassVar, NamedTuple +from typing_extensions import Self, TypeAlias __all__ = [ "register_optionflag", @@ -41,9 +42,22 @@ __all__ = [ "debug", ] -class TestResults(NamedTuple): - failed: int - attempted: int +# MyPy errors on conditionals within named tuples. + +if sys.version_info >= (3, 13): + class TestResults(NamedTuple): + def __new__(cls, failed: int, attempted: int, *, skipped: int = 0) -> Self: ... # type: ignore[misc] + skipped: int + failed: int + attempted: int + _fields: ClassVar = ("failed", "attempted") # type: ignore[misc] + __match_args__ = ("failed", "attempted") # type: ignore[misc] + __doc__: None # type: ignore[misc] + +else: + class TestResults(NamedTuple): + failed: int + attempted: int OPTIONFLAGS_BY_NAME: dict[str, int] @@ -134,6 +148,8 @@ class DocTestRunner: original_optionflags: int tries: int failures: int + if sys.version_info >= (3, 13): + skips: int test: DocTest def __init__(self, checker: OutputChecker | None = None, verbose: bool | None = None, optionflags: int = 0) -> None: ... def report_start(self, out: _Out, test: DocTest, example: Example) -> None: ... diff --git a/stdlib/email/_header_value_parser.pyi b/stdlib/email/_header_value_parser.pyi index 806fc84cf784..ff405a8b61d2 100644 --- a/stdlib/email/_header_value_parser.pyi +++ b/stdlib/email/_header_value_parser.pyi @@ -16,6 +16,10 @@ TOKEN_ENDS: Final[set[str]] ASPECIALS: Final[set[str]] ATTRIBUTE_ENDS: Final[set[str]] EXTENDED_ATTRIBUTE_ENDS: Final[set[str]] +# Added in Python 3.8.20, 3.9.20, 3.10.15, 3.11.10, 3.12.5 +NLSET: Final[set[str]] +# Added in Python 3.8.20, 3.9.20, 3.10.15, 3.11.10, 3.12.5 +SPECIALSNL: Final[set[str]] def quote_string(value: Any) -> str: ... diff --git a/stdlib/email/_policybase.pyi b/stdlib/email/_policybase.pyi index a3dd61a282ce..9e1f653c9d78 100644 --- a/stdlib/email/_policybase.pyi +++ b/stdlib/email/_policybase.pyi @@ -3,20 +3,9 @@ from collections.abc import Callable from email.errors import MessageDefect from email.header import Header from email.message import Message -from typing import Any from typing_extensions import Self class _PolicyBase: - def __add__(self, other: Any) -> Self: ... - def clone(self, **kw: Any) -> Self: ... - -class Policy(_PolicyBase, metaclass=ABCMeta): - max_line_length: int | None - linesep: str - cte_type: str - raise_on_defect: bool - mangle_from_: bool - message_factory: Callable[[Policy], Message] | None def __init__( self, *, @@ -24,9 +13,35 @@ class Policy(_PolicyBase, metaclass=ABCMeta): linesep: str = "\n", cte_type: str = "8bit", raise_on_defect: bool = False, - mangle_from_: bool = False, + mangle_from_: bool = ..., # default depends on sub-class message_factory: Callable[[Policy], Message] | None = None, + # Added in Python 3.8.20, 3.9.20, 3.10.15, 3.11.10, 3.12.5 + verify_generated_headers: bool = True, ) -> None: ... + def clone( + self, + *, + max_line_length: int | None = ..., + linesep: str = ..., + cte_type: str = ..., + raise_on_defect: bool = ..., + mangle_from_: bool = ..., + message_factory: Callable[[Policy], Message] | None = ..., + # Added in Python 3.8.20, 3.9.20, 3.10.15, 3.11.10, 3.12.5 + verify_generated_headers: bool = ..., + ) -> Self: ... + def __add__(self, other: Policy) -> Self: ... + +class Policy(_PolicyBase, metaclass=ABCMeta): + max_line_length: int | None + linesep: str + cte_type: str + raise_on_defect: bool + mangle_from_: bool + message_factory: Callable[[Policy], Message] | None + # Added in Python 3.8.20, 3.9.20, 3.10.15, 3.11.10, 3.12.5 + verify_generated_headers: bool + def handle_defect(self, obj: Message, defect: MessageDefect) -> None: ... def register_defect(self, obj: Message, defect: MessageDefect) -> None: ... def header_max_count(self, name: str) -> int | None: ... diff --git a/stdlib/email/errors.pyi b/stdlib/email/errors.pyi index c54f1560c9ae..f105576c5ee4 100644 --- a/stdlib/email/errors.pyi +++ b/stdlib/email/errors.pyi @@ -7,6 +7,9 @@ class BoundaryError(MessageParseError): ... class MultipartConversionError(MessageError, TypeError): ... class CharsetError(MessageError): ... +# Added in Python 3.8.20, 3.9.20, 3.10.15, 3.11.10, 3.12.5 +class HeaderWriteError(MessageError): ... + class MessageDefect(ValueError): def __init__(self, line: str | None = None) -> None: ... diff --git a/stdlib/email/utils.pyi b/stdlib/email/utils.pyi index 9dab22c18f6c..dc3eecb5ef7f 100644 --- a/stdlib/email/utils.pyi +++ b/stdlib/email/utils.pyi @@ -30,20 +30,12 @@ _PDTZ: TypeAlias = tuple[int, int, int, int, int, int, int, int, int, int | None def quote(str: str) -> str: ... def unquote(str: str) -> str: ... -if sys.version_info >= (3, 13): - def parseaddr(addr: str | list[str], *, strict: bool = True) -> tuple[str, str]: ... - -else: - def parseaddr(addr: str) -> tuple[str, str]: ... - +# `strict` parameter added in Python 3.8.20, 3.9.20, 3.10.15, 3.11.10, 3.12.5 +def parseaddr(addr: str | list[str], *, strict: bool = True) -> tuple[str, str]: ... def formataddr(pair: tuple[str | None, str], charset: str | Charset = "utf-8") -> str: ... -if sys.version_info >= (3, 13): - def getaddresses(fieldvalues: Iterable[str], *, strict: bool = True) -> list[tuple[str, str]]: ... - -else: - def getaddresses(fieldvalues: Iterable[str]) -> list[tuple[str, str]]: ... - +# `strict` parameter added in Python 3.8.20, 3.9.20, 3.10.15, 3.11.10, 3.12.5 +def getaddresses(fieldvalues: Iterable[str], *, strict: bool = True) -> list[tuple[str, str]]: ... @overload def parsedate(data: None) -> None: ... @overload diff --git a/stdlib/tempfile.pyi b/stdlib/tempfile.pyi index 62422b84eb37..0c19d56fc7a6 100644 --- a/stdlib/tempfile.pyi +++ b/stdlib/tempfile.pyi @@ -253,11 +253,11 @@ class _TemporaryFileWrapper(IO[AnyStr]): def truncate(self, size: int | None = ...) -> int: ... def writable(self) -> bool: ... @overload - def write(self: _TemporaryFileWrapper[str], s: str) -> int: ... + def write(self: _TemporaryFileWrapper[str], s: str, /) -> int: ... @overload - def write(self: _TemporaryFileWrapper[bytes], s: ReadableBuffer) -> int: ... + def write(self: _TemporaryFileWrapper[bytes], s: ReadableBuffer, /) -> int: ... @overload - def write(self, s: AnyStr) -> int: ... + def write(self, s: AnyStr, /) -> int: ... @overload def writelines(self: _TemporaryFileWrapper[str], lines: Iterable[str]) -> None: ... @overload diff --git a/stubs/docutils/docutils/nodes.pyi b/stubs/docutils/docutils/nodes.pyi index 0e5b726ad2ab..f9a15b5a936a 100644 --- a/stubs/docutils/docutils/nodes.pyi +++ b/stubs/docutils/docutils/nodes.pyi @@ -416,10 +416,15 @@ class system_message(Special, BackLinkable, PreBibliographic, Element): def __init__(self, message: str | None = None, *children: Node, **attributes) -> None: ... class pending(Special, Invisible, Element): - transform: Transform + transform: type[Transform] details: Mapping[str, Any] def __init__( - self, transform: Transform, details: Mapping[str, Any] | None = None, rawsource: str = "", *children: Node, **attributes + self, + transform: type[Transform], + details: Mapping[str, Any] | None = None, + rawsource: str = "", + *children: Node, + **attributes, ) -> None: ... class raw(Special, Inline, PreBibliographic, FixedTextElement): ... diff --git a/stubs/docutils/docutils/parsers/rst/directives/references.pyi b/stubs/docutils/docutils/parsers/rst/directives/references.pyi index 0f6820f054ea..65677b399d50 100644 --- a/stubs/docutils/docutils/parsers/rst/directives/references.pyi +++ b/stubs/docutils/docutils/parsers/rst/directives/references.pyi @@ -1,3 +1,3 @@ -from _typeshed import Incomplete +from docutils.parsers.rst import Directive -def __getattr__(name: str) -> Incomplete: ... +class TargetNotes(Directive): ... diff --git a/stubs/mysqlclient/MySQLdb/__init__.pyi b/stubs/mysqlclient/MySQLdb/__init__.pyi index 887b28de1747..ab3a60939dad 100644 --- a/stubs/mysqlclient/MySQLdb/__init__.pyi +++ b/stubs/mysqlclient/MySQLdb/__init__.pyi @@ -46,6 +46,6 @@ DATETIME: Incomplete ROWID: Incomplete def Binary(x): ... -def Connect(*args, **kwargs): ... +def Connect(*args, **kwargs) -> Connection: ... connect = Connect diff --git a/stubs/networkx/networkx/classes/reportviews.pyi b/stubs/networkx/networkx/classes/reportviews.pyi index caeeedceb27f..f6abe1194f3c 100644 --- a/stubs/networkx/networkx/classes/reportviews.pyi +++ b/stubs/networkx/networkx/classes/reportviews.pyi @@ -33,7 +33,7 @@ class NodeDataView(AbstractSet[_Node]): class DiDegreeView(Generic[_Node]): def __init__(self, G: Graph[_Node], nbunch: _NBunch[_Node] = None, weight: None | bool | str = None) -> None: ... - def __call__(self, nbunch: _NBunch[_Node] = None, weight: None | bool | str = None) -> DiDegreeView[_Node]: ... + def __call__(self, nbunch: _NBunch[_Node] = None, weight: None | bool | str = None) -> int | DiDegreeView[_Node]: ... def __getitem__(self, n: _Node) -> float: ... def __iter__(self) -> Iterator[tuple[_Node, float]]: ... def __len__(self) -> int: ... diff --git a/stubs/objgraph/METADATA.toml b/stubs/objgraph/METADATA.toml new file mode 100644 index 000000000000..2ea5dba9e6f4 --- /dev/null +++ b/stubs/objgraph/METADATA.toml @@ -0,0 +1,2 @@ +version = "3.6.*" +upstream_repository = "https://github.com/mgedmin/objgraph" diff --git a/stubs/objgraph/objgraph.pyi b/stubs/objgraph/objgraph.pyi new file mode 100644 index 000000000000..427c6e405126 --- /dev/null +++ b/stubs/objgraph/objgraph.pyi @@ -0,0 +1,91 @@ +from _typeshed import Incomplete, SupportsWrite +from collections import defaultdict +from collections.abc import Callable, Container, Iterable +from types import ModuleType +from typing import Final, Literal +from typing_extensions import TypeAlias, TypeGuard + +IS_INTERACTIVE: bool + +__author__: Final[str] +__copyright__: Final[str] +__license__: Final[str] +__version__: Final[str] +__date__: Final[str] + +# GraphViz has types, but does not include the py.typed file. +# See https://github.com/xflr6/graphviz/pull/180 +_GraphvizSource: TypeAlias = Incomplete +_Filter: TypeAlias = Callable[[object], bool] + +def count(typename: str, objects: Iterable[object] | None = None) -> int: ... +def typestats( + objects: Iterable[object] | None = None, shortnames: bool = True, filter: _Filter | None = None +) -> dict[str, int]: ... +def most_common_types( + limit: int = 10, objects: Iterable[object] | None = None, shortnames: bool = True, filter: _Filter | None = None +) -> list[tuple[str, int]]: ... +def show_most_common_types( + limit: int = 10, + objects: Iterable[object] | None = None, + shortnames: bool = True, + file: SupportsWrite[str] | None = None, + filter: _Filter | None = None, +) -> None: ... +def growth( + limit: int = 10, peak_stats: dict[str, int] = {}, shortnames: bool = True, filter: _Filter | None = None +) -> list[tuple[str, int, int]]: ... +def show_growth( + limit: int = 10, + peak_stats: dict[str, int] | None = None, + shortnames: bool = True, + file: SupportsWrite[str] | None = None, + filter: _Filter | None = None, +) -> None: ... +def get_new_ids( + skip_update: bool = False, + limit: int = 10, + sortby: Literal["old", "current", "new", "deltas"] = "deltas", + shortnames: bool | None = None, + file: SupportsWrite[str] | None = None, +) -> defaultdict[str, set[int]]: ... +def get_leaking_objects(objects: Iterable[object] | None = None) -> list[object]: ... +def by_type(typename: str, objects: Iterable[object] | None = None) -> list[object]: ... +def at(addr: int) -> object: ... +def at_addrs(address_set: Container[int]) -> list[object]: ... +def find_ref_chain(obj: object, predicate: _Filter, max_depth: int = 20, extra_ignore: Iterable[int] = ()) -> list[object]: ... +def find_backref_chain( + obj: object, predicate: _Filter, max_depth: int = 20, extra_ignore: Iterable[int] = () +) -> list[object]: ... +def show_backrefs( + objs: object, + max_depth: int = 3, + extra_ignore: Iterable[int] = (), + filter: _Filter | None = None, + too_many: int = 10, + highlight: object = None, + filename: str | None = None, + extra_info: Callable[[object], str] | None = None, + refcounts: bool = False, + shortnames: bool = True, + output: SupportsWrite[str] | None = None, + extra_node_attrs: Callable[[object], dict[str, str]] | None = None, +) -> None | _GraphvizSource: ... +def show_refs( + objs: object, + max_depth: int = 3, + extra_ignore: Iterable[int] = (), + filter: _Filter | None = None, + too_many: int = 10, + highlight: object = None, + filename: str | None = None, + extra_info: Callable[[object], str] | None = None, + refcounts: bool = False, + shortnames: bool = True, + output: SupportsWrite[str] | None = None, + extra_node_attrs: Callable[[object], dict[str, str]] | None = None, +) -> None | _GraphvizSource: ... +def show_chain( + *chains: list[object], obj: object, predicate: _Filter, max_depth: int = 20, extra_ignore: Iterable[int] = () +) -> None: ... +def is_proper_module(obj: object) -> TypeGuard[ModuleType]: ... diff --git a/stubs/pyasn1/pyasn1/compat/integer.pyi b/stubs/pyasn1/pyasn1/compat/integer.pyi index 334f28467986..ecc0e4208a9a 100644 --- a/stubs/pyasn1/pyasn1/compat/integer.pyi +++ b/stubs/pyasn1/pyasn1/compat/integer.pyi @@ -1,8 +1 @@ -from typing import Literal - -implementation: str -null: Literal[b""] - -def from_bytes(octets, signed: bool = False): ... -def to_bytes(value, signed: bool = False, length: int = 0): ... -def bitLength(number): ... +def to_bytes(value: int, signed: bool = False, length: int = 0) -> bytes: ... diff --git a/stubs/pyasn1/pyasn1/compat/octets.pyi b/stubs/pyasn1/pyasn1/compat/octets.pyi deleted file mode 100644 index 162d786b195e..000000000000 --- a/stubs/pyasn1/pyasn1/compat/octets.pyi +++ /dev/null @@ -1,18 +0,0 @@ -from typing import Literal, TypeVar - -_T = TypeVar("_T") - -ints2octs = bytes - -def int2oct(x) -> bytes: ... - -null: Literal[b""] - -def oct2int(x: _T) -> _T: ... -def octs2ints(x: _T) -> _T: ... -def str2octs(x: str) -> bytes: ... -def octs2str(x: bytes) -> str: ... -def isOctetsType(s: object) -> bool: ... -def isStringType(s: object) -> bool: ... - -ensureString = bytes diff --git a/stubs/python-datemath/METADATA.toml b/stubs/python-datemath/METADATA.toml index 519714f98de7..c66bb84067e4 100644 --- a/stubs/python-datemath/METADATA.toml +++ b/stubs/python-datemath/METADATA.toml @@ -1,8 +1,8 @@ -version = "3.0.*" +version = "3.0.1" upstream_repository = "https://github.com/nickmaccarthy/python-datemath" # Requires a version of arrow with a `py.typed` file requires = ["arrow>=1.0.1"] -partial_stub = true +obsolete_since = "3.0.2" # Released on 2024-09-11 [tool.stubtest] ignore_missing_stub = true diff --git a/stubs/python-http-client/@tests/stubtest_allowlist.txt b/stubs/python-http-client/@tests/stubtest_allowlist.txt new file mode 100644 index 000000000000..f1c4ead36ecf --- /dev/null +++ b/stubs/python-http-client/@tests/stubtest_allowlist.txt @@ -0,0 +1 @@ +python_http_client.version_file diff --git a/stubs/python-http-client/METADATA.toml b/stubs/python-http-client/METADATA.toml new file mode 100644 index 000000000000..73ce01ef67e7 --- /dev/null +++ b/stubs/python-http-client/METADATA.toml @@ -0,0 +1,2 @@ +version = "3.3.7" +upstream_repository = "https://github.com/sendgrid/python-http-client" diff --git a/stubs/python-http-client/python_http_client/__init__.pyi b/stubs/python-http-client/python_http_client/__init__.pyi new file mode 100644 index 000000000000..1c17420c7594 --- /dev/null +++ b/stubs/python-http-client/python_http_client/__init__.pyi @@ -0,0 +1,20 @@ +from typing import Final + +from .client import Client as Client +from .exceptions import ( + BadRequestsError as BadRequestsError, + ForbiddenError as ForbiddenError, + GatewayTimeoutError as GatewayTimeoutError, + HTTPError as HTTPError, + InternalServerError as InternalServerError, + MethodNotAllowedError as MethodNotAllowedError, + NotFoundError as NotFoundError, + PayloadTooLargeError as PayloadTooLargeError, + ServiceUnavailableError as ServiceUnavailableError, + TooManyRequestsError as TooManyRequestsError, + UnauthorizedError as UnauthorizedError, + UnsupportedMediaTypeError as UnsupportedMediaTypeError, +) + +dir_path: Final[str] +__version__: Final[str] diff --git a/stubs/python-http-client/python_http_client/client.pyi b/stubs/python-http-client/python_http_client/client.pyi new file mode 100644 index 000000000000..f47cebc70bc8 --- /dev/null +++ b/stubs/python-http-client/python_http_client/client.pyi @@ -0,0 +1,31 @@ +from email.message import Message +from typing import Final + +class Response: + def __init__(self, response) -> None: ... + @property + def status_code(self) -> int: ... + @property + def body(self): ... + @property + def headers(self) -> Message: ... + @property + def to_dict(self): ... + +class Client: + methods: Final[set[str]] + host: str + request_headers: dict[str, str] + append_slash: bool + timeout: int + def __init__( + self, + host: str, + request_headers: dict[str, str] | None = None, + version: int | None = None, + url_path: list[str] | None = None, + append_slash: bool = False, + timeout: int | None = None, + ) -> None: ... + def _(self, name: str) -> Client: ... + def __getattr__(self, name: str) -> Client | Response: ... diff --git a/stubs/python-http-client/python_http_client/exceptions.pyi b/stubs/python-http-client/python_http_client/exceptions.pyi new file mode 100644 index 000000000000..4852c02d679d --- /dev/null +++ b/stubs/python-http-client/python_http_client/exceptions.pyi @@ -0,0 +1,28 @@ +from email.message import Message +from typing import Final + +class HTTPError(Exception): + status_code: int + reason: str + body: str + headers: Message + def __init__(self, *args) -> None: ... + def __reduce__(self): ... + @property + def to_dict(self): ... + +class BadRequestsError(HTTPError): ... +class UnauthorizedError(HTTPError): ... +class ForbiddenError(HTTPError): ... +class NotFoundError(HTTPError): ... +class MethodNotAllowedError(HTTPError): ... +class PayloadTooLargeError(HTTPError): ... +class UnsupportedMediaTypeError(HTTPError): ... +class TooManyRequestsError(HTTPError): ... +class InternalServerError(HTTPError): ... +class ServiceUnavailableError(HTTPError): ... +class GatewayTimeoutError(HTTPError): ... + +err_dict: Final[dict[int, type[HTTPError]]] + +def handle_error(error) -> HTTPError: ... diff --git a/stubs/pytz/METADATA.toml b/stubs/pytz/METADATA.toml index 09d3be07f013..dd8ce1081fe6 100644 --- a/stubs/pytz/METADATA.toml +++ b/stubs/pytz/METADATA.toml @@ -1,3 +1,3 @@ -version = "2024.1" +version = "2024.2" # This is a mirror of https://git.launchpad.net/pytz/tree, see https://pythonhosted.org/pytz/#latest-versions upstream_repository = "https://github.com/stub42/pytz" diff --git a/stubs/regex/METADATA.toml b/stubs/regex/METADATA.toml index a7da19fc00aa..4736b6f4ff0f 100644 --- a/stubs/regex/METADATA.toml +++ b/stubs/regex/METADATA.toml @@ -1,2 +1,2 @@ -version = "2024.7.24" +version = "2024.9.11" upstream_repository = "https://github.com/mrabarnett/mrab-regex" diff --git a/stubs/requests/requests/sessions.pyi b/stubs/requests/requests/sessions.pyi index 4a32b9825252..5427c5201755 100644 --- a/stubs/requests/requests/sessions.pyi +++ b/stubs/requests/requests/sessions.pyi @@ -131,7 +131,7 @@ class Session(SessionRedirectMixin): max_redirects: int trust_env: bool cookies: RequestsCookieJar - adapters: MutableMapping[Any, Any] + adapters: MutableMapping[str, adapters.BaseAdapter] redirect_cache: RecentlyUsedContainer[Any, Any] def __init__(self) -> None: ... def __enter__(self) -> Self: ... diff --git a/stubs/setuptools/setuptools/_distutils/dist.pyi b/stubs/setuptools/setuptools/_distutils/dist.pyi index 5cc6aaf9208a..f3c2755983b3 100644 --- a/stubs/setuptools/setuptools/_distutils/dist.pyi +++ b/stubs/setuptools/setuptools/_distutils/dist.pyi @@ -128,7 +128,7 @@ class Distribution: def has_data_files(self) -> bool: ... def is_pure(self) -> bool: ... - # Getter methods generated in __init__ + # Default getter methods generated in __init__ from self.metadata._METHOD_BASENAMES def get_name(self) -> str: ... def get_version(self) -> str: ... def get_fullname(self) -> str: ... @@ -150,3 +150,26 @@ class Distribution: def get_requires(self) -> list[str]: ... def get_provides(self) -> list[str]: ... def get_obsoletes(self) -> list[str]: ... + + # Default attributes generated in __init__ from self.display_option_names + help_commands: bool | Literal[0] + name: str | Literal[0] + version: str | Literal[0] + fullname: str | Literal[0] + author: str | Literal[0] + author_email: str | Literal[0] + maintainer: str | Literal[0] + maintainer_email: str | Literal[0] + contact: str | Literal[0] + contact_email: str | Literal[0] + url: str | Literal[0] + license: str | Literal[0] + licence: str | Literal[0] + description: str | Literal[0] + long_description: str | Literal[0] + platforms: str | list[str] | Literal[0] + classifiers: str | list[str] | Literal[0] + keywords: str | list[str] | Literal[0] + provides: list[str] | Literal[0] + requires: list[str] | Literal[0] + obsoletes: list[str] | Literal[0] diff --git a/tests/_utils.py b/tests/_utils.py index fab6793f7ffe..2879ee4864e9 100644 --- a/tests/_utils.py +++ b/tests/_utils.py @@ -132,6 +132,14 @@ def parse_stdlib_versions_file() -> SupportedVersionsDict: return result +def supported_versions_for_module(module_versions: SupportedVersionsDict, module_name: str) -> tuple[VersionTuple, VersionTuple]: + while "." in module_name: + if module_name in module_versions: + return module_versions[module_name] + module_name = ".".join(module_name.split(".")[:-1]) + return module_versions[module_name] + + def _parse_version(v_str: str) -> tuple[int, int]: m = VERSION_RE.match(v_str) assert m, f"invalid version: {v_str}" diff --git a/tests/mypy_test.py b/tests/mypy_test.py index 35a7fdab1153..e1b10fc8a7c8 100755 --- a/tests/mypy_test.py +++ b/tests/mypy_test.py @@ -26,8 +26,6 @@ PYTHON_VERSION, STDLIB_PATH, TESTS_DIR, - SupportedVersionsDict, - VersionTuple, colored, get_gitignore_spec, get_mypy_req, @@ -35,6 +33,7 @@ print_error, print_success_msg, spec_matches_path, + supported_versions_for_module, venv_python, ) @@ -375,14 +374,6 @@ def stdlib_module_name_from_path(path: Path) -> str: return ".".join(parts) -def supported_versions_for_module(module_versions: SupportedVersionsDict, module_name: str) -> tuple[VersionTuple, VersionTuple]: - while "." in module_name: - if module_name in module_versions: - return module_versions[module_name] - module_name = ".".join(module_name.split(".")[:-1]) - return module_versions[module_name] - - @dataclass class TestSummary: mypy_result: MypyResult = MypyResult.SUCCESS diff --git a/tests/pytype_test.py b/tests/pytype_test.py index acd5fad6709d..715a7b52a864 100755 --- a/tests/pytype_test.py +++ b/tests/pytype_test.py @@ -30,6 +30,7 @@ from pytype.imports import typeshed # type: ignore[import] from _metadata import read_dependencies +from _utils import SupportedVersionsDict, parse_stdlib_versions_file, supported_versions_for_module TYPESHED_SUBDIRS = ["stdlib", "stubs"] TYPESHED_HOME = "TYPESHED_HOME" @@ -117,16 +118,19 @@ def check_subdirs_discoverable(subdir_paths: list[str]) -> None: def determine_files_to_test(*, paths: Sequence[str]) -> list[str]: - """Determine all files to test, checking if it's in the exclude list and which Python versions to use. + """Determine all files to test. - Returns a list of pairs of the file path and Python version as an int.""" + Checks for files in the pytype exclude list and for the stdlib VERSIONS file. + """ filenames = find_stubs_in_paths(paths) ts = typeshed.Typeshed() - skipped = set(ts.read_blacklist()) + exclude_list = set(ts.read_blacklist()) + stdlib_module_versions = parse_stdlib_versions_file() files = [] for f in sorted(filenames): - rel = _get_relative(f) - if rel in skipped: + if _get_relative(f) in exclude_list: + continue + if not _is_supported_stdlib_version(stdlib_module_versions, f): continue files.append(f) return files @@ -143,6 +147,15 @@ def find_stubs_in_paths(paths: Sequence[str]) -> list[str]: return filenames +def _is_supported_stdlib_version(module_versions: SupportedVersionsDict, filename: str) -> bool: + parts = _get_relative(filename).split(os.path.sep) + if parts[0] != "stdlib": + return True + module_name = _get_module_name(filename) + min_version, max_version = supported_versions_for_module(module_versions, module_name) + return min_version <= sys.version_info <= max_version + + def _get_pkgs_associated_with_requirement(req_name: str) -> list[str]: dist = importlib.metadata.distribution(req_name) toplevel_txt_contents = dist.read_text("top_level.txt") @@ -202,9 +215,9 @@ def run_all_tests(*, files_to_test: Sequence[str], print_stderr: bool, dry_run: errors = 0 total_tests = len(files_to_test) missing_modules = get_missing_modules(files_to_test) + python_version = f"{sys.version_info.major}.{sys.version_info.minor}" print("Testing files with pytype...") for i, f in enumerate(files_to_test): - python_version = f"{sys.version_info.major}.{sys.version_info.minor}" if dry_run: stderr = None else: