diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index d7b04f4d20..e31d33cdd9 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -24,7 +24,7 @@ repos: hooks: - id: black - repo: https://github.com/astral-sh/ruff-pre-commit - rev: v0.17.1 + rev: v0.17.2 hooks: - id: ruff-check types: [file] @@ -69,7 +69,7 @@ repos: additional_dependencies: ["pyyaml"] files: ^(test-requirements\.txt)|(\.pre-commit-config\.yaml)$ - repo: https://github.com/astral-sh/uv-pre-commit - rev: 0.13.1 + rev: 0.13.5 hooks: # Compile requirements - id: pip-compile diff --git a/docs-requirements.txt b/docs-requirements.txt index 5342b39e68..a75cb2601b 100644 --- a/docs-requirements.txt +++ b/docs-requirements.txt @@ -10,7 +10,7 @@ babel==2.18.0 # via sphinx beautifulsoup4==4.15.0 # via sphinx-codeautolink -certifi==2026.7.22 +certifi==2026.10.23 # via requests cffi==2.1.1 ; os_name == 'nt' or platform_python_implementation != 'PyPy' # via @@ -43,13 +43,13 @@ jinja2==3.1.6 # -r docs-requirements.in # sphinx # towncrier -markupsafe==3.0.3 +markupsafe==3.0.4 # via jinja2 outcome==1.3.0.post0 # via -r docs-requirements.in packaging==26.3 # via sphinx -pycparser==3.0 ; (implementation_name != 'PyPy' and os_name == 'nt') or (implementation_name != 'PyPy' and platform_python_implementation != 'PyPy') +pycparser==3.12 ; (implementation_name != 'PyPy' and os_name == 'nt') or (implementation_name != 'PyPy' and platform_python_implementation != 'PyPy') # via cffi pygments==2.21.0 # via sphinx @@ -65,7 +65,9 @@ snowballstemmer==3.1.1 # via sphinx sortedcontainers==2.4.0 # via -r docs-requirements.in -soupsieve==2.10 +soupsieve==2.10 ; python_full_version < '3.11.5' + # via beautifulsoup4 +soupsieve==3.0.4 ; python_full_version >= '3.11.5' # via beautifulsoup4 sphinx==9.0.4 ; python_full_version < '3.12' # via @@ -74,7 +76,14 @@ sphinx==9.0.4 ; python_full_version < '3.12' # sphinx-rtd-theme # sphinxcontrib-jquery # sphinxcontrib-trio -sphinx==9.1.0 ; python_full_version >= '3.12' +sphinx==9.1.1 ; python_full_version == '3.12.*' + # via + # -r docs-requirements.in + # sphinx-codeautolink + # sphinx-rtd-theme + # sphinxcontrib-jquery + # sphinxcontrib-trio +sphinx==9.2.0 ; python_full_version >= '3.13' # via # -r docs-requirements.in # sphinx-codeautolink @@ -95,7 +104,7 @@ sphinxcontrib-jquery==4.1 # via # -r docs-requirements.in # sphinx-rtd-theme -sphinxcontrib-jsmath==1.0.1 +sphinxcontrib-jsmath==2.0.0 # via sphinx sphinxcontrib-qthelp==2.0.0 # via sphinx diff --git a/src/trio/_abc.py b/src/trio/_abc.py index abb6824381..2036f297f9 100644 --- a/src/trio/_abc.py +++ b/src/trio/_abc.py @@ -2,7 +2,7 @@ import socket from abc import ABC, abstractmethod -from typing import TYPE_CHECKING, Generic, TypeVar +from typing import TYPE_CHECKING, Generic, Literal, TypeVar import trio @@ -173,12 +173,20 @@ async def getaddrinfo( proto: int = 0, flags: int = 0, ) -> list[ + # copied from _GetAddrInfoEntry tuple[ - socket.AddressFamily, + Literal[socket.AddressFamily.AF_INET], socket.SocketKind, int, str, - tuple[str, int] | tuple[str, int, int, int] | tuple[int, bytes], + tuple[str, int], + ] + | tuple[ + Literal[socket.AddressFamily.AF_INET6], + socket.SocketKind, + int, + str, + tuple[str, int, int, int] | tuple[int, bytes], ] ]: """A custom implementation of :func:`~trio.socket.getaddrinfo`. diff --git a/src/trio/_dtls.py b/src/trio/_dtls.py index f6ffc31c65..a789038257 100644 --- a/src/trio/_dtls.py +++ b/src/trio/_dtls.py @@ -841,7 +841,7 @@ def __init__( self.endpoint = endpoint self.peer_address = peer_address self._packets_dropped_in_trio = 0 - self._client_hello = None + self._client_hello: tuple[bytes, bytes] | None = None self._did_handshake = False self._ssl = SSL.Connection(ctx) self._handshake_mtu = 0 diff --git a/src/trio/_highlevel_open_tcp_stream.py b/src/trio/_highlevel_open_tcp_stream.py index 82ffcb3e9a..400bc52834 100644 --- a/src/trio/_highlevel_open_tcp_stream.py +++ b/src/trio/_highlevel_open_tcp_stream.py @@ -2,7 +2,7 @@ import sys from contextlib import contextmanager, suppress -from typing import TYPE_CHECKING, Any +from typing import TYPE_CHECKING import trio from trio.socket import SOCK_STREAM, SocketType, getaddrinfo, socket @@ -11,7 +11,7 @@ from collections.abc import Generator, MutableSequence from socket import AddressFamily, SocketKind - from trio._socket import AddressFormat + from trio._socket import AddressFormat, _GetAddrInfoEntry if sys.version_info < (3, 11): from exceptiongroup import BaseExceptionGroup, ExceptionGroup @@ -134,8 +134,8 @@ def close_all() -> Generator[set[SocketType], None, None]: raise BaseExceptionGroup("", errs) -def reorder_for_rfc_6555_section_5_4( # type: ignore[explicit-any] - targets: MutableSequence[tuple[AddressFamily, SocketKind, int, str, Any]], +def reorder_for_rfc_6555_section_5_4( + targets: MutableSequence[_GetAddrInfoEntry], ) -> None: # RFC 6555 section 5.4 says that if getaddrinfo returns multiple address # families (e.g. IPv4 and IPv6), then you should make sure that your first diff --git a/src/trio/_socket.py b/src/trio/_socket.py index 504874553a..a29a24dbfd 100644 --- a/src/trio/_socket.py +++ b/src/trio/_socket.py @@ -10,6 +10,7 @@ TYPE_CHECKING, Any, Concatenate, + Literal, SupportsIndex, TypeAlias, TypeVar, @@ -49,6 +50,25 @@ # but instead we simply do: AddressFormat: TypeAlias = Any # type: ignore[explicit-any] +# typeshed defines _GetAddrInfoResult but we would rather manipulate the inner +# entry type... as well as use a type defined at runtime! +_GetAddrInfoEntry: TypeAlias = ( # noqa: PYI047 + tuple[ + Literal[AddressFamily.AF_INET], + SocketKind, + int, + str, + tuple[str, int], + ] + | tuple[ + Literal[AddressFamily.AF_INET6], + SocketKind, + int, + str, + tuple[str, int, int, int] | tuple[int, bytes], + ] +) + # Usage: # @@ -180,12 +200,20 @@ async def getaddrinfo( proto: int = 0, flags: int = 0, ) -> list[ + # copied from _GetAddrInfoEntry tuple[ - AddressFamily, + Literal[AddressFamily.AF_INET], + SocketKind, + int, + str, + tuple[str, int], + ] + | tuple[ + Literal[AddressFamily.AF_INET6], SocketKind, int, str, - tuple[str, int] | tuple[str, int, int, int] | tuple[int, bytes], + tuple[str, int, int, int] | tuple[int, bytes], ] ]: """Look up a numeric address given a name. diff --git a/src/trio/_tests/test_exports.py b/src/trio/_tests/test_exports.py index 838f5162b7..dbd96adfda 100644 --- a/src/trio/_tests/test_exports.py +++ b/src/trio/_tests/test_exports.py @@ -33,7 +33,7 @@ try: # If installed, check both versions of this class. from typing_extensions import Protocol as Protocol_ext except ImportError: # pragma: no cover - Protocol_ext = Protocol + Protocol_ext = Protocol # type: ignore[assignment] def _ensure_mypy_cache_updated() -> None: diff --git a/src/trio/_tests/test_highlevel_open_tcp_listeners.py b/src/trio/_tests/test_highlevel_open_tcp_listeners.py index 41ad77a5f5..5c5a50c6cd 100644 --- a/src/trio/_tests/test_highlevel_open_tcp_listeners.py +++ b/src/trio/_tests/test_highlevel_open_tcp_listeners.py @@ -4,7 +4,7 @@ import socket as stdlib_socket import sys from socket import AddressFamily, SocketKind -from typing import TYPE_CHECKING, cast, overload +from typing import TYPE_CHECKING, Literal, cast, overload import attrs import pytest @@ -30,7 +30,7 @@ from typing_extensions import Buffer - from trio._socket import AddressFormat + from trio._socket import AddressFormat, _GetAddrInfoEntry async def test_open_tcp_listeners_basic() -> None: @@ -242,7 +242,9 @@ def socket( @attrs.define(slots=False) class FakeHostnameResolver(HostnameResolver): - family_addr_pairs: Sequence[tuple[AddressFamily, str]] + family_addr_pairs: Sequence[ + tuple[Literal[AddressFamily.AF_INET, AddressFamily.AF_INET6], str] + ] async def getaddrinfo( self, @@ -252,18 +254,14 @@ async def getaddrinfo( type: int = 0, proto: int = 0, flags: int = 0, - ) -> list[ - tuple[ - AddressFamily, - SocketKind, - int, - str, - tuple[str, int] | tuple[str, int, int, int] | tuple[int, bytes], - ] - ]: + ) -> list[_GetAddrInfoEntry]: assert isinstance(port, int) return [ - (family, tsocket.SOCK_STREAM, 0, "", (addr, port)) + ( + (family, tsocket.SOCK_STREAM, 0, "", (addr, port)) + if family is AddressFamily.AF_INET + else (family, tsocket.SOCK_STREAM, 0, "", (addr, port, 0, 0)) + ) for family, addr in self.family_addr_pairs ] @@ -333,7 +331,7 @@ async def handler(stream: SendStream) -> None: [{tsocket.AF_INET}, {tsocket.AF_INET6}, {tsocket.AF_INET, tsocket.AF_INET6}], ) async def test_open_tcp_listeners_some_address_families_unavailable( - try_families: set[AddressFamily], + try_families: set[Literal[AddressFamily.AF_INET, AddressFamily.AF_INET6]], fail_families: set[AddressFamily], ) -> None: fsf = FakeSocketFactory( @@ -360,6 +358,10 @@ async def test_open_tcp_listeners_some_address_families_unavailable( else: listeners = await open_tcp_listeners(80) for listener in listeners: + assert ( + listener.socket.family is AddressFamily.AF_INET + or listener.socket.family is AddressFamily.AF_INET6 + ) should_succeed.remove(listener.socket.family) assert not should_succeed diff --git a/src/trio/_tests/test_highlevel_open_tcp_stream.py b/src/trio/_tests/test_highlevel_open_tcp_stream.py index 193bf77e75..3c9ae9e593 100644 --- a/src/trio/_tests/test_highlevel_open_tcp_stream.py +++ b/src/trio/_tests/test_highlevel_open_tcp_stream.py @@ -3,7 +3,7 @@ import socket import sys from socket import AddressFamily, SocketKind -from typing import TYPE_CHECKING +from typing import TYPE_CHECKING, Literal import attrs import pytest @@ -20,6 +20,7 @@ if TYPE_CHECKING: from collections.abc import Sequence + from trio._socket import _GetAddrInfoEntry from trio.testing import MockClock if sys.version_info < (3, 11): @@ -60,7 +61,7 @@ def close(self) -> None: def test_reorder_for_rfc_6555_section_5_4() -> None: def fake4( i: int, - ) -> tuple[socket.AddressFamily, socket.SocketKind, int, str, tuple[str, int]]: + ) -> _GetAddrInfoEntry: return ( AF_INET, SOCK_STREAM, @@ -71,8 +72,14 @@ def fake4( def fake6( i: int, - ) -> tuple[socket.AddressFamily, socket.SocketKind, int, str, tuple[str, int]]: - return (AF_INET6, SOCK_STREAM, IPPROTO_TCP, "", (f"::{i}", 80)) + ) -> tuple[ + Literal[AddressFamily.AF_INET6], + SocketKind, + int, + str, + tuple[str, int, int, int] | tuple[int, bytes], + ]: + return (AF_INET6, SOCK_STREAM, IPPROTO_TCP, "", (f"::{i}", 80, 0, 0)) for fake in fake4, fake6: # No effect on homogeneous lists @@ -281,21 +288,17 @@ def socket( self.socket_count += 1 return FakeSocket(self, family, type_, proto) - def _ip_to_gai_entry(self, ip: str) -> tuple[ - AddressFamily, - SocketKind, - int, - str, - tuple[str, int, int, int] | tuple[str, int] | tuple[int, bytes], - ]: - sockaddr: tuple[str, int] | tuple[str, int, int, int] | tuple[int, bytes] + def _ip_to_gai_entry(self, ip: str) -> _GetAddrInfoEntry: if ":" in ip: - family = trio.socket.AF_INET6 - sockaddr = (ip, self.port, 0, 0) + return ( + trio.socket.AF_INET6, + SOCK_STREAM, + IPPROTO_TCP, + "", + (ip, self.port, 0, 0), + ) else: - family = trio.socket.AF_INET - sockaddr = (ip, self.port) - return (family, SOCK_STREAM, IPPROTO_TCP, "", sockaddr) + return (trio.socket.AF_INET, SOCK_STREAM, IPPROTO_TCP, "", (ip, self.port)) async def getaddrinfo( self, @@ -305,15 +308,7 @@ async def getaddrinfo( type: int = -1, proto: int = -1, flags: int = -1, - ) -> list[ - tuple[ - AddressFamily, - SocketKind, - int, - str, - tuple[str, int, int, int] | tuple[str, int] | tuple[int, bytes], - ] - ]: + ) -> list[_GetAddrInfoEntry]: assert host == b"test.example.com" assert port == self.port assert family == trio.socket.AF_UNSPEC diff --git a/src/trio/_tests/test_highlevel_ssl_helpers.py b/src/trio/_tests/test_highlevel_ssl_helpers.py index 2d7f39372d..80b5e30fab 100644 --- a/src/trio/_tests/test_highlevel_ssl_helpers.py +++ b/src/trio/_tests/test_highlevel_ssl_helpers.py @@ -19,12 +19,12 @@ from .test_ssl import SERVER_CTX, client_ctx # noqa: F401 if TYPE_CHECKING: - from socket import AddressFamily, SocketKind from ssl import SSLContext from trio.abc import Stream from .._highlevel_socket import SocketListener + from .._socket import _GetAddrInfoEntry from .._ssl import SSLListener @@ -44,7 +44,7 @@ async def echo_handler(stream: Stream) -> None: # you ask for. @attrs.define(slots=False) class FakeHostnameResolver(trio.abc.HostnameResolver): - sockaddr: tuple[str, int] | tuple[str, int, int, int] | tuple[int, bytes] + sockaddr: tuple[str, int] async def getaddrinfo( self, @@ -54,15 +54,7 @@ async def getaddrinfo( type: int = 0, proto: int = 0, flags: int = 0, - ) -> list[ - tuple[ - AddressFamily, - SocketKind, - int, - str, - tuple[str, int] | tuple[str, int, int, int] | tuple[int, bytes], - ] - ]: + ) -> list[_GetAddrInfoEntry]: return [(AF_INET, SOCK_STREAM, IPPROTO_TCP, "", self.sockaddr)] async def getnameinfo( diff --git a/src/trio/_tests/test_socket.py b/src/trio/_tests/test_socket.py index 03918b0e1f..6c8e12d1d0 100644 --- a/src/trio/_tests/test_socket.py +++ b/src/trio/_tests/test_socket.py @@ -15,7 +15,14 @@ from .. import _core, socket as tsocket from .._core._tests.tutil import binds_ipv6, can_create_ipv6, creates_ipv6, slow -from .._socket import _NUMERIC_ONLY, AddressFormat, SocketType, _SocketType, _try_sync +from .._socket import ( + _NUMERIC_ONLY, + AddressFormat, + SocketType, + _GetAddrInfoEntry, + _SocketType, + _try_sync, +) from ..testing import assert_checkpoints, wait_all_tasks_blocked if TYPE_CHECKING: @@ -23,14 +30,7 @@ from .._highlevel_socket import SocketStream - GaiTuple: TypeAlias = tuple[ - AddressFamily, - SocketKind, - int, - str, - tuple[str, int] | tuple[str, int, int, int] | tuple[int, bytes], - ] - GetAddrInfoResponse: TypeAlias = list[GaiTuple] + GetAddrInfoResponse: TypeAlias = list[_GetAddrInfoEntry] GetAddrInfoArgs: TypeAlias = tuple[ str | bytes | None, str | bytes | int | None, @@ -180,7 +180,7 @@ def check(got: GetAddrInfoResponse, expected: GetAddrInfoResponse) -> None: # Neither field gets used much and there isn't much opportunity for us # to mess them up, so we don't bother checking them here def interesting_fields( - gai_tup: GaiTuple, + gai_tup: _GetAddrInfoEntry, ) -> tuple[ AddressFamily, SocketKind, diff --git a/src/trio/testing/_fake_net.py b/src/trio/testing/_fake_net.py index 4fed1b0bda..82d14f590d 100644 --- a/src/trio/testing/_fake_net.py +++ b/src/trio/testing/_fake_net.py @@ -29,7 +29,7 @@ from typing_extensions import Buffer, Self - from trio._socket import AddressFormat + from trio._socket import AddressFormat, _GetAddrInfoEntry IPAddress: TypeAlias = ipaddress.IPv4Address | ipaddress.IPv6Address @@ -139,15 +139,7 @@ async def getaddrinfo( type: int = 0, proto: int = 0, flags: int = 0, - ) -> list[ - tuple[ - AddressFamily, - SocketKind, - int, - str, - tuple[str, int] | tuple[str, int, int, int] | tuple[int, bytes], - ] - ]: + ) -> list[_GetAddrInfoEntry]: raise NotImplementedError("FakeNet doesn't do fake DNS yet") async def getnameinfo( diff --git a/test-requirements.txt b/test-requirements.txt index a12a9a041b..0509b690a1 100644 --- a/test-requirements.txt +++ b/test-requirements.txt @@ -2,11 +2,11 @@ # uv pip compile --universal --python-version=3.10 test-requirements.in -o test-requirements.txt alabaster==1.0.0 # via sphinx -ast-serialize==0.11.2 ; implementation_name == 'cpython' +ast-serialize==0.13.1 ; implementation_name == 'cpython' # via mypy astor==0.8.1 # via -r test-requirements.in -astroid==4.3.3 +astroid==4.3.4 # via pylint async-generator==1.10 # via -r test-requirements.in @@ -18,7 +18,7 @@ babel==2.18.0 # via sphinx black==26.10.1 ; implementation_name == 'cpython' # via -r test-requirements.in -certifi==2026.7.22 +certifi==2026.10.23 # via requests cffi==2.1.1 ; os_name == 'nt' or platform_python_implementation != 'PyPy' # via @@ -37,7 +37,9 @@ colorama==0.4.6 ; sys_platform == 'win32' # pylint # pytest # sphinx -coverage==7.16.2 +coverage==7.16.2 ; python_full_version < '3.11' + # via -r test-requirements.in +coverage==7.17.0 ; python_full_version >= '3.11' # via -r test-requirements.in cryptography==50.0.2 # via @@ -47,17 +49,23 @@ cryptography==50.0.2 # types-pyopenssl dill==0.4.1 # via pylint -distlib==0.4.3 +distlib==0.4.4 # via virtualenv docutils==0.21.2 ; python_full_version < '3.11' # via sphinx -docutils==0.22.4 ; python_full_version >= '3.11' +docutils==0.22.4 ; python_full_version >= '3.11' and python_full_version < '3.13' + # via sphinx +docutils==0.23 ; python_full_version >= '3.13' # via sphinx exceptiongroup==1.3.1 ; python_full_version < '3.11' # via # -r test-requirements.in # pytest -filelock==4.0.7 +filelock==4.1.0 ; python_full_version < '3.11' + # via + # python-discovery + # virtualenv +filelock==4.2.4 ; python_full_version >= '3.11' # via # python-discovery # virtualenv @@ -70,21 +78,21 @@ idna==3.20 # trustme imagesize==2.0.1 # via sphinx -iniconfig==2.3.0 +iniconfig==2.3.1 # via pytest isort==9.0.2 # via pylint -jedi==0.20.0 ; implementation_name == 'cpython' +jedi==0.20.1 ; implementation_name == 'cpython' # via -r test-requirements.in jinja2==3.1.6 # via sphinx librt==0.16.0 ; implementation_name == 'cpython' and platform_python_implementation != 'PyPy' # via mypy -markupsafe==3.0.3 +markupsafe==3.0.4 # via jinja2 mccabe==0.7.0 # via pylint -mypy==2.3.1 ; implementation_name == 'cpython' +mypy==2.4.0 ; implementation_name == 'cpython' # via -r test-requirements.in mypy-extensions==1.1.0 # via @@ -110,22 +118,31 @@ pathspec==1.1.1 ; implementation_name == 'cpython' # via # black # mypy -platformdirs==4.12.2 +platformdirs==4.12.4 ; python_full_version < '3.11' + # via + # black + # pylint + # virtualenv +platformdirs==4.13.5 ; python_full_version >= '3.11' # via # black # pylint # virtualenv -pluggy==1.6.0 +pluggy==1.7.0 # via pytest -pre-commit==4.6.2 +pre-commit==4.6.2 ; python_full_version < '3.11' # via -r test-requirements.in -pycparser==3.0 ; (implementation_name != 'PyPy' and os_name == 'nt') or (implementation_name != 'PyPy' and platform_python_implementation != 'PyPy') +pre-commit==4.7.0 ; python_full_version >= '3.11' + # via -r test-requirements.in +pycparser==3.11 ; (python_full_version < '3.11' and implementation_name != 'PyPy' and os_name == 'nt') or (python_full_version < '3.11' and implementation_name != 'PyPy' and platform_python_implementation != 'PyPy') + # via cffi +pycparser==3.12 ; (python_full_version >= '3.11' and implementation_name != 'PyPy' and os_name == 'nt') or (python_full_version >= '3.11' and implementation_name != 'PyPy' and platform_python_implementation != 'PyPy') # via cffi pygments==2.21.0 # via # pytest # sphinx -pylint==4.1.1 +pylint==4.1.3 # via -r test-requirements.in pyopenssl==26.4.0 # via -r test-requirements.in @@ -133,7 +150,7 @@ pyright==1.1.414 # via -r test-requirements.in pytest==9.1.1 # via -r test-requirements.in -python-discovery==1.6.1 +python-discovery==1.6.4 # via virtualenv pytokens==0.4.1 ; implementation_name == 'cpython' # via black @@ -143,7 +160,7 @@ requests==2.34.2 # via sphinx roman-numerals==4.1.0 ; python_full_version >= '3.11' # via sphinx -ruff==0.17.1 +ruff==0.17.2 # via -r test-requirements.in sniffio==1.3.1 # via -r test-requirements.in @@ -155,7 +172,9 @@ sphinx==8.1.3 ; python_full_version < '3.11' # via -r test-requirements.in sphinx==9.0.4 ; python_full_version == '3.11.*' # via -r test-requirements.in -sphinx==9.1.0 ; python_full_version >= '3.12' +sphinx==9.1.1 ; python_full_version == '3.12.*' + # via -r test-requirements.in +sphinx==9.2.0 ; python_full_version >= '3.13' # via -r test-requirements.in sphinxcontrib-applehelp==2.0.0 # via sphinx @@ -163,20 +182,20 @@ sphinxcontrib-devhelp==2.0.0 # via sphinx sphinxcontrib-htmlhelp==2.1.0 # via sphinx -sphinxcontrib-jsmath==1.0.1 +sphinxcontrib-jsmath==2.0.0 # via sphinx sphinxcontrib-qthelp==2.0.0 # via sphinx sphinxcontrib-serializinghtml==2.0.0 # via sphinx -tomli==2.4.1 ; python_full_version < '3.11' +tomli==2.5.0 ; python_full_version < '3.11' # via # black # mypy # pylint # pytest # sphinx -tomlkit==0.15.1 +tomlkit==0.15.2 # via pylint trustme==1.2.1 # via -r test-requirements.in @@ -190,7 +209,7 @@ types-pyopenssl==24.1.0.20240722 # via -r test-requirements.in types-pyyaml==6.0.12.20260906 # via -r test-requirements.in -types-setuptools==84.0.0.20260812 +types-setuptools==84.0.0.20261006 # via types-cffi typing-extensions==4.16.0 # via @@ -205,7 +224,7 @@ typing-extensions==4.16.0 # virtualenv urllib3==2.8.0 # via requests -uv==0.13.1 +uv==0.13.5 # via -r test-requirements.in -virtualenv==21.14.1 +virtualenv==21.14.13 # via pre-commit