diff --git a/stdlib/@tests/stubtest_allowlists/common.txt b/stdlib/@tests/stubtest_allowlists/common.txt index befbc32682c5..fddf9d1d5c8e 100644 --- a/stdlib/@tests/stubtest_allowlists/common.txt +++ b/stdlib/@tests/stubtest_allowlists/common.txt @@ -464,6 +464,9 @@ unittest.runner._WritelnDecorator.write # Methods that come from __getattr__() urllib.response.addbase.write # Methods that come from __getattr__() at runtime urllib.response.addbase.writelines # Methods that come from __getattr__() at runtime +(pydoc.Doc.getdocloc)? # Runtime default is an installation-specific stdlib path. +(hashlib.__all__)? # scrypt depends on how OpenSSL was built. + _?weakref\.CallableProxyType\.__getattr__ # Should have all attributes of proxy _?weakref\.(ref|ReferenceType)\.__init__ # C implementation has incorrect signature _?weakref\.(ref|ReferenceType)\.__call__ # C function default annotation is wrong diff --git a/stdlib/@tests/stubtest_allowlists/darwin-py315.txt b/stdlib/@tests/stubtest_allowlists/darwin-py315.txt index c7a5f5c82d3e..ea531e43e90f 100644 --- a/stdlib/@tests/stubtest_allowlists/darwin-py315.txt +++ b/stdlib/@tests/stubtest_allowlists/darwin-py315.txt @@ -1,13 +1,16 @@ -# ============================================ -# TODO: Allowlist entries that should be fixed -# ============================================ - _pyrepl.fancy_termios _pyrepl.unix_console _pyrepl.unix_eventqueue +(_curses.BUTTON5_CLICKED)? +(_curses.BUTTON5_DOUBLE_CLICKED)? +(_curses.BUTTON5_PRESSED)? +(_curses.BUTTON5_RELEASED)? +(_curses.BUTTON5_TRIPLE_CLICKED)? +(_socket.SO_BINDTODEVICE)? ctypes.c_double_complex._type_ ctypes.c_float_complex._type_ ctypes.c_longdouble_complex._type_ +(errno.ENOTCAPABLE)? os.NODEV os.__all__ posix.NODEV diff --git a/stdlib/@tests/stubtest_allowlists/darwin.txt b/stdlib/@tests/stubtest_allowlists/darwin.txt index f1eb01ce62a5..3bc2b5d4212e 100644 --- a/stdlib/@tests/stubtest_allowlists/darwin.txt +++ b/stdlib/@tests/stubtest_allowlists/darwin.txt @@ -45,6 +45,7 @@ tkinter.Tk.deletefilehandler # Methods that come from __getattr__() at runtime # These entries looks like a `setup-python` bug: (dbm.gnu)? +(mmap.mmap.resize)? (_?locale.bind_textdomain_codeset)? (_?locale.bindtextdomain)? (_?locale.dcgettext)? diff --git a/stdlib/@tests/stubtest_allowlists/linux-py315.txt b/stdlib/@tests/stubtest_allowlists/linux-py315.txt index 01f7975aaa97..d788938cb21a 100644 --- a/stdlib/@tests/stubtest_allowlists/linux-py315.txt +++ b/stdlib/@tests/stubtest_allowlists/linux-py315.txt @@ -1,17 +1,20 @@ -# ============================================ -# TODO: Allowlist entries that should be fixed -# ============================================ - -# GitHub Actions' Python 3.15 Linux build currently lacks _decimal, so -# decimal falls back to _pydecimal with different runtime signatures. -decimal\..* _decimal _pyrepl.fancy_termios _pyrepl.unix_console _pyrepl.unix_eventqueue +(_socket.CAN_ISOTP_LL_OPTS)? +(_socket.CAN_ISOTP_OPTS)? +(_socket.CAN_ISOTP_RECV_FC)? +(_socket.CAN_ISOTP_RX_STMIN)? +(_socket.CAN_ISOTP_TX_STMIN)? +(_socket.SOL_CAN_ISOTP)? ctypes.c_double_complex._type_ ctypes.c_float_complex._type_ ctypes.c_longdouble_complex._type_ +# GitHub Actions' Python 3.15 Linux build currently lacks _decimal, so +# decimal falls back to _pydecimal with different runtime signatures. +decimal\..* +(mmap.mmap.madvise)? os.AT_NO_AUTOMOUNT os.AT_STATX_DONT_SYNC os.AT_STATX_FORCE_SYNC @@ -66,3 +69,12 @@ profiling.sampling.live_collector.display profiling.sampling.live_collector.trend_tracker profiling.sampling.live_collector.widgets readline.get_pre_input_hook +(resource.RLIM_SAVED_CUR)? +(resource.RLIM_SAVED_MAX)? +(socket.CAN_ISOTP_LL_OPTS)? +(socket.CAN_ISOTP_OPTS)? +(socket.CAN_ISOTP_RECV_FC)? +(socket.CAN_ISOTP_RX_STMIN)? +(socket.CAN_ISOTP_TX_STMIN)? +(socket.SOL_CAN_ISOTP)? +(socket.__all__)? diff --git a/stdlib/@tests/stubtest_allowlists/py315.txt b/stdlib/@tests/stubtest_allowlists/py315.txt index 25032c0a2219..e5b1e463bf5b 100644 --- a/stdlib/@tests/stubtest_allowlists/py315.txt +++ b/stdlib/@tests/stubtest_allowlists/py315.txt @@ -1,7 +1,14 @@ -# ============================================ -# TODO: Allowlist entries that should be fixed -# ============================================ +# ========================= +# New errors in Python 3.15 +# ========================= +(os.NODEV)? +(posix.NODEV)? +(resource.RLIMIT_NTHR)? +(resource.RLIMIT_THREADS)? +(resource.RLIMIT_UMTXP)? + +# Importlib exposes deprecated or implementation-detail runtime APIs that the stubs deliberately omit or tighten. _frozen_importlib.BuiltinImporter.load_module _frozen_importlib.FrozenImporter.load_module _frozen_importlib_external.FileFinder.discover @@ -12,35 +19,29 @@ _frozen_importlib_external.SourceFileLoader.source_to_code _frozen_importlib_external.SourceLoader.source_to_code _frozen_importlib_external._LoaderBasics.load_module _frozen_importlib_external.cache_from_source -_interpqueues.create -_interpqueues.put -_pyrepl.base_eventqueue -_pyrepl.commands -_pyrepl.completing_reader -_pyrepl.console -_pyrepl.content -_pyrepl.fancycompleter -_pyrepl.historical_reader -_pyrepl.input -_pyrepl.keymap -_pyrepl.layout -_pyrepl.main -_pyrepl.pager -_pyrepl.reader -_pyrepl.readline -_pyrepl.render -_pyrepl.simple_interact -_pyrepl.terminfo -_pyrepl.trace -_pyrepl.types -_pyrepl.utils -_pyrepl.windows_console -_pyrepl.windows_eventqueue +importlib._abc.Loader.load_module +importlib._bootstrap_external.NamespacePath +importlib.abc.InspectLoader.source_to_code +importlib.abc.MetaPathFinder.discover +importlib.abc.PathEntryFinder.discover + +# The internal implementation of the REPL on py313+; not for public consumption. +_pyrepl\..+ + +# Argument Clinic and C variadic signatures are intentionally more precise in the stubs. _struct.Struct.pack_into _struct.pack _struct.pack_into +ctypes.SetPointerType +marshal.dump +marshal.dumps +symtable.symtable + +# Context manager __exit__ signatures are runtime implementation details; the stubs follow the protocol. _thread.RLock.__exit__ _thread.lock.__exit__ + +# Undocumented private attributes on ForwardRef; same policy as py314. annotationlib.ForwardRef.__arg__ annotationlib.ForwardRef.__ast_node__ annotationlib.ForwardRef.__cell__ @@ -53,91 +54,82 @@ annotationlib.ForwardRef.__resolved_str__ annotationlib.ForwardRef.__resolved_str_cache__ annotationlib.ForwardRef.__slots__ annotationlib.ForwardRef.__stringifier_dict__ + +# Static constructor behavior remains intentionally stricter for runtime AST helpers. ast.type_param.__init__ -# base64.b64decode uses a private sentinel list as the default for parameters whose public types are bool/buffer. -base64.b64decode + +# Runtime incorrectly has `self`; same policy as py314. codecs.backslashreplace_errors codecs.ignore_errors codecs.namereplace_errors codecs.replace_errors codecs.strict_errors codecs.xmlcharrefreplace_errors -collections.Counter.__ixor__ -collections.Counter.__xor__ + +# Decorator/runtime sentinel implementation details; same policy as py314. concurrent.interpreters._crossinterp.UNBOUND_ERROR concurrent.interpreters._crossinterp.UNBOUND_REMOVE concurrent.interpreters._crossinterp.UnboundItem.singleton -concurrent.interpreters._crossinterp.classonly -concurrent.interpreters._crossinterp.classonly.__class_getitem__ -concurrent.interpreters._crossinterp.classonly.__func__ -concurrent.interpreters._crossinterp.classonly.__get__ -concurrent.interpreters._crossinterp.classonly.__init__ -concurrent.interpreters._crossinterp.classonly.__isabstractmethod__ -concurrent.interpreters._crossinterp.classonly.__set_name__ -concurrent.interpreters._crossinterp.classonly.__wrapped__ +concurrent.interpreters._crossinterp.classonly.* + +# object() sentinels and overloaded helper defaults are modeled more usefully in the stubs. copy.deepcopy -ctypes.SetPointerType -dataclasses._MISSING_TYPE dataclasses.MISSING +dataclasses._MISSING_TYPE dataclasses.field + +# Runtime defaults/sentinels are not expressible without losing useful static signatures. doctest.DocTestRunner.report_skip -enum.__all__ -enum.auto.__init__ -enum.auto.value functools.partialmethod.__new__ -genericpath.ALL_BUT_LAST -genericpath.__all__ -genericpath.commonprefix -genericpath.getatime -genericpath.getctime -genericpath.getmtime -genericpath.getsize -genericpath.samefile -genericpath.samestat -glob.glob0 -glob.glob1 gzip.compress -http.HTTPMethod.description -http.client.HTTPConnection.__init__ -http.client.HTTPSConnection.__init__ -http.server.CGIHTTPRequestHandler -http.server.SimpleHTTPRequestHandler.__init__ -http.server.SimpleHTTPRequestHandler.default_content_type -http.server.__all__ -importlib._abc.Loader.load_module -importlib._bootstrap_external.NamespacePath -importlib.abc.InspectLoader.source_to_code -importlib.abc.MetaPathFinder.discover -importlib.abc.PathEntryFinder.discover -importlib.metadata.DeprecatedNonAbstract -importlib.metadata.Distribution -importlib.metadata.MetadataNotFound -importlib.metadata.PathDistribution -importlib.metadata.__all__ importlib.resources._common.files importlib.resources._common.package_to_anchor -importlib.resources.abc.Traversable.open -importlib.resources.abc.Traversable.read_text -inspect._ParameterKind.description -inspect.getdoc inspect.getfullargspec -io.Reader.__class_getitem__ -io.Reader.read -io.Writer.__class_getitem__ -io.Writer.write +multiprocessing.context.BaseContext.set_forkserver_preload +multiprocessing.forkserver.ForkServer.set_forkserver_preload +pdb.Pdb.print_stack_entry +pkgutil.resolve_name +pprint.PrettyPrinter.__init__ +pprint.pformat +pprint.pprint +site.addsitedir +site.addsitepackages +site.addusersitepackages +site.process_startup_files + +# The stub for enum.auto is nothing like the implementation; same policy as py314. +enum.__all__ +enum.auto.__init__ +enum.auto.value + +# Complex ctypes scalar runtime metadata is not useful for static checking. +(ctypes.c_double_complex._type_)? +(ctypes.c_float_complex._type_)? +(ctypes.c_longdouble_complex._type_)? + +# Runtime metadata/export lists changed, but the stubs expose the supported API surface. +http.HTTPMethod.description +inspect._ParameterKind.description +(os.__all__)? +sys.last_exc +threading.Condition.locked +typing_extensions.__all__ +xml.etree.ElementTree.__all__ + +# Problematic protocol signatures at runtime; same policy as py314. +importlib.resources.abc.Traversable.open +(io|typing_extensions)\.Reader\.__class_getitem__ +(io|typing_extensions)\.Reader\.read +(io|typing_extensions)\.Writer\.__class_getitem__ +(io|typing_extensions)\.Writer\.write + +# Runtime context-manager/proxy wrappers are loose; stubs retain the useful public protocol. mailbox.Mailbox.__enter__ mailbox.Mailbox.__exit__ mailbox._ProxyFile.__class_getitem__ -marshal.dump -marshal.dumps -math.fmax -math.fmin -math.isnormal -math.issubnormal -math.signbit -multiprocessing.context.BaseContext.set_forkserver_preload -multiprocessing.forkserver.ForkServer.set_forkserver_preload -multiprocessing.forkserver.main + +# These multiprocessing proxy methods have *args, **kwargs signatures at runtime, +# but have more precise signatures in the stubs; same policy as py314. multiprocessing.managers.BaseListProxy.clear multiprocessing.managers.BaseListProxy.copy multiprocessing.managers._BaseDictProxy.__iter__ @@ -155,103 +147,43 @@ multiprocessing.managers._BaseSetProxy.clear multiprocessing.managers._BaseSetProxy.copy multiprocessing.managers._BaseSetProxy.pop multiprocessing.process.BaseProcess.__init__ -ntpath.ALL_BUT_LAST -ntpath.__all__ -ntpath.realpath -os.path.ALL_BUT_LAST -os.path.__all__ -pathlib.PurePath.__vfspath__ -pathlib.PurePath.is_reserved -pdb.Pdb.print_stack_entry -pkgutil.resolve_name -posixpath.ALL_BUT_LAST -posixpath.__all__ -posixpath.basename -posixpath.dirname -posixpath.isabs -posixpath.normcase -posixpath.realpath -posixpath.split -posixpath.splitdrive -posixpath.splitext -posixpath.splitroot -pprint.PrettyPrinter.__init__ -pprint.pformat -pprint.pprint -profiling -profiling.sampling -profiling.sampling.binary_collector -profiling.sampling.binary_reader -profiling.sampling.cli -profiling.sampling.collector -profiling.sampling.constants -profiling.sampling.dump -profiling.sampling.errors -profiling.sampling.gecko_collector -profiling.sampling.heatmap_collector -profiling.sampling.jsonl_collector -profiling.sampling.module_utils -profiling.sampling.opcode_utils -profiling.sampling.pstats_collector -profiling.sampling.sample -profiling.sampling.stack_collector -profiling.sampling.string_table -profiling.tracing -pydoc.Doc.STDLIB_DIR -pydoc.Doc.getdocloc -site.addsitedir -site.addsitepackages -site.addusersitepackages -site.process_startup_files -sre_compile -sre_constants -sre_parse -symtable.symtable + +# Runtime path APIs include implementation hooks/deprecated behavior that the stubs intentionally hide or tighten. +(ntpath.realpath)? + +# base64.b64decode uses a private sentinel list as the default for parameters whose public types are bool/buffer. +base64.b64decode + +# New profiling package internals are not part of the typed public surface. +profiling\.sampling\..+ + +# readline hook availability is build-dependent. +(readline.get_pre_input_hook)? + +# Doesn't really exist, or is hidden behind implementation guards; see comments in the sys stub. sys.__jit sys._monitoring -sys.abi_info -sys.get_lazy_imports -sys.get_lazy_imports_filter -sys.last_exc -sys.lazy_modules -sys.set_lazy_imports -sys.set_lazy_imports_filter -threading.Condition.locked -threading.__all__ -threading.concurrent_tee -threading.serialize_iterator -threading.synchronized_iterator -timeit.Timer.autorange + +# Tkinter runtime mixins expose Tcl container behavior that is not part of the typed public API. tkinter.Grid.content -tkinter.Grid.grid_content tkinter.Image.__iter__ tkinter.Misc.__iter__ tkinter.Misc.content -tkinter.Misc.grid_content -tkinter.Misc.pack_content -tkinter.Misc.place_content tkinter.Pack.content -tkinter.Pack.pack_content tkinter.Place.content -tkinter.Place.place_content -tkinter.Text.search -tkinter.Text.search_all tkinter.font.Font.__iter__ tkinter.simpledialog.__all__ -types.AsyncGeneratorType.ag_state -types.CodeType.co_lnotab -types.CoroutineType.cr_state -types.FrameLocalsProxyType -types.GeneratorType.gi_state -types.LazyImportType + +# Runtime attribute mutability differs from the useful static model; same policy as py314. types.MappingProxyType.get types.SimpleNamespace.__delattr__ types.SimpleNamespace.__setattr__ + +# Super-special typing primitives and runtime aliases; same policy as py314. types.UnionType.__class_getitem__ types.UnionType.__mro_entries__ types.UnionType.__name__ types.UnionType.__qualname__ -types.__all__ typing.LiteralString typing.NewType.__mro_entries__ typing.ParamSpec.__mro_entries__ @@ -263,17 +195,4 @@ typing.TypeVar.__mro_entries__ typing.TypeVarTuple.__mro_entries__ typing.Union typing._SpecialForm.__mro_entries__ -typing_extensions.__all__ typing_extensions.Protocol -urllib.parse._DefragResultBase.geturl -urllib.parse._ParseResultBase.geturl -urllib.parse._SplitResultBase.geturl -urllib.parse.urldefrag -urllib.parse.urlparse -urllib.parse.urlsplit -urllib.parse.urlunparse -urllib.parse.urlunsplit -xml.etree.ElementTree.__all__ -xml.is_valid_name -xml.utils -zipimport.zipimporter.load_module diff --git a/stdlib/@tests/stubtest_allowlists/win32-py315.txt b/stdlib/@tests/stubtest_allowlists/win32-py315.txt index 1e9f5fdb0f3c..5273a6e89368 100644 --- a/stdlib/@tests/stubtest_allowlists/win32-py315.txt +++ b/stdlib/@tests/stubtest_allowlists/win32-py315.txt @@ -1,7 +1,4 @@ -# ============================================ -# TODO: Allowlist entries that should be fixed -# ============================================ - +(_decimal.SPEC_VERSION)? _winapi.DeregisterEventSource _winapi.EVENTLOG_AUDIT_FAILURE _winapi.EVENTLOG_AUDIT_SUCCESS @@ -13,4 +10,5 @@ _winapi.GetOEMCP _winapi.RegisterEventSource _winapi.ReportEvent asyncio.windows_events.IocpProactor.finish_socket_func +(decimal.SPEC_VERSION)? winreg.DeleteTree diff --git a/stdlib/VERSIONS b/stdlib/VERSIONS index 5487195b7165..fffe1a8d8f66 100644 --- a/stdlib/VERSIONS +++ b/stdlib/VERSIONS @@ -208,6 +208,7 @@ mailbox: 3.0- mailcap: 3.0-3.12 marshal: 3.0- math: 3.0- +math.integer: 3.15- mimetypes: 3.0- mmap: 3.0- modulefinder: 3.0- @@ -242,6 +243,9 @@ posix: 3.0- posixpath: 3.0- pprint: 3.0- profile: 3.0- +profiling: 3.15- +profiling.sampling: 3.15- +profiling.tracing: 3.15- pstats: 3.0- pty: 3.0- pwd: 3.0- @@ -276,9 +280,9 @@ socket: 3.0- socketserver: 3.0- spwd: 3.0-3.12 sqlite3: 3.0- -sre_compile: 3.0- -sre_constants: 3.0- -sre_parse: 3.0- +sre_compile: 3.0-3.14 +sre_constants: 3.0-3.14 +sre_parse: 3.0-3.14 ssl: 3.0- stat: 3.0- statistics: 3.4- @@ -335,6 +339,7 @@ wsgiref: 3.0- wsgiref.types: 3.11- xdrlib: 3.0-3.12 xml: 3.0- +xml.utils: 3.15- xmlrpc: 3.0- xxlimited: 3.2- zipapp: 3.5- diff --git a/stdlib/_interpqueues.pyi b/stdlib/_interpqueues.pyi index 5586b9bd7b20..94605e4c0dda 100644 --- a/stdlib/_interpqueues.pyi +++ b/stdlib/_interpqueues.pyi @@ -1,3 +1,4 @@ +import sys from typing import Any, Literal, SupportsIndex, TypeAlias _UnboundOp: TypeAlias = Literal[1, 2, 3] @@ -6,7 +7,13 @@ class QueueError(RuntimeError): ... class QueueNotFoundError(QueueError): ... def bind(qid: SupportsIndex) -> None: ... -def create(maxsize: SupportsIndex, fmt: SupportsIndex, unboundop: _UnboundOp) -> int: ... + +if sys.version_info >= (3, 15): + def create(maxsize: SupportsIndex, unboundop: SupportsIndex = -1, fallback: SupportsIndex = -1) -> int: ... + +else: + def create(maxsize: SupportsIndex, fmt: SupportsIndex, unboundop: _UnboundOp) -> int: ... + def destroy(qid: SupportsIndex) -> None: ... def get(qid: SupportsIndex) -> tuple[Any, int, _UnboundOp | None]: ... def get_count(qid: SupportsIndex) -> int: ... @@ -14,5 +21,11 @@ def get_maxsize(qid: SupportsIndex) -> int: ... def get_queue_defaults(qid: SupportsIndex) -> tuple[int, _UnboundOp]: ... def is_full(qid: SupportsIndex) -> bool: ... def list_all() -> list[tuple[int, int, _UnboundOp]]: ... -def put(qid: SupportsIndex, obj: Any, fmt: SupportsIndex, unboundop: _UnboundOp) -> None: ... + +if sys.version_info >= (3, 15): + def put(qid: SupportsIndex, obj: Any, unboundop: SupportsIndex = -1, fallback: SupportsIndex = -1) -> None: ... + +else: + def put(qid: SupportsIndex, obj: Any, fmt: SupportsIndex, unboundop: _UnboundOp) -> None: ... + def release(qid: SupportsIndex) -> None: ... diff --git a/stdlib/collections/__init__.pyi b/stdlib/collections/__init__.pyi index e835060468ca..8c88d81d106e 100644 --- a/stdlib/collections/__init__.pyi +++ b/stdlib/collections/__init__.pyi @@ -18,7 +18,7 @@ from typing import Any, ClassVar, Generic, NoReturn, SupportsIndex, TypeVar, fin from typing_extensions import Self, disjoint_base if sys.version_info >= (3, 15): - from builtins import frozendict + from builtins import frozendict as _frozendict __all__ = ["ChainMap", "Counter", "OrderedDict", "UserDict", "UserList", "UserString", "defaultdict", "deque", "namedtuple"] @@ -315,6 +315,9 @@ class Counter(dict[_T, int], Generic[_T]): def __sub__(self, other: Counter[_T]) -> Counter[_T]: ... def __and__(self, other: Counter[_T]) -> Counter[_T]: ... def __or__(self, other: Counter[_S]) -> Counter[_T | _S]: ... # type: ignore[override] + if sys.version_info >= (3, 15): + def __xor__(self, other: Counter[_S]) -> Counter[_T | _S]: ... # type: ignore[override] + def __pos__(self) -> Counter[_T]: ... def __neg__(self) -> Counter[_T]: ... # several type: ignores because __iadd__ is supposedly incompatible with __add__, etc. @@ -322,6 +325,8 @@ class Counter(dict[_T, int], Generic[_T]): def __isub__(self, other: SupportsItems[_T, int]) -> Self: ... def __iand__(self, other: SupportsItems[_T, int]) -> Self: ... def __ior__(self, other: SupportsItems[_T, int]) -> Self: ... # type: ignore[override,misc] + if sys.version_info >= (3, 15): + def __ixor__(self, other: Counter[_T]) -> Self: ... # type: ignore[misc] # The pure-Python implementations of the "views" classes # These are exposed at runtime in `collections/__init__.py` @@ -386,14 +391,14 @@ class OrderedDict(dict[_KT, _VT]): def __eq__(self, value: object, /) -> bool: ... if sys.version_info >= (3, 15): @overload - def __or__(self, value: dict[_KT, _VT] | frozendict[_KT, _VT], /) -> Self: ... + def __or__(self, value: dict[_KT, _VT] | _frozendict[_KT, _VT], /) -> Self: ... @overload - def __or__(self, value: dict[_T1, _T2] | frozendict[_T1, _T2], /) -> OrderedDict[_KT | _T1, _VT | _T2]: ... + def __or__(self, value: dict[_T1, _T2] | _frozendict[_T1, _T2], /) -> OrderedDict[_KT | _T1, _VT | _T2]: ... @overload # type: ignore[override] - def __ror__(self, value: dict[_KT, _VT] | frozendict[_KT, _VT], /) -> Self: ... # type: ignore[override,misc] + def __ror__(self, value: dict[_KT, _VT] | _frozendict[_KT, _VT], /) -> Self: ... # type: ignore[override,misc] @overload def __ror__( # type: ignore[misc] - self, value: dict[_T1, _T2] | frozendict[_T1, _T2], / + self, value: dict[_T1, _T2] | _frozendict[_T1, _T2], / ) -> OrderedDict[_KT | _T1, _VT | _T2]: ... else: @overload diff --git a/stdlib/genericpath.pyi b/stdlib/genericpath.pyi index 3caed77a661a..33261a399d99 100644 --- a/stdlib/genericpath.pyi +++ b/stdlib/genericpath.pyi @@ -3,7 +3,7 @@ import sys from _typeshed import BytesPath, FileDescriptorOrPath, StrOrBytesPath, StrPath, SupportsRichComparisonT from collections.abc import Sequence from typing import Literal, NewType, overload -from typing_extensions import LiteralString +from typing_extensions import LiteralString, deprecated __all__ = [ "commonprefix", @@ -23,22 +23,43 @@ if sys.version_info >= (3, 12): __all__ += ["islink"] if sys.version_info >= (3, 13): __all__ += ["isjunction", "isdevdrive", "lexists"] +if sys.version_info >= (3, 15): + __all__ += ["ALL_BUT_LAST"] + ALL_BUT_LAST: object # All overloads can return empty string. Ideally, Literal[""] would be a valid # Iterable[T], so that list[T] | Literal[""] could be used as a return # type. But because this only works when T is str, we need Sequence[T] instead. -@overload -def commonprefix(m: Sequence[LiteralString]) -> LiteralString: ... -@overload -def commonprefix(m: Sequence[StrPath]) -> str: ... -@overload -def commonprefix(m: Sequence[BytesPath]) -> bytes | Literal[""]: ... -@overload -def commonprefix(m: Sequence[list[SupportsRichComparisonT]]) -> Sequence[SupportsRichComparisonT]: ... -@overload -def commonprefix(m: Sequence[tuple[SupportsRichComparisonT, ...]]) -> Sequence[SupportsRichComparisonT]: ... +if sys.version_info >= (3, 15): + @overload + @deprecated("Deprecated since Python 3.15; use os.path.commonpath() for path prefixes.") + def commonprefix(m: Sequence[LiteralString], /) -> LiteralString: ... + @overload + @deprecated("Deprecated since Python 3.15; use os.path.commonpath() for path prefixes.") + def commonprefix(m: Sequence[StrPath], /) -> str: ... + @overload + @deprecated("Deprecated since Python 3.15; use os.path.commonpath() for path prefixes.") + def commonprefix(m: Sequence[BytesPath], /) -> bytes | Literal[""]: ... + @overload + @deprecated("Deprecated since Python 3.15; use os.path.commonpath() for path prefixes.") + def commonprefix(m: Sequence[list[SupportsRichComparisonT]], /) -> Sequence[SupportsRichComparisonT]: ... + @overload + @deprecated("Deprecated since Python 3.15; use os.path.commonpath() for path prefixes.") + def commonprefix(m: Sequence[tuple[SupportsRichComparisonT, ...]], /) -> Sequence[SupportsRichComparisonT]: ... + +else: + @overload + def commonprefix(m: Sequence[LiteralString]) -> LiteralString: ... + @overload + def commonprefix(m: Sequence[StrPath]) -> str: ... + @overload + def commonprefix(m: Sequence[BytesPath]) -> bytes | Literal[""]: ... + @overload + def commonprefix(m: Sequence[list[SupportsRichComparisonT]]) -> Sequence[SupportsRichComparisonT]: ... + @overload + def commonprefix(m: Sequence[tuple[SupportsRichComparisonT, ...]]) -> Sequence[SupportsRichComparisonT]: ... + def exists(path: FileDescriptorOrPath) -> bool: ... -def getsize(filename: FileDescriptorOrPath) -> int: ... def isfile(path: FileDescriptorOrPath) -> bool: ... def isdir(s: FileDescriptorOrPath) -> bool: ... @@ -47,12 +68,23 @@ if sys.version_info >= (3, 12): # These return float if os.stat_float_times() == True, # but int is a subclass of float. -def getatime(filename: FileDescriptorOrPath) -> float: ... -def getmtime(filename: FileDescriptorOrPath) -> float: ... -def getctime(filename: FileDescriptorOrPath) -> float: ... -def samefile(f1: FileDescriptorOrPath, f2: FileDescriptorOrPath) -> bool: ... def sameopenfile(fp1: int, fp2: int) -> bool: ... -def samestat(s1: os.stat_result, s2: os.stat_result) -> bool: ... + +if sys.version_info >= (3, 15): + def getsize(filename: FileDescriptorOrPath, /) -> int: ... + def getatime(filename: FileDescriptorOrPath, /) -> float: ... + def getmtime(filename: FileDescriptorOrPath, /) -> float: ... + def getctime(filename: FileDescriptorOrPath, /) -> float: ... + def samefile(f1: FileDescriptorOrPath, f2: FileDescriptorOrPath, /) -> bool: ... + def samestat(s1: os.stat_result, s2: os.stat_result, /) -> bool: ... + +else: + def getsize(filename: FileDescriptorOrPath) -> int: ... + def getatime(filename: FileDescriptorOrPath) -> float: ... + def getmtime(filename: FileDescriptorOrPath) -> float: ... + def getctime(filename: FileDescriptorOrPath) -> float: ... + def samefile(f1: FileDescriptorOrPath, f2: FileDescriptorOrPath) -> bool: ... + def samestat(s1: os.stat_result, s2: os.stat_result) -> bool: ... if sys.version_info >= (3, 13): def isjunction(path: StrOrBytesPath) -> bool: ... diff --git a/stdlib/glob.pyi b/stdlib/glob.pyi index 07455acaefc6..1e4d7203070d 100644 --- a/stdlib/glob.pyi +++ b/stdlib/glob.pyi @@ -9,14 +9,17 @@ __all__ = ["escape", "glob", "iglob"] if sys.version_info >= (3, 13): __all__ += ["translate"] -@deprecated( - "Deprecated since Python 3.10; will be removed in Python 3.15. Use `glob.glob()` with the *root_dir* argument instead." -) -def glob0(dirname: AnyStr, pattern: AnyStr) -> list[AnyStr]: ... -@deprecated( - "Deprecated since Python 3.10; will be removed in Python 3.15. Use `glob.glob()` with the *root_dir* argument instead." -) -def glob1(dirname: AnyStr, pattern: AnyStr) -> list[AnyStr]: ... +if sys.version_info >= (3, 15): + pass +else: + @deprecated( + "Deprecated since Python 3.10; will be removed in Python 3.15. Use `glob.glob()` with the *root_dir* argument instead." + ) + def glob0(dirname: AnyStr, pattern: AnyStr) -> list[AnyStr]: ... + @deprecated( + "Deprecated since Python 3.10; will be removed in Python 3.15. Use `glob.glob()` with the *root_dir* argument instead." + ) + def glob1(dirname: AnyStr, pattern: AnyStr) -> list[AnyStr]: ... if sys.version_info >= (3, 11): def glob( diff --git a/stdlib/http/client.pyi b/stdlib/http/client.pyi index 2af9769d3c36..fa89c0669680 100644 --- a/stdlib/http/client.pyi +++ b/stdlib/http/client.pyi @@ -178,14 +178,27 @@ class HTTPConnection: host: str port: int sock: socket | MaybeNone # can be `None` if `.connect()` was not called - def __init__( - self, - host: str, - port: int | None = None, - timeout: float | None = ..., - source_address: tuple[str, int] | None = None, - blocksize: int = 8192, - ) -> None: ... + if sys.version_info >= (3, 15): + def __init__( + self, + host: str, + port: int | None = None, + timeout: float | None = ..., + source_address: tuple[str, int] | None = None, + blocksize: int = 8192, + *, + max_response_headers: int | None = None, + ) -> None: ... + else: + def __init__( + self, + host: str, + port: int | None = None, + timeout: float | None = ..., + source_address: tuple[str, int] | None = None, + blocksize: int = 8192, + ) -> None: ... + def request( self, method: str, @@ -211,7 +224,19 @@ class HTTPConnection: class HTTPSConnection(HTTPConnection): # Can be `None` if `.connect()` was not called: sock: ssl.SSLSocket | MaybeNone - if sys.version_info >= (3, 12): + if sys.version_info >= (3, 15): + def __init__( + self, + host: str, + port: int | None = None, + *, + timeout: float | None = ..., + source_address: tuple[str, int] | None = None, + context: ssl.SSLContext | None = None, + blocksize: int = 8192, + max_response_headers: int | None = None, + ) -> None: ... + elif sys.version_info >= (3, 12): def __init__( self, host: str, diff --git a/stdlib/http/server.pyi b/stdlib/http/server.pyi index 2c1a374331bc..0f892060b782 100644 --- a/stdlib/http/server.pyi +++ b/stdlib/http/server.pyi @@ -10,7 +10,16 @@ from ssl import Purpose, SSLContext from typing import Any, AnyStr, BinaryIO, ClassVar, Protocol, type_check_only from typing_extensions import Self, deprecated -if sys.version_info >= (3, 14): +if sys.version_info >= (3, 15): + __all__ = [ + "HTTPServer", + "ThreadingHTTPServer", + "HTTPSServer", + "ThreadingHTTPSServer", + "BaseHTTPRequestHandler", + "SimpleHTTPRequestHandler", + ] +elif sys.version_info >= (3, 14): __all__ = [ "HTTPServer", "ThreadingHTTPServer", @@ -77,6 +86,8 @@ class BaseHTTPRequestHandler(socketserver.StreamRequestHandler): protocol_version: str MessageClass: type responses: Mapping[int, tuple[str, str]] + if sys.version_info >= (3, 15): + default_content_type: str default_request_version: str # undocumented weekdayname: ClassVar[Sequence[str]] # undocumented monthname: ClassVar[Sequence[str | None]] # undocumented @@ -102,14 +113,26 @@ class SimpleHTTPRequestHandler(BaseHTTPRequestHandler): if sys.version_info >= (3, 12): index_pages: ClassVar[tuple[str, ...]] directory: str - def __init__( - self, - request: socketserver._RequestType, - client_address: _socket._RetAddress, - server: socketserver.BaseServer, - *, - directory: StrPath | None = None, - ) -> None: ... + if sys.version_info >= (3, 15): + def __init__( + self, + request: socketserver._RequestType, + client_address: _socket._RetAddress, + server: socketserver.BaseServer, + *, + directory: StrPath | None = None, + extra_response_headers: Mapping[str, str] | None = None, + ) -> None: ... + else: + def __init__( + self, + request: socketserver._RequestType, + client_address: _socket._RetAddress, + server: socketserver.BaseServer, + *, + directory: StrPath | None = None, + ) -> None: ... + def do_GET(self) -> None: ... def do_HEAD(self) -> None: ... def send_head(self) -> io.BytesIO | BinaryIO | None: ... # undocumented @@ -120,7 +143,9 @@ class SimpleHTTPRequestHandler(BaseHTTPRequestHandler): def executable(path: StrPath) -> bool: ... # undocumented -if sys.version_info >= (3, 13): +if sys.version_info >= (3, 15): + pass +elif sys.version_info >= (3, 13): @deprecated("Deprecated since Python 3.13; will be removed in Python 3.15.") class CGIHTTPRequestHandler(SimpleHTTPRequestHandler): cgi_directories: list[str] diff --git a/stdlib/importlib/metadata/__init__.pyi b/stdlib/importlib/metadata/__init__.pyi index a75b27e3d483..a1d0cbb912e4 100644 --- a/stdlib/importlib/metadata/__init__.pyi +++ b/stdlib/importlib/metadata/__init__.pyi @@ -31,6 +31,9 @@ __all__ = [ "version", ] +if sys.version_info >= (3, 15): + __all__ += ["PackagePath", "MetadataNotFound", "SimplePath"] + _SimplePath: TypeAlias = SimplePath def packages_distributions() -> Mapping[str, list[str]]: ... @@ -39,6 +42,9 @@ class PackageNotFoundError(ModuleNotFoundError): @property def name(self) -> str: ... # type: ignore[override] +if sys.version_info >= (3, 15): + class MetadataNotFound(FileNotFoundError): ... + if sys.version_info >= (3, 13): _EntryPointBase = object elif sys.version_info >= (3, 11): @@ -203,7 +209,9 @@ class FileHash: value: str def __init__(self, spec: str) -> None: ... -if sys.version_info >= (3, 12): +if sys.version_info >= (3, 15): + _distribution_parent = abc.ABC +elif sys.version_info >= (3, 12): class DeprecatedNonAbstract: ... _distribution_parent = DeprecatedNonAbstract else: diff --git a/stdlib/importlib/resources/abc.pyi b/stdlib/importlib/resources/abc.pyi index 477339ea7429..a3a40127a1f3 100644 --- a/stdlib/importlib/resources/abc.pyi +++ b/stdlib/importlib/resources/abc.pyi @@ -44,8 +44,12 @@ if sys.version_info >= (3, 11): def __truediv__(self, child: StrPath, /) -> Traversable: ... @abstractmethod def read_bytes(self) -> bytes: ... - @abstractmethod - def read_text(self, encoding: str | None = None) -> str: ... + if sys.version_info >= (3, 15): + @abstractmethod + def read_text(self, encoding: str | None = None, errors: str | None = None) -> str: ... + else: + @abstractmethod + def read_text(self, encoding: str | None = None) -> str: ... class TraversableResources(ResourceReader): @abstractmethod diff --git a/stdlib/inspect.pyi b/stdlib/inspect.pyi index f74f45dfcbf2..5fc69796cc40 100644 --- a/stdlib/inspect.pyi +++ b/stdlib/inspect.pyi @@ -306,7 +306,13 @@ def getblock(lines: list[str]) -> list[str]: ... def getblock(lines: tuple[str, ...]) -> tuple[str, ...]: ... @overload def getblock(lines: Sequence[str]) -> Sequence[str]: ... -def getdoc(object: object) -> str | None: ... + +if sys.version_info >= (3, 15): + def getdoc(object: object, *, inherit_class_doc: bool = True, fallback_to_class_doc: bool = True) -> str | None: ... + +else: + def getdoc(object: object) -> str | None: ... + def getcomments(object: object) -> str | None: ... def getfile(object: _SourceObjectType) -> str: ... def getmodule(object: object, _filename: str | None = None) -> ModuleType | None: ... diff --git a/stdlib/math.pyi b/stdlib/math/__init__.pyi similarity index 93% rename from stdlib/math.pyi rename to stdlib/math/__init__.pyi index 30858b870f68..9f4f7162634b 100644 --- a/stdlib/math.pyi +++ b/stdlib/math/__init__.pyi @@ -58,6 +58,11 @@ def floor(x: _SupportsFloor[_T], /) -> _T: ... @overload def floor(x: _SupportsFloatOrIndex, /) -> int: ... def fmod(x: _SupportsFloatOrIndex, y: _SupportsFloatOrIndex, /) -> float: ... + +if sys.version_info >= (3, 15): + def fmax(x: _SupportsFloatOrIndex, y: _SupportsFloatOrIndex, /) -> float: ... + def fmin(x: _SupportsFloatOrIndex, y: _SupportsFloatOrIndex, /) -> float: ... + def frexp(x: _SupportsFloatOrIndex, /) -> tuple[float, int]: ... def fsum(seq: Iterable[_SupportsFloatOrIndex], /) -> float: ... def gamma(x: _SupportsFloatOrIndex, /) -> float: ... @@ -73,6 +78,11 @@ def isclose( def isinf(x: _SupportsFloatOrIndex, /) -> bool: ... def isfinite(x: _SupportsFloatOrIndex, /) -> bool: ... def isnan(x: _SupportsFloatOrIndex, /) -> bool: ... + +if sys.version_info >= (3, 15): + def isnormal(x: _SupportsFloatOrIndex, /) -> bool: ... + def issubnormal(x: _SupportsFloatOrIndex, /) -> bool: ... + def isqrt(n: SupportsIndex, /) -> int: ... def lcm(*integers: SupportsIndex) -> int: ... def ldexp(x: _SupportsFloatOrIndex, i: int, /) -> float: ... @@ -118,6 +128,10 @@ def prod(iterable: Iterable[_MultiplicableT1], /, *, start: _MultiplicableT2) -> def radians(x: _SupportsFloatOrIndex, /) -> float: ... def remainder(x: _SupportsFloatOrIndex, y: _SupportsFloatOrIndex, /) -> float: ... def sin(x: _SupportsFloatOrIndex, /) -> float: ... + +if sys.version_info >= (3, 15): + def signbit(x: _SupportsFloatOrIndex, /) -> bool: ... + def sinh(x: _SupportsFloatOrIndex, /) -> float: ... if sys.version_info >= (3, 12): diff --git a/stdlib/math/integer.pyi b/stdlib/math/integer.pyi new file mode 100644 index 000000000000..6d6d6b3e82dc --- /dev/null +++ b/stdlib/math/integer.pyi @@ -0,0 +1,8 @@ +from typing import SupportsIndex + +def comb(n: SupportsIndex, k: SupportsIndex, /) -> int: ... +def factorial(n: SupportsIndex, /) -> int: ... +def gcd(*integers: SupportsIndex) -> int: ... +def isqrt(n: SupportsIndex, /) -> int: ... +def lcm(*integers: SupportsIndex) -> int: ... +def perm(n: SupportsIndex, k: SupportsIndex | None = None, /) -> int: ... diff --git a/stdlib/multiprocessing/forkserver.pyi b/stdlib/multiprocessing/forkserver.pyi index 570b492e9daf..f0af1ce7a827 100644 --- a/stdlib/multiprocessing/forkserver.pyi +++ b/stdlib/multiprocessing/forkserver.pyi @@ -15,7 +15,20 @@ class ForkServer: def connect_to_new_process(self, fds: Sequence[int]) -> tuple[int, int]: ... def ensure_running(self) -> None: ... -if sys.version_info >= (3, 14): +if sys.version_info >= (3, 15): + def main( + listener_fd: int | None, + alive_r: FileDescriptorLike, + preload: Sequence[str], + main_path: str | None = None, + sys_path: list[str] | None = None, + *, + sys_argv: list[str] | None = None, + authkey_r: int | None = None, + on_error: str = "ignore", + ) -> None: ... + +elif sys.version_info >= (3, 14): # `sys_argv` parameter added in Python 3.14.3 def main( listener_fd: int | None, diff --git a/stdlib/ntpath.pyi b/stdlib/ntpath.pyi index 074df075b972..10b7c52adf48 100644 --- a/stdlib/ntpath.pyi +++ b/stdlib/ntpath.pyi @@ -51,6 +51,8 @@ if sys.version_info >= (3, 12): from posixpath import isjunction as isjunction, splitroot as splitroot if sys.version_info >= (3, 13): from genericpath import isdevdrive as isdevdrive +if sys.version_info >= (3, 15): + from genericpath import ALL_BUT_LAST as ALL_BUT_LAST __all__ = [ "normcase", @@ -97,6 +99,8 @@ if sys.version_info >= (3, 12): __all__ += ["isjunction", "splitroot"] if sys.version_info >= (3, 13): __all__ += ["isdevdrive", "isreserved"] +if sys.version_info >= (3, 15): + __all__ += ["ALL_BUT_LAST"] altsep: LiteralString @@ -111,10 +115,16 @@ def join(path: StrPath, /, *paths: StrPath) -> str: ... def join(path: BytesPath, /, *paths: BytesPath) -> bytes: ... if sys.platform == "win32": - @overload - def realpath(path: PathLike[AnyStr], *, strict: bool | _AllowMissingType = False) -> AnyStr: ... - @overload - def realpath(path: AnyStr, *, strict: bool | _AllowMissingType = False) -> AnyStr: ... + if sys.version_info >= (3, 15): + @overload + def realpath(path: PathLike[AnyStr], /, *, strict: bool | _AllowMissingType = False) -> AnyStr: ... + @overload + def realpath(path: AnyStr, /, *, strict: bool | _AllowMissingType = False) -> AnyStr: ... + else: + @overload + def realpath(path: PathLike[AnyStr], *, strict: bool | _AllowMissingType = False) -> AnyStr: ... + @overload + def realpath(path: AnyStr, *, strict: bool | _AllowMissingType = False) -> AnyStr: ... else: realpath = abspath diff --git a/stdlib/opcode.pyi b/stdlib/opcode.pyi index 3bc41db42bb6..4300b7680141 100644 --- a/stdlib/opcode.pyi +++ b/stdlib/opcode.pyi @@ -1,4 +1,7 @@ import sys + +if sys.version_info >= (3, 15): + from builtins import frozendict from typing import Final, Literal if sys.version_info >= (3, 15): diff --git a/stdlib/pathlib/__init__.pyi b/stdlib/pathlib/__init__.pyi index 12cd36425d13..91f3f53b6eb7 100644 --- a/stdlib/pathlib/__init__.pyi +++ b/stdlib/pathlib/__init__.pyi @@ -29,7 +29,9 @@ if sys.version_info >= (3, 13): __all__ += ["UnsupportedOperation"] class PurePath(PathLike[str]): - if sys.version_info >= (3, 13): + if sys.version_info >= (3, 15): + pass + elif sys.version_info >= (3, 13): __slots__ = ( "_raw_paths", "_drv", @@ -82,6 +84,9 @@ class PurePath(PathLike[str]): def __hash__(self) -> int: ... def __fspath__(self) -> str: ... + if sys.version_info >= (3, 15): + def __vfspath__(self) -> str: ... + def __lt__(self, other: PurePath) -> bool: ... def __le__(self, other: PurePath) -> bool: ... def __gt__(self, other: PurePath) -> bool: ... @@ -93,7 +98,9 @@ class PurePath(PathLike[str]): @deprecated("Deprecated since Python 3.14; will be removed in Python 3.19. Use `Path.as_uri()` instead.") def as_uri(self) -> str: ... def is_absolute(self) -> bool: ... - if sys.version_info >= (3, 13): + if sys.version_info >= (3, 15): + pass + elif sys.version_info >= (3, 13): @deprecated( "Deprecated since Python 3.13; will be removed in Python 3.15. " "Use `os.path.isreserved()` to detect reserved paths on Windows." diff --git a/stdlib/posixpath.pyi b/stdlib/posixpath.pyi index 84e1b1e028bd..2de3c2879734 100644 --- a/stdlib/posixpath.pyi +++ b/stdlib/posixpath.pyi @@ -17,6 +17,9 @@ from genericpath import ( samestat as samestat, ) +if sys.version_info >= (3, 15): + from genericpath import ALL_BUT_LAST as ALL_BUT_LAST + if sys.version_info >= (3, 13): from genericpath import isdevdrive as isdevdrive from os import PathLike @@ -64,6 +67,8 @@ __all__ = [ "commonpath", ] __all__ += ["ALLOW_MISSING"] +if sys.version_info >= (3, 15): + __all__ += ["ALL_BUT_LAST"] if sys.version_info >= (3, 12): __all__ += ["isjunction", "splitroot"] if sys.version_info >= (3, 13): @@ -85,14 +90,27 @@ devnull: LiteralString def abspath(path: PathLike[AnyStr]) -> AnyStr: ... @overload def abspath(path: AnyStr) -> AnyStr: ... -@overload -def basename(p: PathLike[AnyStr]) -> AnyStr: ... -@overload -def basename(p: AnyOrLiteralStr) -> AnyOrLiteralStr: ... -@overload -def dirname(p: PathLike[AnyStr]) -> AnyStr: ... -@overload -def dirname(p: AnyOrLiteralStr) -> AnyOrLiteralStr: ... + +if sys.version_info >= (3, 15): + @overload + def basename(p: PathLike[AnyStr], /) -> AnyStr: ... + @overload + def basename(p: AnyOrLiteralStr, /) -> AnyOrLiteralStr: ... + @overload + def dirname(p: PathLike[AnyStr], /) -> AnyStr: ... + @overload + def dirname(p: AnyOrLiteralStr, /) -> AnyOrLiteralStr: ... + +else: + @overload + def basename(p: PathLike[AnyStr]) -> AnyStr: ... + @overload + def basename(p: AnyOrLiteralStr) -> AnyOrLiteralStr: ... + @overload + def dirname(p: PathLike[AnyStr]) -> AnyStr: ... + @overload + def dirname(p: AnyOrLiteralStr) -> AnyOrLiteralStr: ... + @overload def expanduser(path: PathLike[AnyStr]) -> AnyStr: ... @overload @@ -101,10 +119,19 @@ def expanduser(path: AnyStr) -> AnyStr: ... def expandvars(path: PathLike[AnyStr]) -> AnyStr: ... @overload def expandvars(path: AnyStr) -> AnyStr: ... -@overload -def normcase(s: PathLike[AnyStr]) -> AnyStr: ... -@overload -def normcase(s: AnyOrLiteralStr) -> AnyOrLiteralStr: ... + +if sys.version_info >= (3, 15): + @overload + def normcase(s: PathLike[AnyStr], /) -> AnyStr: ... + @overload + def normcase(s: AnyOrLiteralStr, /) -> AnyOrLiteralStr: ... + +else: + @overload + def normcase(s: PathLike[AnyStr]) -> AnyStr: ... + @overload + def normcase(s: AnyOrLiteralStr) -> AnyOrLiteralStr: ... + @overload def normpath(path: PathLike[AnyStr]) -> AnyStr: ... @overload @@ -116,7 +143,7 @@ def commonpath(paths: Iterable[StrPath]) -> str: ... @overload def commonpath(paths: Iterable[BytesPath]) -> bytes: ... -# First parameter is not actually pos-only, +# First parameter is not actually pos-only before Python 3.15, # but must be defined as pos-only in the stub or cross-platform code doesn't type-check, # as the parameter name is different in ntpath.join() @overload @@ -125,36 +152,77 @@ def join(a: LiteralString, /, *paths: LiteralString) -> LiteralString: ... def join(a: StrPath, /, *paths: StrPath) -> str: ... @overload def join(a: BytesPath, /, *paths: BytesPath) -> bytes: ... -@overload -def realpath(filename: PathLike[AnyStr], *, strict: bool | _AllowMissingType = False) -> AnyStr: ... -@overload -def realpath(filename: AnyStr, *, strict: bool | _AllowMissingType = False) -> AnyStr: ... + +if sys.version_info >= (3, 15): + @overload + def realpath(filename: PathLike[AnyStr], /, *, strict: bool | _AllowMissingType = False) -> AnyStr: ... + @overload + def realpath(filename: AnyStr, /, *, strict: bool | _AllowMissingType = False) -> AnyStr: ... + +else: + @overload + def realpath(filename: PathLike[AnyStr], *, strict: bool | _AllowMissingType = False) -> AnyStr: ... + @overload + def realpath(filename: AnyStr, *, strict: bool | _AllowMissingType = False) -> AnyStr: ... + @overload def relpath(path: LiteralString, start: LiteralString | None = None) -> LiteralString: ... @overload def relpath(path: BytesPath, start: BytesPath | None = None) -> bytes: ... @overload def relpath(path: StrPath, start: StrPath | None = None) -> str: ... -@overload -def split(p: PathLike[AnyStr]) -> tuple[AnyStr, AnyStr]: ... -@overload -def split(p: AnyOrLiteralStr) -> tuple[AnyOrLiteralStr, AnyOrLiteralStr]: ... -@overload -def splitdrive(p: PathLike[AnyStr]) -> tuple[AnyStr, AnyStr]: ... -@overload -def splitdrive(p: AnyOrLiteralStr) -> tuple[AnyOrLiteralStr, AnyOrLiteralStr]: ... -@overload -def splitext(p: PathLike[AnyStr]) -> tuple[AnyStr, AnyStr]: ... -@overload -def splitext(p: AnyOrLiteralStr) -> tuple[AnyOrLiteralStr, AnyOrLiteralStr]: ... -def isabs(s: StrOrBytesPath) -> bool: ... + +if sys.version_info >= (3, 15): + @overload + def split(p: PathLike[AnyStr], /) -> tuple[AnyStr, AnyStr]: ... + @overload + def split(p: AnyOrLiteralStr, /) -> tuple[AnyOrLiteralStr, AnyOrLiteralStr]: ... + @overload + def splitdrive(p: PathLike[AnyStr], /) -> tuple[AnyStr, AnyStr]: ... + @overload + def splitdrive(p: AnyOrLiteralStr, /) -> tuple[AnyOrLiteralStr, AnyOrLiteralStr]: ... + +else: + @overload + def split(p: PathLike[AnyStr]) -> tuple[AnyStr, AnyStr]: ... + @overload + def split(p: AnyOrLiteralStr) -> tuple[AnyOrLiteralStr, AnyOrLiteralStr]: ... + @overload + def splitdrive(p: PathLike[AnyStr]) -> tuple[AnyStr, AnyStr]: ... + @overload + def splitdrive(p: AnyOrLiteralStr) -> tuple[AnyOrLiteralStr, AnyOrLiteralStr]: ... + +if sys.version_info >= (3, 15): + @overload + def splitext(p: PathLike[AnyStr], /) -> tuple[AnyStr, AnyStr]: ... + @overload + def splitext(p: AnyOrLiteralStr, /) -> tuple[AnyOrLiteralStr, AnyOrLiteralStr]: ... + +else: + @overload + def splitext(p: PathLike[AnyStr]) -> tuple[AnyStr, AnyStr]: ... + @overload + def splitext(p: AnyOrLiteralStr) -> tuple[AnyOrLiteralStr, AnyOrLiteralStr]: ... + +if sys.version_info >= (3, 15): + def isabs(s: StrOrBytesPath, /) -> bool: ... + +else: + def isabs(s: StrOrBytesPath) -> bool: ... + def islink(path: FileDescriptorOrPath) -> bool: ... def ismount(path: FileDescriptorOrPath) -> bool: ... def lexists(path: FileDescriptorOrPath) -> bool: ... if sys.version_info >= (3, 12): def isjunction(path: StrOrBytesPath) -> bool: ... - @overload - def splitroot(p: AnyOrLiteralStr) -> tuple[AnyOrLiteralStr, AnyOrLiteralStr, AnyOrLiteralStr]: ... - @overload - def splitroot(p: PathLike[AnyStr]) -> tuple[AnyStr, AnyStr, AnyStr]: ... + if sys.version_info >= (3, 15): + @overload + def splitroot(path: AnyOrLiteralStr, /) -> tuple[AnyOrLiteralStr, AnyOrLiteralStr, AnyOrLiteralStr]: ... + @overload + def splitroot(path: PathLike[AnyStr], /) -> tuple[AnyStr, AnyStr, AnyStr]: ... + else: + @overload + def splitroot(p: AnyOrLiteralStr) -> tuple[AnyOrLiteralStr, AnyOrLiteralStr, AnyOrLiteralStr]: ... + @overload + def splitroot(p: PathLike[AnyStr]) -> tuple[AnyStr, AnyStr, AnyStr]: ... diff --git a/stdlib/profiling/__init__.pyi b/stdlib/profiling/__init__.pyi new file mode 100644 index 000000000000..435f5a6cc66c --- /dev/null +++ b/stdlib/profiling/__init__.pyi @@ -0,0 +1,3 @@ +from . import sampling as sampling, tracing as tracing + +__all__ = ("tracing", "sampling") diff --git a/stdlib/profiling/sampling.pyi b/stdlib/profiling/sampling.pyi new file mode 100644 index 000000000000..456fdb9d437a --- /dev/null +++ b/stdlib/profiling/sampling.pyi @@ -0,0 +1,67 @@ +# pyright: reportMissingParameterType=false, reportUnknownParameterType=false + +from _typeshed import StrOrBytesPath +from abc import ABC, abstractmethod + +__all__ = ( + "Collector", + "PstatsCollector", + "CollapsedStackCollector", + "HeatmapCollector", + "GeckoCollector", + "JsonlCollector", + "StringTable", +) + +class Collector(ABC): + @abstractmethod + def collect(self, stack_frames, timestamps_us=None) -> None: ... + def collect_failed_sample(self) -> None: ... + @abstractmethod + def export(self, filename: StrOrBytesPath) -> None: ... + +class PstatsCollector(Collector): + def __init__(self, sample_interval_usec: int, *, skip_idle: bool = False) -> None: ... + def collect(self, stack_frames, timestamps_us=None) -> None: ... + def export(self, filename: StrOrBytesPath) -> None: ... + def create_stats(self) -> None: ... + def print_stats(self, sort=-1, limit: int | None = None, show_summary: bool = True, mode=None) -> None: ... + +class CollapsedStackCollector(Collector): + def __init__(self, *args, **kwargs) -> None: ... + def collect(self, stack_frames, timestamps_us=None) -> None: ... + def export(self, filename: StrOrBytesPath) -> None: ... + def process_frames(self, frames, thread_id: int, weight: int = 1) -> None: ... + +class HeatmapCollector(Collector): + FILE_INDEX_FORMAT: str + def __init__(self, *args, **kwargs) -> None: ... + def collect(self, stack_frames, timestamps_us=None) -> None: ... + def export(self, output_path: StrOrBytesPath) -> None: ... + def process_frames(self, frames, thread_id: int, weight: int = 1) -> None: ... + def set_stats( + self, + sample_interval_usec: int, + duration_sec: float, + sample_rate: float, + error_rate: float | None = None, + missed_samples: int | None = None, + **kwargs, + ) -> None: ... + +class GeckoCollector(Collector): + def __init__(self, sample_interval_usec: int, *, skip_idle: bool = False, opcodes: bool = False) -> None: ... + def collect(self, stack_frames, timestamps_us=None) -> None: ... + def export(self, filename: StrOrBytesPath) -> None: ... + +class JsonlCollector(Collector): + def __init__(self, sample_interval_usec: int, *, skip_idle: bool = False, mode=None) -> None: ... + def collect(self, stack_frames, timestamps_us=None) -> None: ... + def export(self, filename: StrOrBytesPath) -> None: ... + def process_frames(self, frames, _thread_id: int, weight: int = 1) -> None: ... + +class StringTable: + def intern(self, string: object) -> int: ... + def get_string(self, index: int) -> str: ... + def get_strings(self) -> list[str]: ... + def __len__(self) -> int: ... diff --git a/stdlib/profiling/tracing.pyi b/stdlib/profiling/tracing.pyi new file mode 100644 index 000000000000..af4ab508406a --- /dev/null +++ b/stdlib/profiling/tracing.pyi @@ -0,0 +1,9 @@ +from cProfile import Profile as Profile, run as run, runctx as runctx +from types import CodeType +from typing import TypeAlias + +__all__ = ("run", "runctx", "Profile") + +_Label: TypeAlias = tuple[str, int, str] + +def label(code: str | CodeType) -> _Label: ... # undocumented diff --git a/stdlib/pydoc.pyi b/stdlib/pydoc.pyi index 59be9438015a..d340f5c587b3 100644 --- a/stdlib/pydoc.pyi +++ b/stdlib/pydoc.pyi @@ -62,6 +62,9 @@ def safeimport(path: str, forceload: bool = ..., cache: MutableMapping[str, Modu class Doc: PYTHONDOCS: str + if sys.version_info >= (3, 15): + STDLIB_DIR: str + def document(self, object: object, name: str | None = None, *args: Any) -> str: ... def fail(self, object: object, name: str | None = None, *args: Any) -> NoReturn: ... @abstractmethod @@ -76,7 +79,10 @@ class Doc: def docproperty(self, object: object, name: str | None = None, *args: Any) -> str: ... @abstractmethod def docdata(self, object: object, name: str | None = None, *args: Any) -> str: ... - def getdocloc(self, object: object, basedir: str = ...) -> str | None: ... + if sys.version_info >= (3, 15): + def getdocloc(self, object: object, basedir: str | None = None) -> str | None: ... + else: + def getdocloc(self, object: object, basedir: str = ...) -> str | None: ... class HTMLRepr(Repr): def __init__(self) -> None: ... diff --git a/stdlib/sys/__init__.pyi b/stdlib/sys/__init__.pyi index 7976656e5359..51c6d1deeecc 100644 --- a/stdlib/sys/__init__.pyi +++ b/stdlib/sys/__init__.pyi @@ -4,18 +4,30 @@ from _typeshed.importlib import MetaPathFinderProtocol, PathEntryFinderProtocol from builtins import object as _object from collections.abc import AsyncGenerator, Callable, Sequence from io import TextIOWrapper -from types import FrameType, ModuleType, TracebackType +from types import FrameType, ModuleType, SimpleNamespace, TracebackType from typing import Any, Final, Literal, NoReturn, Protocol, TextIO, TypeAlias, TypeVar, final, overload, type_check_only from typing_extensions import LiteralString, deprecated _T = TypeVar("_T") +_LazyImportMode: TypeAlias = Literal["normal", "all", "none"] +_LazyImportFilter: TypeAlias = Callable[[str, str, tuple[str, ...] | None], bool] # see https://github.com/python/typeshed/issues/8513#issue-1333671093 for the rationale behind this alias _ExitCode: TypeAlias = str | int | None +if sys.version_info >= (3, 15): + @type_check_only + class _AbiInfo(SimpleNamespace): + pointer_bits: int + free_threaded: bool + debug: bool + byteorder: Literal["little", "big"] + # ----- sys variables ----- if sys.platform != "win32": abiflags: str +if sys.version_info >= (3, 15): + abi_info: _AbiInfo argv: list[str] base_exec_prefix: str base_prefix: str @@ -40,6 +52,8 @@ maxsize: int maxunicode: int meta_path: list[MetaPathFinderProtocol] modules: dict[str, ModuleType] +if sys.version_info >= (3, 15): + lazy_modules: dict[str, set[str]] orig_argv: list[str] path: list[str] path_hooks: list[Callable[[str], PathEntryFinderProtocol]] @@ -376,6 +390,11 @@ if sys.platform != "win32": def getfilesystemencoding() -> LiteralString: ... def getfilesystemencodeerrors() -> LiteralString: ... + +if sys.version_info >= (3, 15): + def get_lazy_imports() -> _LazyImportMode: ... + def get_lazy_imports_filter() -> _LazyImportFilter | None: ... + def getrefcount(object: Any, /) -> int: ... def getrecursionlimit() -> int: ... def getsizeof(obj: object, default: int = ...) -> int: ... @@ -486,6 +505,10 @@ def set_coroutine_origin_tracking_depth(depth: int) -> None: ... def set_int_max_str_digits(maxdigits: int) -> None: ... def get_int_max_str_digits() -> int: ... +if sys.version_info >= (3, 15): + def set_lazy_imports(mode: _LazyImportMode) -> None: ... + def set_lazy_imports_filter(filter: _LazyImportFilter | None) -> None: ... + if sys.version_info >= (3, 12): if sys.version_info >= (3, 13): def getunicodeinternedsize(*, _only_immortal: bool = False) -> int: ... diff --git a/stdlib/threading.pyi b/stdlib/threading.pyi index bd9bf7693824..6b51b424cee6 100644 --- a/stdlib/threading.pyi +++ b/stdlib/threading.pyi @@ -2,11 +2,11 @@ import _thread import sys from _thread import _ExceptHookArgs, get_native_id as get_native_id from _typeshed import ProfileFunction, TraceFunction -from collections.abc import Callable, Iterable, Mapping +from collections.abc import Callable, Iterable, Iterator, Mapping from contextvars import Context from types import TracebackType from typing import Any, Final, TypeVar, final -from typing_extensions import deprecated +from typing_extensions import Self, deprecated _T = TypeVar("_T") @@ -42,6 +42,9 @@ __all__ = [ if sys.version_info >= (3, 12): __all__ += ["setprofile_all_threads", "settrace_all_threads"] +if sys.version_info >= (3, 15): + __all__ += ["concurrent_tee", "serialize_iterator", "synchronized_iterator"] + _profile_hook: ProfileFunction | None def active_count() -> int: ... @@ -62,6 +65,20 @@ if sys.version_info >= (3, 12): def gettrace() -> TraceFunction | None: ... def getprofile() -> ProfileFunction | None: ... + +if sys.version_info >= (3, 15): + @final + class serialize_iterator(Iterator[_T]): + def __init__(self, iterable: Iterable[_T]) -> None: ... + def __iter__(self) -> Self: ... + def __next__(self) -> _T: ... + def send(self, value: Any, /) -> _T: ... + def throw(self, typ: type[BaseException], val: BaseException | object = ..., tb: TracebackType | None = ...) -> _T: ... + def close(self) -> None: ... + + def synchronized_iterator(func: Callable[..., Iterable[_T]]) -> Callable[..., Iterator[_T]]: ... + def concurrent_tee(iterable: Iterable[_T], n: int = 2) -> tuple[Iterator[_T], ...]: ... + def stack_size(size: int = 0, /) -> int: ... TIMEOUT_MAX: Final[float] diff --git a/stdlib/timeit.pyi b/stdlib/timeit.pyi index 9ce00952c882..cc2b2027a820 100644 --- a/stdlib/timeit.pyi +++ b/stdlib/timeit.pyi @@ -1,3 +1,4 @@ +import sys import time from collections.abc import Callable, Sequence from typing import IO, Any, TypeAlias @@ -20,7 +21,12 @@ class Timer: def print_exc(self, file: IO[str] | None = None) -> None: ... def timeit(self, number: int = 1000000) -> float: ... def repeat(self, repeat: int = 5, number: int = 1000000) -> list[float]: ... - def autorange(self, callback: Callable[[int, float], object] | None = None) -> tuple[int, float]: ... + if sys.version_info >= (3, 15): + def autorange( + self, callback: Callable[[int, float], object] | None = None, target_time: float = 0.2 + ) -> tuple[int, float]: ... + else: + def autorange(self, callback: Callable[[int, float], object] | None = None) -> tuple[int, float]: ... def timeit( stmt: _Stmt = "pass", diff --git a/stdlib/tkinter/__init__.pyi b/stdlib/tkinter/__init__.pyi index c6fe017c79ca..21cebd45cd6e 100644 --- a/stdlib/tkinter/__init__.pyi +++ b/stdlib/tkinter/__init__.pyi @@ -313,6 +313,9 @@ class Event(Generic[_W_co]): type: EventType widget: _W_co delta: int + if sys.version_info >= (3, 15): + detail: str + user_data: str if sys.version_info >= (3, 14): def __class_getitem__(cls, item: Any, /) -> GenericAlias: ... @@ -634,6 +637,10 @@ class Misc: def pack_slaves(self) -> list[Widget]: ... def grid_slaves(self, row: int | None = None, column: int | None = None) -> list[Widget]: ... def place_slaves(self) -> list[Widget]: ... + if sys.version_info >= (3, 15): + def pack_content(self) -> list[Widget]: ... + def grid_content(self, row: int | None = None, column: int | None = None) -> list[Widget]: ... + def place_content(self) -> list[Widget]: ... slaves = pack_slaves def event_add(self, virtual: str, *sequences: str) -> None: ... def event_delete(self, virtual: str, *sequences: str) -> None: ... @@ -1110,6 +1117,8 @@ class Pack: ) -> None: ... def pack_forget(self) -> None: ... def pack_info(self) -> _PackInfo: ... # errors if widget hasn't been packed + if sys.version_info >= (3, 15): + def pack_content(self) -> list[Widget]: ... pack = pack_configure forget = pack_forget propagate = Misc.pack_propagate @@ -1148,6 +1157,8 @@ class Place: ) -> None: ... def place_forget(self) -> None: ... def place_info(self) -> _PlaceInfo: ... + if sys.version_info >= (3, 15): + def place_content(self) -> list[Widget]: ... place = place_configure info = place_info @@ -1185,6 +1196,8 @@ class Grid: def grid_forget(self) -> None: ... def grid_remove(self) -> None: ... def grid_info(self) -> _GridInfo: ... + if sys.version_info >= (3, 15): + def grid_content(self, row: int | None = None, column: int | None = None) -> list[Widget]: ... grid = grid_configure location = Misc.grid_location size = Misc.grid_size @@ -3605,19 +3618,55 @@ class Text(Widget, XView, YView): ) -> None: ... def scan_mark(self, x: int, y: int) -> None: ... def scan_dragto(self, x: int, y: int) -> None: ... - def search( - self, - pattern: str, - index: str | float | _tkinter.Tcl_Obj | Widget, - stopindex: str | float | _tkinter.Tcl_Obj | Widget | None = None, - forwards: bool | None = None, - backwards: bool | None = None, - exact: bool | None = None, - regexp: bool | None = None, - nocase: bool | None = None, - count: Variable | None = None, - elide: bool | None = None, - ) -> str: ... # returns empty string for not found + if sys.version_info >= (3, 15): + def search( + self, + pattern: str, + index: str | float | _tkinter.Tcl_Obj | Widget, + stopindex: str | float | _tkinter.Tcl_Obj | Widget | None = None, + forwards: bool | None = None, + backwards: bool | None = None, + exact: bool | None = None, + regexp: bool | None = None, + nocase: bool | None = None, + count: Variable | None = None, + elide: bool | None = None, + *, + nolinestop: bool | None = None, + strictlimits: bool | None = None, + ) -> str: ... # returns empty string for not found + def search_all( + self, + pattern: str, + index: str | float | _tkinter.Tcl_Obj | Widget, + stopindex: str | float | _tkinter.Tcl_Obj | Widget | None = None, + *, + forwards: bool | None = None, + backwards: bool | None = None, + exact: bool | None = None, + regexp: bool | None = None, + nocase: bool | None = None, + count: Variable | None = None, + elide: bool | None = None, + nolinestop: bool | None = None, + overlap: bool | None = None, + strictlimits: bool | None = None, + ) -> tuple[str, ...]: ... + else: + def search( + self, + pattern: str, + index: str | float | _tkinter.Tcl_Obj | Widget, + stopindex: str | float | _tkinter.Tcl_Obj | Widget | None = None, + forwards: bool | None = None, + backwards: bool | None = None, + exact: bool | None = None, + regexp: bool | None = None, + nocase: bool | None = None, + count: Variable | None = None, + elide: bool | None = None, + ) -> str: ... # returns empty string for not found + def see(self, index: str | float | _tkinter.Tcl_Obj | Widget) -> None: ... def tag_add( self, tagName: str, index1: str | float | _tkinter.Tcl_Obj | Widget, *args: str | float | _tkinter.Tcl_Obj | Widget diff --git a/stdlib/types.pyi b/stdlib/types.pyi index a67a3eda6574..ad14d5daedc9 100644 --- a/stdlib/types.pyi +++ b/stdlib/types.pyi @@ -12,6 +12,7 @@ from collections.abc import ( Iterator, KeysView, Mapping, + MutableMapping, MutableSequence, ValuesView, ) @@ -62,6 +63,9 @@ if sys.version_info >= (3, 12): if sys.version_info >= (3, 13): __all__ += ["CapsuleType"] +if sys.version_info >= (3, 15): + __all__ += ["FrameLocalsProxyType", "LazyImportType"] + # Note, all classes "defined" here require special handling. _T1 = TypeVar("_T1") @@ -149,9 +153,13 @@ class CodeType: def co_name(self) -> str: ... @property def co_firstlineno(self) -> int: ... - @property - @deprecated("Deprecated since Python 3.10; will be removed in Python 3.15. Use `CodeType.co_lines()` instead.") - def co_lnotab(self) -> bytes: ... + if sys.version_info >= (3, 15): + pass + else: + @property + @deprecated("Deprecated since Python 3.10; will be removed in Python 3.15. Use `CodeType.co_lines()` instead.") + def co_lnotab(self) -> bytes: ... + @property def co_freevars(self) -> tuple[str, ...]: ... @property @@ -360,6 +368,9 @@ class GeneratorType(Generator[_YieldT_co, _SendT_contra, _ReturnT_co]): if sys.version_info >= (3, 11): @property def gi_suspended(self) -> bool: ... + if sys.version_info >= (3, 15): + @property + def gi_state(self) -> Literal["GEN_CREATED", "GEN_SUSPENDED", "GEN_RUNNING", "GEN_CLOSED"]: ... __name__: str __qualname__: str def __iter__(self) -> Self: ... @@ -389,6 +400,9 @@ class AsyncGeneratorType(AsyncGenerator[_YieldT_co, _SendT_contra]): if sys.version_info >= (3, 12): @property def ag_suspended(self) -> bool: ... + if sys.version_info >= (3, 15): + @property + def ag_state(self) -> Literal["AGEN_CREATED", "AGEN_SUSPENDED", "AGEN_RUNNING", "AGEN_CLOSED"]: ... def __aiter__(self) -> Self: ... def __anext__(self) -> Coroutine[Any, Any, _YieldT_co]: ... @@ -423,6 +437,9 @@ class CoroutineType(Coroutine[_YieldT_co, _SendT_nd_contra, _ReturnT_nd_co]): if sys.version_info >= (3, 11): @property def cr_suspended(self) -> bool: ... + if sys.version_info >= (3, 15): + @property + def cr_state(self) -> Literal["CORO_CREATED", "CORO_SUSPENDED", "CORO_RUNNING", "CORO_CLOSED"]: ... def close(self) -> None: ... def __await__(self) -> Generator[Any, None, _ReturnT_nd_co]: ... @@ -552,8 +569,12 @@ class FrameType: # An `int | None` annotation here causes too many false-positive errors, so applying `int | Any`. @property def f_lineno(self) -> int | MaybeNone: ... - @property - def f_locals(self) -> dict[str, Any]: ... + if sys.version_info >= (3, 15): + @property + def f_locals(self) -> FrameLocalsProxyType: ... + else: + @property + def f_locals(self) -> dict[str, Any]: ... f_trace: Callable[[FrameType, str, Any], Any] | None f_trace_lines: bool f_trace_opcodes: bool @@ -562,6 +583,28 @@ class FrameType: @property def f_generator(self) -> GeneratorType[Any, Any, Any] | CoroutineType[Any, Any, Any] | None: ... +if sys.version_info >= (3, 15): + @final + class FrameLocalsProxyType(MutableMapping[str, Any]): + def __new__(cls, frame: FrameType, /) -> Self: ... + def __getitem__(self, key: str, /) -> Any: ... + def __setitem__(self, key: str, value: Any, /) -> None: ... + def __delitem__(self, key: str, /) -> None: ... + def __iter__(self) -> Iterator[str]: ... + def __len__(self) -> int: ... + def __contains__(self, key: object, /) -> bool: ... + def __reversed__(self) -> Iterator[str]: ... + def copy(self) -> dict[str, Any]: ... + def pop(self, key: str, default: Any = ..., /) -> Any: ... + def setdefault(self, key: str, default: Any = ..., /) -> Any: ... + def update(self, object: SupportsKeysAndGetItem[str, Any] | Iterable[tuple[str, Any]], /) -> None: ... # type: ignore[override] + + @final + class LazyImportType: + @property + def __name__(self) -> str: ... + def resolve(self) -> Any: ... + @final class GetSetDescriptorType: @property diff --git a/stdlib/urllib/parse.pyi b/stdlib/urllib/parse.pyi index fe1cd6a71567..5cf8485f658f 100644 --- a/stdlib/urllib/parse.pyi +++ b/stdlib/urllib/parse.pyi @@ -1,4 +1,5 @@ import sys +from _typeshed import Incomplete from collections.abc import Iterable, Mapping, Sequence from types import GenericAlias from typing import Any, AnyStr, Final, Generic, Literal, NamedTuple, Protocol, TypeAlias, overload, type_check_only @@ -63,24 +64,52 @@ class _NetlocResultMixinStr(_NetlocResultMixinBase[str], _ResultMixinStr): class _NetlocResultMixinBytes(_NetlocResultMixinBase[bytes], _ResultMixinBytes): __slots__ = () -class _DefragResultBase(NamedTuple, Generic[AnyStr]): - url: AnyStr - fragment: AnyStr - -class _SplitResultBase(NamedTuple, Generic[AnyStr]): - scheme: AnyStr - netloc: AnyStr - path: AnyStr - query: AnyStr - fragment: AnyStr - -class _ParseResultBase(NamedTuple, Generic[AnyStr]): - scheme: AnyStr - netloc: AnyStr - path: AnyStr - params: AnyStr - query: AnyStr - fragment: AnyStr +if sys.version_info >= (3, 15): + class _DefragResultBase(NamedTuple, Generic[AnyStr]): + url: AnyStr + fragment: AnyStr + def geturl(self) -> AnyStr: ... # type: ignore[misc] + +else: + class _DefragResultBase(NamedTuple, Generic[AnyStr]): + url: AnyStr + fragment: AnyStr + +if sys.version_info >= (3, 15): + class _SplitResultBase(NamedTuple, Generic[AnyStr]): + scheme: AnyStr + netloc: AnyStr + path: AnyStr + query: AnyStr + fragment: AnyStr + def geturl(self) -> AnyStr: ... # type: ignore[misc] + +else: + class _SplitResultBase(NamedTuple, Generic[AnyStr]): + scheme: AnyStr + netloc: AnyStr + path: AnyStr + query: AnyStr + fragment: AnyStr + +if sys.version_info >= (3, 15): + class _ParseResultBase(NamedTuple, Generic[AnyStr]): + scheme: AnyStr + netloc: AnyStr + path: AnyStr + params: AnyStr + query: AnyStr + fragment: AnyStr + def geturl(self) -> AnyStr: ... # type: ignore[misc] + +else: + class _ParseResultBase(NamedTuple, Generic[AnyStr]): + scheme: AnyStr + netloc: AnyStr + path: AnyStr + params: AnyStr + query: AnyStr + fragment: AnyStr # Structured result objects for string data class DefragResult(_DefragResultBase[str], _ResultMixinStr): @@ -102,6 +131,95 @@ class SplitResultBytes(_SplitResultBase[bytes], _NetlocResultMixinBytes): class ParseResultBytes(_ParseResultBase[bytes], _NetlocResultMixinBytes): def geturl(self) -> bytes: ... +if sys.version_info >= (3, 15): + @type_check_only + class DefragResultMaybeNone(NamedTuple): + url: str + fragment: str | None + def encode(self, encoding: str = "ascii", errors: str = "strict") -> DefragResultBytesMaybeNone: ... + def geturl(self) -> str: ... + + @type_check_only + class SplitResultMaybeNone(NamedTuple): + scheme: str | None + netloc: str | None + path: str + query: str | None + fragment: str | None + @property + def username(self) -> str | None: ... + @property + def password(self) -> str | None: ... + @property + def hostname(self) -> str | None: ... + @property + def port(self) -> int | None: ... + def encode(self, encoding: str = "ascii", errors: str = "strict") -> SplitResultBytesMaybeNone: ... + def geturl(self) -> str: ... + + @type_check_only + class ParseResultMaybeNone(NamedTuple): + scheme: str | None + netloc: str | None + path: str + params: str | None + query: str | None + fragment: str | None + @property + def username(self) -> str | None: ... + @property + def password(self) -> str | None: ... + @property + def hostname(self) -> str | None: ... + @property + def port(self) -> int | None: ... + def encode(self, encoding: str = "ascii", errors: str = "strict") -> ParseResultBytesMaybeNone: ... + def geturl(self) -> str: ... + + @type_check_only + class DefragResultBytesMaybeNone(NamedTuple): + url: bytes + fragment: bytes | None + def decode(self, encoding: str = "ascii", errors: str = "strict") -> DefragResultMaybeNone: ... + def geturl(self) -> bytes: ... + + @type_check_only + class SplitResultBytesMaybeNone(NamedTuple): + scheme: bytes | None + netloc: bytes | None + path: bytes + query: bytes | None + fragment: bytes | None + @property + def username(self) -> bytes | None: ... + @property + def password(self) -> bytes | None: ... + @property + def hostname(self) -> bytes | None: ... + @property + def port(self) -> int | None: ... + def decode(self, encoding: str = "ascii", errors: str = "strict") -> SplitResultMaybeNone: ... + def geturl(self) -> bytes: ... + + @type_check_only + class ParseResultBytesMaybeNone(NamedTuple): + scheme: bytes | None + netloc: bytes | None + path: bytes + params: bytes | None + query: bytes | None + fragment: bytes | None + @property + def username(self) -> bytes | None: ... + @property + def password(self) -> bytes | None: ... + @property + def hostname(self) -> bytes | None: ... + @property + def port(self) -> int | None: ... + def decode(self, encoding: str = "ascii", errors: str = "strict") -> ParseResultMaybeNone: ... + def geturl(self) -> bytes: ... + def parse_qs( qs: AnyStr | None, keep_blank_values: bool = False, @@ -137,6 +255,20 @@ def urldefrag(url: str) -> DefragResult: ... @overload def urldefrag(url: bytes | bytearray | None) -> DefragResultBytes: ... +if sys.version_info >= (3, 15): + @overload + def urldefrag(url: str, *, missing_as_none: Literal[True]) -> DefragResultMaybeNone: ... + @overload + def urldefrag(url: str, *, missing_as_none: Literal[False] = False) -> DefragResult: ... + @overload + def urldefrag(url: bytes | bytearray | None, *, missing_as_none: Literal[True]) -> DefragResultBytesMaybeNone: ... + @overload + def urldefrag(url: bytes | bytearray | None, *, missing_as_none: Literal[False] = False) -> DefragResultBytes: ... + @overload + def urldefrag(url: str, *, missing_as_none: bool) -> DefragResult | DefragResultMaybeNone: ... + @overload + def urldefrag(url: bytes | bytearray | None, *, missing_as_none: bool) -> DefragResultBytes | DefragResultBytesMaybeNone: ... + # The values are passed through `str()` (unless they are bytes), so anything is valid. _QueryType: TypeAlias = ( Mapping[str, object] @@ -171,6 +303,45 @@ def urlparse(url: str, scheme: str = "", allow_fragments: bool = True) -> ParseR def urlparse( url: bytes | bytearray | None, scheme: bytes | bytearray | None | Literal[""] = "", allow_fragments: bool = True ) -> ParseResultBytes: ... + +if sys.version_info >= (3, 15): + @overload + def urlparse( + url: str, scheme: str = "", allow_fragments: bool = True, *, missing_as_none: Literal[True] + ) -> ParseResultMaybeNone: ... + @overload + def urlparse( + url: str, scheme: str = "", allow_fragments: bool = True, *, missing_as_none: Literal[False] = False + ) -> ParseResult: ... + @overload + def urlparse( + url: bytes | bytearray | None, + scheme: bytes | bytearray | None | Literal[""] = "", + allow_fragments: bool = True, + *, + missing_as_none: Literal[True], + ) -> ParseResultBytesMaybeNone: ... + @overload + def urlparse( + url: bytes | bytearray | None, + scheme: bytes | bytearray | None | Literal[""] = "", + allow_fragments: bool = True, + *, + missing_as_none: Literal[False] = False, + ) -> ParseResultBytes: ... + @overload + def urlparse( + url: str, scheme: str = "", allow_fragments: bool = True, *, missing_as_none: bool + ) -> ParseResult | ParseResultMaybeNone: ... + @overload + def urlparse( + url: bytes | bytearray | None, + scheme: bytes | bytearray | None | Literal[""] = "", + allow_fragments: bool = True, + *, + missing_as_none: bool, + ) -> ParseResultBytes | ParseResultBytesMaybeNone: ... + @overload def urlsplit(url: str, scheme: str = "", allow_fragments: bool = True) -> SplitResult: ... @@ -186,15 +357,66 @@ else: url: bytes | bytearray | None, scheme: bytes | bytearray | None | Literal[""] = "", allow_fragments: bool = True ) -> SplitResultBytes: ... -# Requires an iterable of length 6 -@overload -def urlunparse(components: Iterable[None]) -> Literal[b""]: ... # type: ignore[overload-overlap] -@overload -def urlunparse(components: Iterable[AnyStr | None]) -> AnyStr: ... +if sys.version_info >= (3, 15): + @overload + def urlsplit( + url: str, scheme: str = "", allow_fragments: bool = True, *, missing_as_none: Literal[True] + ) -> SplitResultMaybeNone: ... + @overload + def urlsplit( + url: str, scheme: str = "", allow_fragments: bool = True, *, missing_as_none: Literal[False] = False + ) -> SplitResult: ... + @overload + def urlsplit( + url: bytes | None, + scheme: bytes | None | Literal[""] = "", + allow_fragments: bool = True, + *, + missing_as_none: Literal[True], + ) -> SplitResultBytesMaybeNone: ... + @overload + def urlsplit( + url: bytes | None, + scheme: bytes | None | Literal[""] = "", + allow_fragments: bool = True, + *, + missing_as_none: Literal[False] = False, + ) -> SplitResultBytes: ... + @overload + def urlsplit( + url: str, scheme: str = "", allow_fragments: bool = True, *, missing_as_none: bool + ) -> SplitResult | SplitResultMaybeNone: ... + @overload + def urlsplit( + url: bytes | None, scheme: bytes | None | Literal[""] = "", allow_fragments: bool = True, *, missing_as_none: bool + ) -> SplitResultBytes | SplitResultBytesMaybeNone: ... + +if sys.version_info >= (3, 15): + # Requires an iterable of length 6 + @overload + def urlunparse(components: Iterable[None], *, keep_empty: bool | None | Incomplete = ...) -> Literal[b""]: ... # type: ignore[overload-overlap] + @overload + def urlunparse(components: Iterable[AnyStr | None], *, keep_empty: bool | None | Incomplete = ...) -> AnyStr: ... + +else: + # Requires an iterable of length 6 + @overload + def urlunparse(components: Iterable[None]) -> Literal[b""]: ... # type: ignore[overload-overlap] + @overload + def urlunparse(components: Iterable[AnyStr | None]) -> AnyStr: ... + +if sys.version_info >= (3, 15): + # Requires an iterable of length 5 + @overload + def urlunsplit(components: Iterable[None], *, keep_empty: bool | None | Incomplete = ...) -> Literal[b""]: ... # type: ignore[overload-overlap] + @overload + def urlunsplit(components: Iterable[AnyStr | None], *, keep_empty: bool | None | Incomplete = ...) -> AnyStr: ... + +else: + # Requires an iterable of length 5 + @overload + def urlunsplit(components: Iterable[None]) -> Literal[b""]: ... # type: ignore[overload-overlap] + @overload + def urlunsplit(components: Iterable[AnyStr | None]) -> AnyStr: ... -# Requires an iterable of length 5 -@overload -def urlunsplit(components: Iterable[None]) -> Literal[b""]: ... # type: ignore[overload-overlap] -@overload -def urlunsplit(components: Iterable[AnyStr | None]) -> AnyStr: ... def unwrap(url: str) -> str: ... diff --git a/stdlib/xml/__init__.pyi b/stdlib/xml/__init__.pyi index 7a240965136e..fa47f9eccbd2 100644 --- a/stdlib/xml/__init__.pyi +++ b/stdlib/xml/__init__.pyi @@ -1,3 +1,9 @@ # At runtime, listing submodules in __all__ without them being imported is # valid, and causes them to be included in a star import. See #6523 -__all__ = ["dom", "parsers", "sax", "etree"] # noqa: F822 # pyright: ignore[reportUnsupportedDunderAll] +import sys + +if sys.version_info >= (3, 15): + __all__ = ["dom", "parsers", "sax", "etree", "is_valid_name"] # noqa: F822 # pyright: ignore[reportUnsupportedDunderAll] + from xml.utils import is_valid_name as is_valid_name, is_valid_text as is_valid_text +else: + __all__ = ["dom", "parsers", "sax", "etree"] # noqa: F822 # pyright: ignore[reportUnsupportedDunderAll] diff --git a/stdlib/xml/utils.pyi b/stdlib/xml/utils.pyi new file mode 100644 index 000000000000..1c3bb877a7cc --- /dev/null +++ b/stdlib/xml/utils.pyi @@ -0,0 +1,2 @@ +def is_valid_name(name: str) -> bool: ... +def is_valid_text(data: str) -> bool: ... diff --git a/stdlib/zipimport.pyi b/stdlib/zipimport.pyi index f660684d351e..1dae386451f5 100644 --- a/stdlib/zipimport.pyi +++ b/stdlib/zipimport.pyi @@ -34,9 +34,15 @@ class zipimporter(_LoaderBasics): def get_source(self, fullname: str) -> str | None: ... def is_package(self, fullname: str) -> bool: ... - @deprecated("Deprecated since Python 3.10; removed in Python 3.15. Use `exec_module()` instead.") - def load_module(self, fullname: str) -> ModuleType: ... - def exec_module(self, module: ModuleType) -> None: ... - def create_module(self, spec: ModuleSpec) -> None: ... - def find_spec(self, fullname: str, target: ModuleType | None = None) -> ModuleSpec | None: ... - def invalidate_caches(self) -> None: ... + if sys.version_info >= (3, 15): + def exec_module(self, module: ModuleType) -> None: ... + def create_module(self, spec: ModuleSpec) -> None: ... + def find_spec(self, fullname: str, target: ModuleType | None = None) -> ModuleSpec | None: ... + def invalidate_caches(self) -> None: ... + else: + @deprecated("Deprecated since Python 3.10; removed in Python 3.15. Use `exec_module()` instead.") + def load_module(self, fullname: str) -> ModuleType: ... + def exec_module(self, module: ModuleType) -> None: ... + def create_module(self, spec: ModuleSpec) -> None: ... + def find_spec(self, fullname: str, target: ModuleType | None = None) -> ModuleSpec | None: ... + def invalidate_caches(self) -> None: ...