diff --git a/.github/workflows/daily.yml b/.github/workflows/daily.yml index 21632d852e88..0fe291e14596 100644 --- a/.github/workflows/daily.yml +++ b/.github/workflows/daily.yml @@ -35,7 +35,7 @@ jobs: strategy: matrix: os: ["ubuntu-latest", "windows-latest", "macos-latest"] - python-version: ["3.10", "3.11", "3.12", "3.13", "3.14"] + python-version: ["3.10", "3.11", "3.12", "3.13", "3.14", "3.15"] exclude: # https://github.com/python/typeshed/issues/15694 - os: "windows-latest" diff --git a/.github/workflows/stubtest_stdlib.yml b/.github/workflows/stubtest_stdlib.yml index bcc613894589..04738a1d8d63 100644 --- a/.github/workflows/stubtest_stdlib.yml +++ b/.github/workflows/stubtest_stdlib.yml @@ -31,7 +31,7 @@ jobs: strategy: matrix: os: ["ubuntu-latest", "windows-latest", "macos-latest"] - python-version: ["3.10", "3.11", "3.12", "3.13", "3.14"] + python-version: ["3.10", "3.11", "3.12", "3.13", "3.14", "3.15"] exclude: # https://github.com/python/typeshed/issues/15694 - os: "windows-latest" diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 8905c779c423..8696719d2954 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -42,7 +42,7 @@ jobs: strategy: matrix: platform: ["linux", "win32", "darwin"] - python-version: ["3.10", "3.11", "3.12", "3.13", "3.14"] + python-version: ["3.10", "3.11", "3.12", "3.13", "3.14", "3.15"] fail-fast: false steps: - uses: actions/checkout@v6 @@ -71,7 +71,9 @@ jobs: - uses: actions/checkout@v6 - uses: actions/setup-python@v6 with: - python-version: "3.14" + python-version: "3.15" + allow-prereleases: true + check-latest: true - uses: astral-sh/setup-uv@v7 with: version-file: "requirements-tests.txt" @@ -83,6 +85,8 @@ jobs: runs-on: ubuntu-latest strategy: matrix: + # TODO: Add 3.15 once pyright CI can avoid installing third-party + # runtime dependency stacks that do not support Python 3.15 yet. python-platform: ["Linux", "Windows", "Darwin"] python-version: ["3.11", "3.12", "3.13", "3.14"] fail-fast: false diff --git a/lib/ts_utils/py315.py b/lib/ts_utils/py315.py new file mode 100644 index 000000000000..e2cca68c6b28 --- /dev/null +++ b/lib/ts_utils/py315.py @@ -0,0 +1,20 @@ +"""Helpers for Python 3.15 test infrastructure.""" + +# These stubs require runtime dependencies that do not install cleanly on Python 3.15 yet. +PY315_INCOMPATIBLE_RUNTIME_DEPENDENCIES = { + # Depend on numpy, which does not provide Python 3.15 wheels yet. + "JACK-Client", + "geopandas", + "hnswlib", + "networkx", + "pycocotools", + "resampy", + "shapely", + "tensorflow", + # Depends on referencing, which depends on rpds-py. rpds-py currently uses + # PyO3, which rejects Python 3.15. + "jsonschema", + # Depends on matplotlib, which depends on contourpy. contourpy does not + # provide Python 3.15 wheels yet. + "seaborn", +} diff --git a/requirements-tests.txt b/requirements-tests.txt index b92b282bbcba..aeb0fd6696df 100644 --- a/requirements-tests.txt +++ b/requirements-tests.txt @@ -5,14 +5,15 @@ pyright==1.1.409 # Libraries used by our various scripts. aiohttp==3.13.5 -grpcio-tools>=1.76.0 # For grpc_tools.protoc -mypy-protobuf==5.0.0 +grpcio-tools>=1.76.0; python_version < "3.15" # For grpc_tools.protoc +mypy-protobuf==5.0.0; python_version < "3.15" packaging==26.0 pathspec>=1.1.1 pre-commit -# Required by create_baseline_stubs.py. Must match .pre-commit-config.yaml. +# Required by create_baseline_stubs.py. +# stubdefaulter depends on libcst, which does not yet install cleanly on Python 3.15. ruff==0.15.8 -stubdefaulter==0.1.0 +stubdefaulter==0.1.0; python_version < "3.15" termcolor>=2.3 tomli==2.4.1; python_version < "3.11" tomlkit==0.14.0 diff --git a/scripts/sync_protobuf/_utils.py b/scripts/sync_protobuf/_utils.py index f22bd10fb353..2af94d3d1c79 100644 --- a/scripts/sync_protobuf/_utils.py +++ b/scripts/sync_protobuf/_utils.py @@ -4,19 +4,21 @@ import sys from collections.abc import Iterable from http.client import HTTPResponse +from importlib.metadata import PackageNotFoundError, version from pathlib import Path from typing import TYPE_CHECKING from urllib.request import urlopen from zipfile import ZipFile -from mypy_protobuf.main import ( # type: ignore[import-untyped] # pyright: ignore[reportMissingTypeStubs] - __version__ as mypy_protobuf__version__, -) +try: + _mypy_protobuf_version = version("mypy-protobuf") +except PackageNotFoundError: + _mypy_protobuf_version = "unavailable" if TYPE_CHECKING: from _typeshed import StrOrBytesPath, StrPath -MYPY_PROTOBUF_VERSION = mypy_protobuf__version__ +MYPY_PROTOBUF_VERSION = _mypy_protobuf_version def download_file(url: str, destination: Path) -> None: diff --git a/stdlib/@tests/stubtest_allowlists/common.txt b/stdlib/@tests/stubtest_allowlists/common.txt index f8b4c47bc4ad..befbc32682c5 100644 --- a/stdlib/@tests/stubtest_allowlists/common.txt +++ b/stdlib/@tests/stubtest_allowlists/common.txt @@ -6,9 +6,6 @@ importlib.abc.MetaPathFinder.find_spec # Not defined on the actual class, but expected to exist. importlib.abc.PathEntryFinder.find_spec # Not defined on the actual class, but expected to exist. -tkinter.simpledialog.[A-Z_]+ -tkinter.simpledialog.TclVersion -tkinter.simpledialog.TkVersion tarfile.TarInfo.__slots__ # it's a big dictionary at runtime and the dictionary values are a bit long @@ -457,17 +454,6 @@ typing(_extensions)?\.TextIO\.newlines typing(_extensions)?\.IO\.__iter__ typing(_extensions)?\.IO\.__next__ -# typing.IO uses positional-or-keyword arguments, but in the stubs we prefer -# to mark these as positional-only for compatibility with existing sub-classes. -typing(_extensions)?\.BinaryIO\.write -typing(_extensions)?\.IO\.read -typing(_extensions)?\.IO\.readline -typing(_extensions)?\.IO\.readlines -typing(_extensions)?\.IO\.seek -typing(_extensions)?\.IO\.truncate -typing(_extensions)?\.IO\.write -typing(_extensions)?\.IO\.writelines - types.MethodType.__closure__ # read-only but not actually a property; stubtest thinks it doesn't exist. types.MethodType.__code__ # read-only but not actually a property; stubtest thinks it doesn't exist. types.MethodType.__defaults__ # read-only but not actually a property; stubtest thinks it doesn't exist. @@ -499,7 +485,3 @@ xml.etree.ElementTree.XMLParser.__init__ # Defined in C so has general signatur # Iterable classes that don't define __iter__ at runtime (usually iterable via __getitem__) # These would ideally be special-cased by type checkers; see https://github.com/python/mypy/issues/2220 xml.etree.ElementTree.Element.__iter__ - -# These three have a pos-or-keyword first parameter at runtime, but deliberately have a pos-only first parameter in the stub. #6812 -posixpath.join -ntpath.join diff --git a/stdlib/@tests/stubtest_allowlists/darwin-py315.txt b/stdlib/@tests/stubtest_allowlists/darwin-py315.txt new file mode 100644 index 000000000000..3c2820e84ea2 --- /dev/null +++ b/stdlib/@tests/stubtest_allowlists/darwin-py315.txt @@ -0,0 +1,29 @@ +# ============================================ +# TODO: Allowlist entries that should be fixed +# ============================================ + +_decimal.SPEC_VERSION +_pyrepl.fancy_termios +_pyrepl.unix_console +_pyrepl.unix_eventqueue +ctypes.c_double_complex._type_ +ctypes.c_float_complex._type_ +ctypes.c_longdouble_complex._type_ +decimal.SPEC_VERSION +mmap.MS_ASYNC +mmap.MS_INVALIDATE +mmap.MS_SYNC +mmap.mmap.madvise +mmap.mmap.resize +os.NODEV +os.__all__ +posix.NODEV +profiling.sampling.live_collector +profiling.sampling.live_collector.collector +profiling.sampling.live_collector.constants +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 diff --git a/stdlib/@tests/stubtest_allowlists/linux-py315.txt b/stdlib/@tests/stubtest_allowlists/linux-py315.txt new file mode 100644 index 000000000000..0465aecbb8cb --- /dev/null +++ b/stdlib/@tests/stubtest_allowlists/linux-py315.txt @@ -0,0 +1,133 @@ +# ============================================ +# 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_CHK_PAD_DATA +_socket.CAN_ISOTP_CHK_PAD_LEN +_socket.CAN_ISOTP_DEFAULT_EXT_ADDRESS +_socket.CAN_ISOTP_DEFAULT_FLAGS +_socket.CAN_ISOTP_DEFAULT_FRAME_TXTIME +_socket.CAN_ISOTP_DEFAULT_LL_MTU +_socket.CAN_ISOTP_DEFAULT_LL_TX_DL +_socket.CAN_ISOTP_DEFAULT_LL_TX_FLAGS +_socket.CAN_ISOTP_DEFAULT_PAD_CONTENT +_socket.CAN_ISOTP_DEFAULT_RECV_BS +_socket.CAN_ISOTP_DEFAULT_RECV_STMIN +_socket.CAN_ISOTP_DEFAULT_RECV_WFTMAX +_socket.CAN_ISOTP_EXTEND_ADDR +_socket.CAN_ISOTP_FORCE_RXSTMIN +_socket.CAN_ISOTP_FORCE_TXSTMIN +_socket.CAN_ISOTP_HALF_DUPLEX +_socket.CAN_ISOTP_LISTEN_MODE +_socket.CAN_ISOTP_LL_OPTS +_socket.CAN_ISOTP_OPTS +_socket.CAN_ISOTP_RECV_FC +_socket.CAN_ISOTP_RX_EXT_ADDR +_socket.CAN_ISOTP_RX_PADDING +_socket.CAN_ISOTP_RX_STMIN +_socket.CAN_ISOTP_SF_BROADCAST +_socket.CAN_ISOTP_TX_PADDING +_socket.CAN_ISOTP_TX_STMIN +_socket.CAN_ISOTP_WAIT_TX_DONE +_socket.IPV6_HDRINCL +_socket.SOL_CAN_ISOTP +ctypes.c_double_complex._type_ +ctypes.c_float_complex._type_ +ctypes.c_longdouble_complex._type_ +mmap.MS_ASYNC +mmap.MS_INVALIDATE +mmap.MS_SYNC +mmap.mmap.madvise +os.AT_NO_AUTOMOUNT +os.AT_STATX_DONT_SYNC +os.AT_STATX_FORCE_SYNC +os.AT_STATX_SYNC_AS_STAT +os.NODEV +os.STATX_ATIME +os.STATX_BASIC_STATS +os.STATX_BLOCKS +os.STATX_BTIME +os.STATX_CTIME +os.STATX_DIOALIGN +os.STATX_GID +os.STATX_INO +os.STATX_MNT_ID +os.STATX_MNT_ID_UNIQUE +os.STATX_MODE +os.STATX_MTIME +os.STATX_NLINK +os.STATX_SIZE +os.STATX_TYPE +os.STATX_UID +os.__all__ +os._clearenv +os.statx +os.statx_result +posix.AT_NO_AUTOMOUNT +posix.AT_STATX_DONT_SYNC +posix.AT_STATX_FORCE_SYNC +posix.AT_STATX_SYNC_AS_STAT +posix.NODEV +posix.STATX_ATIME +posix.STATX_BASIC_STATS +posix.STATX_BLOCKS +posix.STATX_BTIME +posix.STATX_CTIME +posix.STATX_DIOALIGN +posix.STATX_GID +posix.STATX_INO +posix.STATX_MNT_ID +posix.STATX_MNT_ID_UNIQUE +posix.STATX_MODE +posix.STATX_MTIME +posix.STATX_NLINK +posix.STATX_SIZE +posix.STATX_TYPE +posix.STATX_UID +posix.statx +profiling.sampling.live_collector +profiling.sampling.live_collector.collector +profiling.sampling.live_collector.constants +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_CHK_PAD_DATA +socket.CAN_ISOTP_CHK_PAD_LEN +socket.CAN_ISOTP_DEFAULT_EXT_ADDRESS +socket.CAN_ISOTP_DEFAULT_FLAGS +socket.CAN_ISOTP_DEFAULT_FRAME_TXTIME +socket.CAN_ISOTP_DEFAULT_LL_MTU +socket.CAN_ISOTP_DEFAULT_LL_TX_DL +socket.CAN_ISOTP_DEFAULT_LL_TX_FLAGS +socket.CAN_ISOTP_DEFAULT_PAD_CONTENT +socket.CAN_ISOTP_DEFAULT_RECV_BS +socket.CAN_ISOTP_DEFAULT_RECV_STMIN +socket.CAN_ISOTP_DEFAULT_RECV_WFTMAX +socket.CAN_ISOTP_EXTEND_ADDR +socket.CAN_ISOTP_FORCE_RXSTMIN +socket.CAN_ISOTP_FORCE_TXSTMIN +socket.CAN_ISOTP_HALF_DUPLEX +socket.CAN_ISOTP_LISTEN_MODE +socket.CAN_ISOTP_LL_OPTS +socket.CAN_ISOTP_OPTS +socket.CAN_ISOTP_RECV_FC +socket.CAN_ISOTP_RX_EXT_ADDR +socket.CAN_ISOTP_RX_PADDING +socket.CAN_ISOTP_RX_STMIN +socket.CAN_ISOTP_SF_BROADCAST +socket.CAN_ISOTP_TX_PADDING +socket.CAN_ISOTP_TX_STMIN +socket.CAN_ISOTP_WAIT_TX_DONE +socket.IPV6_HDRINCL +socket.SOL_CAN_ISOTP +socket.__all__ diff --git a/stdlib/@tests/stubtest_allowlists/py310.txt b/stdlib/@tests/stubtest_allowlists/py310.txt index 59266fb81b63..58e826f7081b 100644 --- a/stdlib/@tests/stubtest_allowlists/py310.txt +++ b/stdlib/@tests/stubtest_allowlists/py310.txt @@ -2,7 +2,6 @@ # New errors in Python 3.10 # ========================= - # ========= # 3.10 only # ========= @@ -134,6 +133,35 @@ importlib.abc.Traversable.open # Problematic protocol signature at runtime, see typing_extensions.TypeAliasType.__call__ +# ===== +# <3.15 +# ===== + +tkinter.simpledialog.[A-Z_]+ +tkinter.simpledialog.TclVersion +tkinter.simpledialog.TkVersion + + +# ============================================================= +# Allowlist entries that cannot or should not be fixed; <3.15 +# ============================================================= + +# typing.IO uses positional-or-keyword arguments, but in the stubs we prefer +# to mark these as positional-only for compatibility with existing sub-classes. +typing(_extensions)?\.BinaryIO\.write +typing(_extensions)?\.IO\.read +typing(_extensions)?\.IO\.readline +typing(_extensions)?\.IO\.readlines +typing(_extensions)?\.IO\.seek +typing(_extensions)?\.IO\.truncate +typing(_extensions)?\.IO\.write +typing(_extensions)?\.IO\.writelines + +# These have a pos-or-keyword first parameter at runtime, but deliberately have a pos-only first parameter in the stub. #6812 +posixpath.join +ntpath.join + + # =============================================================== # Allowlist entries that cannot or should not be fixed; 3.10 only # =============================================================== diff --git a/stdlib/@tests/stubtest_allowlists/py311.txt b/stdlib/@tests/stubtest_allowlists/py311.txt index 213240f9933d..11af276eb139 100644 --- a/stdlib/@tests/stubtest_allowlists/py311.txt +++ b/stdlib/@tests/stubtest_allowlists/py311.txt @@ -2,7 +2,6 @@ # New errors in Python 3.11 # ========================= - # ======= # >= 3.11 # ======= @@ -108,6 +107,35 @@ typing_extensions.TypeAliasType.__call__ enum.Enum.__init__ +# ===== +# <3.15 +# ===== + +tkinter.simpledialog.[A-Z_]+ +tkinter.simpledialog.TclVersion +tkinter.simpledialog.TkVersion + + +# ============================================================= +# Allowlist entries that cannot or should not be fixed; <3.15 +# ============================================================= + +# typing.IO uses positional-or-keyword arguments, but in the stubs we prefer +# to mark these as positional-only for compatibility with existing sub-classes. +typing(_extensions)?\.BinaryIO\.write +typing(_extensions)?\.IO\.read +typing(_extensions)?\.IO\.readline +typing(_extensions)?\.IO\.readlines +typing(_extensions)?\.IO\.seek +typing(_extensions)?\.IO\.truncate +typing(_extensions)?\.IO\.write +typing(_extensions)?\.IO\.writelines + +# These have a pos-or-keyword first parameter at runtime, but deliberately have a pos-only first parameter in the stub. #6812 +posixpath.join +ntpath.join + + # ============================================================= # Allowlist entries that cannot or should not be fixed; >= 3.11 # ============================================================= diff --git a/stdlib/@tests/stubtest_allowlists/py312.txt b/stdlib/@tests/stubtest_allowlists/py312.txt index 013cb733440f..1e1fdc9cf15b 100644 --- a/stdlib/@tests/stubtest_allowlists/py312.txt +++ b/stdlib/@tests/stubtest_allowlists/py312.txt @@ -2,7 +2,6 @@ # New errors in Python 3.12 # ========================= - # ======= # >= 3.12 # ======= @@ -101,6 +100,35 @@ _?hashlib.scrypt # Raises TypeError if salt, n, r or p are None typing_extensions.TypeAliasType.__call__ +# ===== +# <3.15 +# ===== + +tkinter.simpledialog.[A-Z_]+ +tkinter.simpledialog.TclVersion +tkinter.simpledialog.TkVersion + + +# ============================================================= +# Allowlist entries that cannot or should not be fixed; <3.15 +# ============================================================= + +# typing.IO uses positional-or-keyword arguments, but in the stubs we prefer +# to mark these as positional-only for compatibility with existing sub-classes. +typing(_extensions)?\.BinaryIO\.write +typing(_extensions)?\.IO\.read +typing(_extensions)?\.IO\.readline +typing(_extensions)?\.IO\.readlines +typing(_extensions)?\.IO\.seek +typing(_extensions)?\.IO\.truncate +typing(_extensions)?\.IO\.write +typing(_extensions)?\.IO\.writelines + +# These have a pos-or-keyword first parameter at runtime, but deliberately have a pos-only first parameter in the stub. #6812 +posixpath.join +ntpath.join + + # ============================================================= # Allowlist entries that cannot or should not be fixed; >= 3.12 # ============================================================= diff --git a/stdlib/@tests/stubtest_allowlists/py313.txt b/stdlib/@tests/stubtest_allowlists/py313.txt index fc531aab7ddb..3929791d4ef4 100644 --- a/stdlib/@tests/stubtest_allowlists/py313.txt +++ b/stdlib/@tests/stubtest_allowlists/py313.txt @@ -2,7 +2,6 @@ # New errors in Python 3.13 # ========================= - # ==================================== # Pre-existing errors from Python 3.12 # ==================================== @@ -54,6 +53,35 @@ _?hashlib.scrypt # Raises TypeError if salt, n, r or p are None typing_extensions.TypeAliasType.__call__ +# ===== +# <3.15 +# ===== + +tkinter.simpledialog.[A-Z_]+ +tkinter.simpledialog.TclVersion +tkinter.simpledialog.TkVersion + + +# ============================================================= +# Allowlist entries that cannot or should not be fixed; <3.15 +# ============================================================= + +# typing.IO uses positional-or-keyword arguments, but in the stubs we prefer +# to mark these as positional-only for compatibility with existing sub-classes. +typing(_extensions)?\.BinaryIO\.write +typing(_extensions)?\.IO\.read +typing(_extensions)?\.IO\.readline +typing(_extensions)?\.IO\.readlines +typing(_extensions)?\.IO\.seek +typing(_extensions)?\.IO\.truncate +typing(_extensions)?\.IO\.write +typing(_extensions)?\.IO\.writelines + +# These have a pos-or-keyword first parameter at runtime, but deliberately have a pos-only first parameter in the stub. #6812 +posixpath.join +ntpath.join + + # ============================================================= # Allowlist entries that cannot or should not be fixed; >= 3.13 # ============================================================= diff --git a/stdlib/@tests/stubtest_allowlists/py314.txt b/stdlib/@tests/stubtest_allowlists/py314.txt index 19d7eb49d6a6..64a6fa7d2752 100644 --- a/stdlib/@tests/stubtest_allowlists/py314.txt +++ b/stdlib/@tests/stubtest_allowlists/py314.txt @@ -53,6 +53,35 @@ types.SimpleNamespace.__delattr__ typing.NewType.__mro_entries__ +# ===== +# <3.15 +# ===== + +tkinter.simpledialog.[A-Z_]+ +tkinter.simpledialog.TclVersion +tkinter.simpledialog.TkVersion + + +# ============================================================= +# Allowlist entries that cannot or should not be fixed; <3.15 +# ============================================================= + +# typing.IO uses positional-or-keyword arguments, but in the stubs we prefer +# to mark these as positional-only for compatibility with existing sub-classes. +typing(_extensions)?\.BinaryIO\.write +typing(_extensions)?\.IO\.read +typing(_extensions)?\.IO\.readline +typing(_extensions)?\.IO\.readlines +typing(_extensions)?\.IO\.seek +typing(_extensions)?\.IO\.truncate +typing(_extensions)?\.IO\.write +typing(_extensions)?\.IO\.writelines + +# These have a pos-or-keyword first parameter at runtime, but deliberately have a pos-only first parameter in the stub. #6812 +posixpath.join +ntpath.join + + # ============================================================= # Allowlist entries that cannot or should not be fixed; >= 3.14 # ============================================================= diff --git a/stdlib/@tests/stubtest_allowlists/py315.txt b/stdlib/@tests/stubtest_allowlists/py315.txt new file mode 100644 index 000000000000..d76872ab2ebb --- /dev/null +++ b/stdlib/@tests/stubtest_allowlists/py315.txt @@ -0,0 +1,448 @@ +# ============================================ +# TODO: Allowlist entries that should be fixed +# ============================================ + +_collections_abc.__all__ +_frozen_importlib.BuiltinImporter.load_module +_frozen_importlib.FrozenImporter.load_module +_frozen_importlib_external.FileFinder.discover +_frozen_importlib_external.NamespaceLoader.load_module +_frozen_importlib_external.NamespacePath +_frozen_importlib_external.PathFinder.discover +_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 +_json.make_scanner.array_hook +_json.scanstring +_pydecimal.SPEC_VERSION +_pydecimal.__all__ +_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 +_sqlite3.SQLITE_KEYWORDS +_ssl.HAS_PSK_TLS13 +_ssl._SSLContext.get_groups +_ssl._SSLContext.set_ciphersuites +_ssl._SSLContext.set_client_sigalgs +_ssl._SSLContext.set_groups +_ssl._SSLContext.set_server_sigalgs +_ssl.get_sigalgs +_struct.Struct.pack_into +_struct.pack +_struct.pack_into +_thread.RLock.__exit__ +_thread.lock.__exit__ +annotationlib.ForwardRef.__arg__ +annotationlib.ForwardRef.__ast_node__ +annotationlib.ForwardRef.__cell__ +annotationlib.ForwardRef.__code__ +annotationlib.ForwardRef.__extra_names__ +annotationlib.ForwardRef.__globals__ +annotationlib.ForwardRef.__init_subclass__ +annotationlib.ForwardRef.__owner__ +annotationlib.ForwardRef.__resolved_str__ +annotationlib.ForwardRef.__resolved_str_cache__ +annotationlib.ForwardRef.__slots__ +annotationlib.ForwardRef.__stringifier_dict__ +argparse.ArgumentParser.__init__ +argparse.ArgumentParser._get_formatter +argparse.ArgumentParser.format_help +argparse.ArgumentParser.format_usage +argparse.HelpFormatter.__init__ +array.typecodes +ast.DictComp.value +ast.Import.__match_args__ +ast.Import.is_lazy +ast.ImportFrom.__match_args__ +ast.ImportFrom.is_lazy +ast.dump +ast.parse +ast.type_param.__init__ +asyncio.taskgroups.TaskGroup.cancel +asyncio.tools.display_awaited_by_tasks_table +asyncio.tools.display_awaited_by_tasks_tree +base64.a85decode +base64.b16decode +base64.b16encode +base64.b32decode +base64.b32encode +base64.b32hexdecode +base64.b32hexencode +base64.b64decode +base64.b64encode +base64.b85decode +base64.b85encode +base64.urlsafe_b64decode +base64.urlsafe_b64encode +base64.z85decode +base64.z85encode +binascii.ASCII85_ALPHABET +binascii.BASE32HEX_ALPHABET +binascii.BASE32_ALPHABET +binascii.BASE64_ALPHABET +binascii.BASE85_ALPHABET +binascii.BINHEX_ALPHABET +binascii.CRYPT_ALPHABET +binascii.URLSAFE_BASE64_ALPHABET +binascii.UU_ALPHABET +binascii.Z85_ALPHABET +binascii.a2b_ascii85 +binascii.a2b_base32 +binascii.a2b_base64 +binascii.a2b_base85 +binascii.a2b_hex +binascii.b2a_ascii85 +binascii.b2a_base32 +binascii.b2a_base64 +binascii.b2a_base85 +binascii.unhexlify +builtins.ImportCycleError +builtins.__lazy_import__ +builtins.bin +builtins.bytearray.replace +builtins.bytearray.take_bytes +builtins.bytes.replace +builtins.compile +builtins.frozendict +builtins.hex +builtins.oct +builtins.sentinel +builtins.slice.__class_getitem__ +cProfile.label +calendar.HTMLCalendar.formatmonthpage +calendar.__all__ +calendar.standalone_month_abbr +calendar.standalone_month_name +codecs.backslashreplace_errors +codecs.ignore_errors +codecs.namereplace_errors +codecs.replace_errors +codecs.strict_errors +codecs.xmlcharrefreplace_errors +collections.Counter.__ixor__ +collections.Counter.__xor__ +collections.abc.__all__ +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__ +copy.deepcopy +ctypes.SetPointerType +dataclasses._MISSING_TYPE +datetime.date.fromisoformat +datetime.date.strptime +datetime.datetime.fromisoformat +datetime.datetime.strptime +datetime.time.fromisoformat +datetime.time.strptime +dbm.dumb._Database.reorganize +dbm.sqlite3.REORGANIZE +dbm.sqlite3._Database.reorganize +difflib.unified_diff +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 +hashlib.__all__ +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 +json.decoder.JSONDecoder.__init__ +json.load +json.loads +mailbox.Mailbox.__enter__ +mailbox.Mailbox.__exit__ +mailbox._ProxyFile.__class_getitem__ +marshal.dump +marshal.dumps +math.fmax +math.fmin +math.isnormal +math.issubnormal +math.signbit +mmap.mmap.find +mmap.mmap.flush +mmap.mmap.rfind +mmap.mmap.set_name +multiprocessing.context.BaseContext.set_forkserver_preload +multiprocessing.forkserver.ForkServer.set_forkserver_preload +multiprocessing.forkserver.main +multiprocessing.managers.BaseListProxy.clear +multiprocessing.managers.BaseListProxy.copy +multiprocessing.managers._BaseDictProxy.__iter__ +multiprocessing.managers._BaseDictProxy.__len__ +multiprocessing.managers._BaseDictProxy.__reversed__ +multiprocessing.managers._BaseDictProxy.clear +multiprocessing.managers._BaseDictProxy.copy +multiprocessing.managers._BaseDictProxy.items +multiprocessing.managers._BaseDictProxy.keys +multiprocessing.managers._BaseDictProxy.popitem +multiprocessing.managers._BaseDictProxy.values +multiprocessing.managers._BaseSetProxy.__iter__ +multiprocessing.managers._BaseSetProxy.__len__ +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 +platform.java_ver +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 +pstats.Stats.print_call_subheading +pydoc.Doc.STDLIB_DIR +pydoc.Doc.getdocloc +pyexpat.XMLParserType.SetBillionLaughsAttackProtectionActivationThreshold +pyexpat.XMLParserType.SetBillionLaughsAttackProtectionMaximumAmplification +re.Pattern.prefixmatch +re.__all__ +re.prefixmatch +shelve.BsdDbShelf.__init__ +shelve.DbfilenameShelf.__init__ +shelve.Shelf.__init__ +shelve.Shelf.reorganize +shelve.ShelveError +shelve.__all__ +shelve.open +site.addsitedir +site.addsitepackages +site.addusersitepackages +site.process_startup_files +sqlite3.Connection.create_aggregate +sqlite3.Connection.create_function +sqlite3.Connection.set_authorizer +sqlite3.Connection.set_progress_handler +sqlite3.Connection.set_trace_callback +sqlite3.SQLITE_KEYWORDS +sqlite3.dbapi2.SQLITE_KEYWORDS +sre_compile +sre_constants +sre_parse +ssl.SSLObject.client_sigalg +ssl.SSLObject.group +ssl.SSLObject.server_sigalg +ssl.SSLSocket.client_sigalg +ssl.SSLSocket.group +ssl.SSLSocket.server_sigalg +stat.STATX_ATTR_APPEND +stat.STATX_ATTR_AUTOMOUNT +stat.STATX_ATTR_COMPRESSED +stat.STATX_ATTR_DAX +stat.STATX_ATTR_ENCRYPTED +stat.STATX_ATTR_IMMUTABLE +stat.STATX_ATTR_MOUNT_ROOT +stat.STATX_ATTR_NODUMP +stat.STATX_ATTR_VERITY +stat.STATX_ATTR_WRITE_ATOMIC +symtable.Function.get_cells +symtable.Symbol.is_cell +symtable.symtable +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 +sysconfig.is_python_build +tarfile.TarFile.__init__ +threading.Condition.locked +threading.__all__ +threading.concurrent_tee +threading.serialize_iterator +threading.synchronized_iterator +timeit.Timer.autorange +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 +types.MappingProxyType.get +types.SimpleNamespace.__delattr__ +types.SimpleNamespace.__setattr__ +types.UnionType.__class_getitem__ +types.UnionType.__mro_entries__ +types.UnionType.__name__ +types.UnionType.__qualname__ +types.__all__ +typing.LiteralString +typing.NewType.__mro_entries__ +typing.NoExtraItems +typing.ParamSpec.__mro_entries__ +typing.ParamSpecArgs.__mro_entries__ +typing.ParamSpecKwargs.__mro_entries__ +typing.SupportsAbs.__type_params__ +typing.SupportsRound.__type_params__ +typing.TypeAliasType.__qualname__ +typing.TypeForm +typing.TypeVar.__mro_entries__ +typing.TypeVarTuple.__bound__ +typing.TypeVarTuple.__contravariant__ +typing.TypeVarTuple.__covariant__ +typing.TypeVarTuple.__infer_variance__ +typing.TypeVarTuple.__mro_entries__ +typing.Union +typing._SpecialForm.__mro_entries__ +typing.__all__ +typing.disjoint_base +typing.no_type_check_decorator +typing_extensions.Protocol +unicodedata.block +unicodedata.extended_pictographic +unicodedata.grapheme_cluster_break +unicodedata.indic_conjunct_break +unicodedata.isxidcontinue +unicodedata.isxidstart +unicodedata.iter_graphemes +unittest._log._AssertLogsContext.__init__ +unittest.case.TestCase.assertLogs +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 +warnings.WarningMessage.__init__ +wave.WAVE_FORMAT_EXTENSIBLE +wave.WAVE_FORMAT_IEEE_FLOAT +wave.Wave_read.getformat +wave.Wave_read.getmark +wave.Wave_read.getmarkers +wave.Wave_write.getformat +wave.Wave_write.getmark +wave.Wave_write.getmarkers +wave.Wave_write.setformat +wave.Wave_write.setmark +wave.__all__ +xml.etree.ElementTree.__all__ +xml.is_valid_name +xml.utils +zipimport.zipimporter.load_module +zlib.adler32_combine +zlib.crc32_combine diff --git a/stdlib/@tests/stubtest_allowlists/win32-py315.txt b/stdlib/@tests/stubtest_allowlists/win32-py315.txt new file mode 100644 index 000000000000..c8d924c64747 --- /dev/null +++ b/stdlib/@tests/stubtest_allowlists/win32-py315.txt @@ -0,0 +1,21 @@ +# ============================================ +# TODO: Allowlist entries that should be fixed +# ============================================ + +_decimal.SPEC_VERSION +_socket.IPV6_HDRINCL +_winapi.DeregisterEventSource +_winapi.EVENTLOG_AUDIT_FAILURE +_winapi.EVENTLOG_AUDIT_SUCCESS +_winapi.EVENTLOG_ERROR_TYPE +_winapi.EVENTLOG_INFORMATION_TYPE +_winapi.EVENTLOG_SUCCESS +_winapi.EVENTLOG_WARNING_TYPE +_winapi.GetOEMCP +_winapi.RegisterEventSource +_winapi.ReportEvent +asyncio.windows_events.IocpProactor.finish_socket_func +decimal.SPEC_VERSION +socket.IPV6_HDRINCL +socket.__all__ +winreg.DeleteTree diff --git a/tests/mypy_test.py b/tests/mypy_test.py index c9b3993839b9..1fd8a87f2618 100755 --- a/tests/mypy_test.py +++ b/tests/mypy_test.py @@ -23,6 +23,7 @@ from ts_utils.metadata import PackageDependencies, get_recursive_requirements, read_metadata from ts_utils.mypy import MypyDistConf, mypy_configuration_from_distribution, temporary_mypy_config_file from ts_utils.paths import STDLIB_PATH, STUBS_PATH, TESTS_DIR, TS_BASE_PATH, distribution_path +from ts_utils.py315 import PY315_INCOMPATIBLE_RUNTIME_DEPENDENCIES from ts_utils.utils import ( PYTHON_VERSION, colored, @@ -43,7 +44,7 @@ print_error("Cannot import mypy. Did you install it?") sys.exit(1) -SUPPORTED_VERSIONS = ["3.14", "3.13", "3.12", "3.11", "3.10"] +SUPPORTED_VERSIONS = ["3.15", "3.14", "3.13", "3.12", "3.11", "3.10"] SUPPORTED_PLATFORMS = ("linux", "win32", "darwin") DIRECTORIES_TO_TEST = [STDLIB_PATH, STUBS_PATH] @@ -493,7 +494,17 @@ def test_third_party_stubs(args: TestConfig, tempdir: Path) -> TestSummary: summary.skip_package() continue - distributions_to_check[distribution] = get_recursive_requirements(distribution) + requirements = get_recursive_requirements(distribution) + if args.version == "3.15" and distribution in PY315_INCOMPATIBLE_RUNTIME_DEPENDENCIES: + msg = ( + f"skipping {distribution!r} for target Python {args.version} " + "(runtime dependencies do not support 3.15 yet)" + ) + print(colored(msg, "yellow")) + summary.skip_package() + continue + + distributions_to_check[distribution] = requirements # Setup the necessary virtual environments for testing the third-party stubs. # Note that some stubs may not be tested on all Python versions diff --git a/tests/regr_test.py b/tests/regr_test.py index 39381c676062..196176b14576 100755 --- a/tests/regr_test.py +++ b/tests/regr_test.py @@ -24,6 +24,7 @@ from ts_utils.metadata import get_recursive_requirements, read_metadata from ts_utils.mypy import mypy_configuration_from_distribution, temporary_mypy_config_file from ts_utils.paths import STDLIB_PATH, TEST_CASES_DIR, TS_BASE_PATH, distribution_path +from ts_utils.py315 import PY315_INCOMPATIBLE_RUNTIME_DEPENDENCIES from ts_utils.utils import ( PYTHON_VERSION, DistributionTests, @@ -41,7 +42,7 @@ TYPESHED = "typeshed" SUPPORTED_PLATFORMS = ["linux", "darwin", "win32"] -SUPPORTED_VERSIONS = ["3.14", "3.13", "3.12", "3.11", "3.10"] +SUPPORTED_VERSIONS = ["3.15", "3.14", "3.13", "3.12", "3.11", "3.10"] def distribution_with_test_cases(distribution_name: str) -> DistributionTests: @@ -190,9 +191,11 @@ def run_testcases( "--pretty", "--config-file", temp.name, - # Avoid race conditions when reading the cache - # (https://github.com/python/typeshed/issues/11220) + # Avoid race conditions when using the cache + # https://github.com/python/mypy/issues/13916 "--no-incremental", + "--cache-dir", + str(tempdir / ".mypy_cache" / version / platform), # Not useful for the test cases "--disable-error-code=empty-body", ] @@ -304,6 +307,10 @@ def concurrently_run_testcases( pkg = testcase_dir.name requires_python = None if not testcase_dir.is_stdlib: + if PYTHON_VERSION == "3.15" and pkg in PY315_INCOMPATIBLE_RUNTIME_DEPENDENCIES: + msg = f"skipping {pkg!r} test cases (runtime dependencies do not support 3.15 yet)" + print(colored(msg, "yellow")) + continue requires_python = read_metadata(pkg).requires_python if not requires_python.contains(PYTHON_VERSION): msg = f"skipping {pkg!r} (requires Python {requires_python}; test is being run using Python {PYTHON_VERSION})" diff --git a/tests/runtests.py b/tests/runtests.py index 41fa0da67a6f..9da379b723a6 100755 --- a/tests/runtests.py +++ b/tests/runtests.py @@ -50,7 +50,7 @@ def main() -> None: parser.add_argument( "--python-version", default=None, - choices=("3.10", "3.11", "3.12", "3.13", "3.14"), + choices=("3.10", "3.11", "3.12", "3.13", "3.14", "3.15"), # We're using the oldest fully supported version because it's the most likely to produce errors # due to unsupported syntax, feature, or bug in a tool. help="Target Python version for the test (defaults to oldest supported Python version).", diff --git a/tests/typecheck_typeshed.py b/tests/typecheck_typeshed.py index 6ddbb90a8a5b..cbb16b1b9e9e 100755 --- a/tests/typecheck_typeshed.py +++ b/tests/typecheck_typeshed.py @@ -14,7 +14,7 @@ ReturnCode: TypeAlias = int SUPPORTED_PLATFORMS = ("linux", "darwin", "win32") -SUPPORTED_VERSIONS = ("3.14", "3.13", "3.12", "3.11", "3.10") +SUPPORTED_VERSIONS = ("3.15", "3.14", "3.13", "3.12", "3.11", "3.10") LOWEST_SUPPORTED_VERSION = min(SUPPORTED_VERSIONS, key=lambda x: int(x.split(".")[1])) DIRECTORIES_TO_TEST = ("scripts", "tests") EMPTY: list[str] = []