diff --git a/examples/clients/simple-auth-client/mcp_simple_auth_client/main.py b/examples/clients/simple-auth-client/mcp_simple_auth_client/main.py index 6354f2026..7a9e32279 100644 --- a/examples/clients/simple-auth-client/mcp_simple_auth_client/main.py +++ b/examples/clients/simple-auth-client/mcp_simple_auth_client/main.py @@ -81,7 +81,7 @@ def do_GET(self):

Authorization Failed

-

Error: {query_params['error'][0]}

+

Error: {query_params["error"][0]}

You can close this window and return to the terminal.

diff --git a/examples/fastmcp/memory.py b/examples/fastmcp/memory.py index 0f97babf1..35094ec9c 100644 --- a/examples/fastmcp/memory.py +++ b/examples/fastmcp/memory.py @@ -16,7 +16,7 @@ from dataclasses import dataclass from datetime import datetime, timezone from pathlib import Path -from typing import Annotated, Self +from typing import Annotated, Self, TypeVar import asyncpg import numpy as np @@ -35,6 +35,8 @@ DEFAULT_LLM_MODEL = "openai:gpt-4o" DEFAULT_EMBEDDING_MODEL = "text-embedding-3-small" +T = TypeVar("T") + mcp = FastMCP( "memory", dependencies=[ @@ -57,7 +59,7 @@ def cosine_similarity(a: list[float], b: list[float]) -> float: return np.dot(a_array, b_array) / (np.linalg.norm(a_array) * np.linalg.norm(b_array)) -async def do_ai[T]( +async def do_ai( user_prompt: str, system_prompt: str, result_type: type[T] | Annotated, diff --git a/examples/fastmcp/unicode_example.py b/examples/fastmcp/unicode_example.py index 94ef628bb..bb487f618 100644 --- a/examples/fastmcp/unicode_example.py +++ b/examples/fastmcp/unicode_example.py @@ -8,7 +8,7 @@ mcp = FastMCP() -@mcp.tool(description="🌟 A tool that uses various Unicode characters in its description: " "á é í ó ú ñ 漢字 🎉") +@mcp.tool(description="🌟 A tool that uses various Unicode characters in its description: á é í ó ú ñ 漢字 🎉") def hello_unicode(name: str = "世界", greeting: str = "¡Hola") -> str: """ A simple tool that demonstrates Unicode handling in: diff --git a/examples/servers/simple-auth/mcp_simple_auth/simple_auth_provider.py b/examples/servers/simple-auth/mcp_simple_auth/simple_auth_provider.py index 9ae189b84..aa813b542 100644 --- a/examples/servers/simple-auth/mcp_simple_auth/simple_auth_provider.py +++ b/examples/servers/simple-auth/mcp_simple_auth/simple_auth_provider.py @@ -89,7 +89,7 @@ async def authorize(self, client: OAuthClientInformationFull, params: Authorizat } # Build simple login URL that points to login page - auth_url = f"{self.auth_callback_url}" f"?state={state}" f"&client_id={client.client_id}" + auth_url = f"{self.auth_callback_url}?state={state}&client_id={client.client_id}" return auth_url @@ -117,7 +117,7 @@ async def get_login_page(self, state: str) -> HTMLResponse:

Username: demo_user
Password: demo_password

-
+
diff --git a/examples/servers/simple-streamablehttp-stateless/mcp_simple_streamablehttp_stateless/server.py b/examples/servers/simple-streamablehttp-stateless/mcp_simple_streamablehttp_stateless/server.py index 6a9ff9364..68f3ac6a6 100644 --- a/examples/servers/simple-streamablehttp-stateless/mcp_simple_streamablehttp_stateless/server.py +++ b/examples/servers/simple-streamablehttp-stateless/mcp_simple_streamablehttp_stateless/server.py @@ -51,7 +51,7 @@ async def call_tool(name: str, arguments: dict) -> list[types.ContentBlock]: for i in range(count): await ctx.session.send_log_message( level="info", - data=f"Notification {i+1}/{count} from caller: {caller}", + data=f"Notification {i + 1}/{count} from caller: {caller}", logger="notification_stream", related_request_id=ctx.request_id, ) diff --git a/examples/servers/simple-streamablehttp/mcp_simple_streamablehttp/server.py b/examples/servers/simple-streamablehttp/mcp_simple_streamablehttp/server.py index 85eb1369f..9c25cc569 100644 --- a/examples/servers/simple-streamablehttp/mcp_simple_streamablehttp/server.py +++ b/examples/servers/simple-streamablehttp/mcp_simple_streamablehttp/server.py @@ -55,7 +55,7 @@ async def call_tool(name: str, arguments: dict) -> list[types.ContentBlock]: for i in range(count): # Include more detailed message for resumability demonstration notification_msg = ( - f"[{i+1}/{count}] Event from '{caller}' - " + f"[{i + 1}/{count}] Event from '{caller}' - " f"Use Last-Event-ID to resume if disconnected" ) await ctx.session.send_log_message( @@ -69,7 +69,7 @@ async def call_tool(name: str, arguments: dict) -> list[types.ContentBlock]: # - nowhere (if GET request isn't supported) related_request_id=ctx.request_id, ) - logger.debug(f"Sent notification {i+1}/{count} for caller: {caller}") + logger.debug(f"Sent notification {i + 1}/{count} for caller: {caller}") if i < count - 1: # Don't wait after the last notification await anyio.sleep(interval) diff --git a/src/mcp/cli/claude.py b/src/mcp/cli/claude.py index e6eab2851..a33dd3e4a 100644 --- a/src/mcp/cli/claude.py +++ b/src/mcp/cli/claude.py @@ -35,7 +35,7 @@ def get_uv_path() -> str: uv_path = shutil.which("uv") if not uv_path: logger.error( - "uv executable not found in PATH, falling back to 'uv'. " "Please ensure uv is installed and in your PATH" + "uv executable not found in PATH, falling back to 'uv'. Please ensure uv is installed and in your PATH" ) return "uv" # Fall back to just "uv" if not found return uv_path diff --git a/src/mcp/cli/cli.py b/src/mcp/cli/cli.py index 69e2921f1..cb9e16fec 100644 --- a/src/mcp/cli/cli.py +++ b/src/mcp/cli/cli.py @@ -150,10 +150,10 @@ def _check_server_object(server_object: Any, object_name: str): True if it's supported. """ if not isinstance(server_object, FastMCP): - logger.error(f"The server object {object_name} is of type " f"{type(server_object)} (expecting {FastMCP}).") + logger.error(f"The server object {object_name} is of type {type(server_object)} (expecting {FastMCP}).") if isinstance(server_object, LowLevelServer): logger.warning( - "Note that only FastMCP server is supported. Low level " "Server class is not yet supported." + "Note that only FastMCP server is supported. Low level Server class is not yet supported." ) return False return True @@ -164,7 +164,7 @@ def _check_server_object(server_object: Any, object_name: str): for name in ["mcp", "server", "app"]: if hasattr(module, name): if not _check_server_object(getattr(module, name), f"{file}:{name}"): - logger.error(f"Ignoring object '{file}:{name}' as it's not a valid " "server object") + logger.error(f"Ignoring object '{file}:{name}' as it's not a valid server object") continue return getattr(module, name) @@ -269,7 +269,7 @@ def dev( npx_cmd = _get_npx_command() if not npx_cmd: logger.error( - "npx not found. Please ensure Node.js and npm are properly installed " "and added to your system PATH." + "npx not found. Please ensure Node.js and npm are properly installed and added to your system PATH." ) sys.exit(1) @@ -371,7 +371,7 @@ def install( typer.Option( "--name", "-n", - help="Custom name for the server (defaults to server's name attribute or" " file name)", + help="Custom name for the server (defaults to server's name attribute or file name)", ), ] = None, with_editable: Annotated[ @@ -445,7 +445,7 @@ def install( name = server.name except (ImportError, ModuleNotFoundError) as e: logger.debug( - "Could not import server (likely missing dependencies), using file" " name", + "Could not import server (likely missing dependencies), using file name", extra={"error": str(e)}, ) name = file.stem diff --git a/src/mcp/client/session.py b/src/mcp/client/session.py index 891eff0a6..1853ce7c1 100644 --- a/src/mcp/client/session.py +++ b/src/mcp/client/session.py @@ -168,7 +168,7 @@ async def initialize(self) -> types.InitializeResult: ) if result.protocolVersion not in SUPPORTED_PROTOCOL_VERSIONS: - raise RuntimeError("Unsupported protocol version from the server: " f"{result.protocolVersion}") + raise RuntimeError(f"Unsupported protocol version from the server: {result.protocolVersion}") await self.send_notification( types.ClientNotification(types.InitializedNotification(method="notifications/initialized")) diff --git a/src/mcp/client/sse.py b/src/mcp/client/sse.py index 0c05c6def..68b9654b3 100644 --- a/src/mcp/client/sse.py +++ b/src/mcp/client/sse.py @@ -83,7 +83,7 @@ async def sse_reader( or url_parsed.scheme != endpoint_parsed.scheme ): error_msg = ( - "Endpoint origin does not match " f"connection origin: {endpoint_url}" + f"Endpoint origin does not match connection origin: {endpoint_url}" ) logger.error(error_msg) raise ValueError(error_msg) @@ -125,7 +125,7 @@ async def post_writer(endpoint_url: str): ), ) response.raise_for_status() - logger.debug("Client message sent successfully: " f"{response.status_code}") + logger.debug(f"Client message sent successfully: {response.status_code}") except Exception as exc: logger.error(f"Error in post_writer: {exc}") finally: diff --git a/src/mcp/server/auth/handlers/authorize.py b/src/mcp/server/auth/handlers/authorize.py index 3ce4c34bc..f484cf886 100644 --- a/src/mcp/server/auth/handlers/authorize.py +++ b/src/mcp/server/auth/handlers/authorize.py @@ -33,7 +33,7 @@ class AuthorizationRequest(BaseModel): state: str | None = Field(None, description="Optional state parameter") scope: str | None = Field( None, - description="Optional scope; if specified, should be " "a space-separated list of scope strings", + description="Optional scope; if specified, should be a space-separated list of scope strings", ) resource: str | None = Field( None, diff --git a/src/mcp/server/auth/handlers/register.py b/src/mcp/server/auth/handlers/register.py index 61e403aca..e6d99e66d 100644 --- a/src/mcp/server/auth/handlers/register.py +++ b/src/mcp/server/auth/handlers/register.py @@ -72,7 +72,7 @@ async def handle(self, request: Request) -> Response: return PydanticJSONResponse( content=RegistrationErrorResponse( error="invalid_client_metadata", - error_description="grant_types must be authorization_code " "and refresh_token", + error_description="grant_types must be authorization_code and refresh_token", ), status_code=400, ) diff --git a/src/mcp/server/auth/handlers/token.py b/src/mcp/server/auth/handlers/token.py index 552417169..4e15e6265 100644 --- a/src/mcp/server/auth/handlers/token.py +++ b/src/mcp/server/auth/handlers/token.py @@ -119,9 +119,7 @@ async def handle(self, request: Request): return self.response( TokenErrorResponse( error="unsupported_grant_type", - error_description=( - f"Unsupported grant type (supported grant types are " f"{client_info.grant_types})" - ), + error_description=(f"Unsupported grant type (supported grant types are {client_info.grant_types})"), ) ) @@ -166,7 +164,7 @@ async def handle(self, request: Request): return self.response( TokenErrorResponse( error="invalid_request", - error_description=("redirect_uri did not match the one " "used when creating auth code"), + error_description=("redirect_uri did not match the one used when creating auth code"), ) ) @@ -222,7 +220,7 @@ async def handle(self, request: Request): return self.response( TokenErrorResponse( error="invalid_scope", - error_description=(f"cannot request scope `{scope}` " "not provided by refresh token"), + error_description=(f"cannot request scope `{scope}` not provided by refresh token"), ) ) diff --git a/src/mcp/server/fastmcp/server.py b/src/mcp/server/fastmcp/server.py index 956a8aa78..705d9f494 100644 --- a/src/mcp/server/fastmcp/server.py +++ b/src/mcp/server/fastmcp/server.py @@ -390,7 +390,7 @@ async def async_tool(x: int, context: Context) -> str: # Check if user passed function directly instead of calling decorator if callable(name): raise TypeError( - "The @tool decorator was used incorrectly. " "Did you forget to call it? Use @tool() instead of @tool" + "The @tool decorator was used incorrectly. Did you forget to call it? Use @tool() instead of @tool" ) def decorator(fn: AnyFunction) -> AnyFunction: @@ -497,7 +497,7 @@ def decorator(fn: AnyFunction) -> AnyFunction: if uri_params != func_params: raise ValueError( - f"Mismatch between URI parameters {uri_params} " f"and function parameters {func_params}" + f"Mismatch between URI parameters {uri_params} and function parameters {func_params}" ) # Register as template diff --git a/src/mcp/server/fastmcp/tools/base.py b/src/mcp/server/fastmcp/tools/base.py index 366a76895..3d8827ed7 100644 --- a/src/mcp/server/fastmcp/tools/base.py +++ b/src/mcp/server/fastmcp/tools/base.py @@ -27,7 +27,7 @@ class Tool(BaseModel): description: str = Field(description="Description of what the tool does") parameters: dict[str, Any] = Field(description="JSON schema for tool parameters") fn_metadata: FuncMetadata = Field( - description="Metadata about the function including a pydantic model for tool" " arguments" + description="Metadata about the function including a pydantic model for tool arguments" ) is_async: bool = Field(description="Whether the tool is async") context_kwarg: str | None = Field(None, description="Name of the kwarg that should receive context") diff --git a/src/mcp/shared/auth.py b/src/mcp/shared/auth.py index 1f2d1659a..eb127ecfa 100644 --- a/src/mcp/shared/auth.py +++ b/src/mcp/shared/auth.py @@ -87,7 +87,7 @@ def validate_redirect_uri(self, redirect_uri: AnyUrl | None) -> AnyUrl: elif len(self.redirect_uris) == 1: return self.redirect_uris[0] else: - raise InvalidRedirectUriError("redirect_uri must be specified when client " "has multiple registered URIs") + raise InvalidRedirectUriError("redirect_uri must be specified when client has multiple registered URIs") class OAuthClientInformationFull(OAuthClientMetadata): diff --git a/src/mcp/shared/session.py b/src/mcp/shared/session.py index 6536272d9..b2f49fc8b 100644 --- a/src/mcp/shared/session.py +++ b/src/mcp/shared/session.py @@ -402,7 +402,7 @@ async def _receive_loop(self) -> None: except Exception as e: # For other validation errors, log and continue logging.warning( - f"Failed to validate notification: {e}. " f"Message was: {message.message.root}" + f"Failed to validate notification: {e}. Message was: {message.message.root}" ) else: # Response or error stream = self._response_streams.pop(message.message.root.id, None) @@ -410,7 +410,7 @@ async def _receive_loop(self) -> None: await stream.send(message.message.root) else: await self._handle_incoming( - RuntimeError("Received response with an unknown " f"request ID: {message}") + RuntimeError(f"Received response with an unknown request ID: {message}") ) except anyio.ClosedResourceError: diff --git a/tests/client/test_resource_cleanup.py b/tests/client/test_resource_cleanup.py index 990b3a89a..527884219 100644 --- a/tests/client/test_resource_cleanup.py +++ b/tests/client/test_resource_cleanup.py @@ -57,8 +57,7 @@ async def mock_send(*args, **kwargs): # Verify that no response streams were leaked assert len(session._response_streams) == initial_stream_count, ( - f"Expected {initial_stream_count} response streams after request, " - f"but found {len(session._response_streams)}" + f"Expected {initial_stream_count} response streams after request, but found {len(session._response_streams)}" ) # Clean up diff --git a/tests/server/fastmcp/auth/test_auth_integration.py b/tests/server/fastmcp/auth/test_auth_integration.py index 5db5d58c2..e4a8f3f4c 100644 --- a/tests/server/fastmcp/auth/test_auth_integration.py +++ b/tests/server/fastmcp/auth/test_auth_integration.py @@ -658,7 +658,7 @@ async def test_client_registration_invalid_uri(self, test_client: httpx.AsyncCli assert "error" in error_data assert error_data["error"] == "invalid_client_metadata" assert error_data["error_description"] == ( - "redirect_uris.0: Input should be a valid URL, " "relative URL without a base" + "redirect_uris.0: Input should be a valid URL, relative URL without a base" ) @pytest.mark.anyio diff --git a/tests/server/fastmcp/test_integration.py b/tests/server/fastmcp/test_integration.py index 526201f9a..f13c76fa9 100644 --- a/tests/server/fastmcp/test_integration.py +++ b/tests/server/fastmcp/test_integration.py @@ -696,7 +696,7 @@ def everything_streamable_http_server( time.sleep(0.1) attempt += 1 else: - raise RuntimeError(f"Comprehensive StreamableHTTP server failed to start after " f"{max_attempts} attempts") + raise RuntimeError(f"Comprehensive StreamableHTTP server failed to start after {max_attempts} attempts") yield diff --git a/uv.lock b/uv.lock index cfcc8238e..82b8b0859 100644 --- a/uv.lock +++ b/uv.lock @@ -1659,27 +1659,27 @@ wheels = [ [[package]] name = "ruff" -version = "0.8.5" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/25/5d/4b5403f3e89837decfd54c51bea7f94b7d3fae77e08858603d0e04d7ad17/ruff-0.8.5.tar.gz", hash = "sha256:1098d36f69831f7ff2a1da3e6407d5fbd6dfa2559e4f74ff2d260c5588900317", size = 3454835, upload-time = "2025-01-02T12:04:16.105Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/73/f8/03391745a703ce11678eb37c48ae89ec60396ea821e9d0bcea7c8e88fd91/ruff-0.8.5-py3-none-linux_armv6l.whl", hash = "sha256:5ad11a5e3868a73ca1fa4727fe7e33735ea78b416313f4368c504dbeb69c0f88", size = 10626889, upload-time = "2025-01-02T12:03:14.406Z" }, - { url = "https://files.pythonhosted.org/packages/55/74/83bb74a44183b904216f3edfb9995b89830c83aaa6ce84627f74da0e0cf8/ruff-0.8.5-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:f69ab37771ea7e0715fead8624ec42996d101269a96e31f4d31be6fc33aa19b7", size = 10398233, upload-time = "2025-01-02T12:03:18.107Z" }, - { url = "https://files.pythonhosted.org/packages/e8/7a/a162a4feb3ef85d594527165e366dde09d7a1e534186ff4ba5d127eda850/ruff-0.8.5-py3-none-macosx_11_0_arm64.whl", hash = "sha256:b5462d7804558ccff9c08fe8cbf6c14b7efe67404316696a2dde48297b1925bb", size = 10001843, upload-time = "2025-01-02T12:03:22.265Z" }, - { url = "https://files.pythonhosted.org/packages/e7/9f/5ee5dcd135411402e35b6ec6a8dfdadbd31c5cd1c36a624d356a38d76090/ruff-0.8.5-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d56de7220a35607f9fe59f8a6d018e14504f7b71d784d980835e20fc0611cd50", size = 10872507, upload-time = "2025-01-02T12:03:25.198Z" }, - { url = "https://files.pythonhosted.org/packages/b6/67/db2df2dd4a34b602d7f6ebb1b3744c8157f0d3579973ffc58309c9c272e8/ruff-0.8.5-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:9d99cf80b0429cbebf31cbbf6f24f05a29706f0437c40413d950e67e2d4faca4", size = 10377200, upload-time = "2025-01-02T12:03:29.499Z" }, - { url = "https://files.pythonhosted.org/packages/fe/ff/fe3a6a73006bced73e60d171d154a82430f61d97e787f511a24bd6302611/ruff-0.8.5-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7b75ac29715ac60d554a049dbb0ef3b55259076181c3369d79466cb130eb5afd", size = 11433155, upload-time = "2025-01-02T12:03:33.293Z" }, - { url = "https://files.pythonhosted.org/packages/e3/95/c1d1a1fe36658c1f3e1b47e1cd5f688b72d5786695b9e621c2c38399a95e/ruff-0.8.5-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:c9d526a62c9eda211b38463528768fd0ada25dad524cb33c0e99fcff1c67b5dc", size = 12139227, upload-time = "2025-01-02T12:03:36.318Z" }, - { url = "https://files.pythonhosted.org/packages/1b/fe/644b70d473a27b5112ac7a3428edcc1ce0db775c301ff11aa146f71886e0/ruff-0.8.5-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:587c5e95007612c26509f30acc506c874dab4c4abbacd0357400bd1aa799931b", size = 11697941, upload-time = "2025-01-02T12:03:40.544Z" }, - { url = "https://files.pythonhosted.org/packages/00/39/4f83e517ec173e16a47c6d102cd22a1aaebe80e1208a1f2e83ab9a0e4134/ruff-0.8.5-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:622b82bf3429ff0e346835ec213aec0a04d9730480cbffbb6ad9372014e31bbd", size = 12967686, upload-time = "2025-01-02T12:03:43.751Z" }, - { url = "https://files.pythonhosted.org/packages/1a/f6/52a2973ff108d74b5da706a573379eea160bece098f7cfa3f35dc4622710/ruff-0.8.5-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f99be814d77a5dac8a8957104bdd8c359e85c86b0ee0e38dca447cb1095f70fb", size = 11253788, upload-time = "2025-01-02T12:03:48.222Z" }, - { url = "https://files.pythonhosted.org/packages/ce/1f/3b30f3c65b1303cb8e268ec3b046b77ab21ed8e26921cfc7e8232aa57f2c/ruff-0.8.5-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:c01c048f9c3385e0fd7822ad0fd519afb282af9cf1778f3580e540629df89725", size = 10860360, upload-time = "2025-01-02T12:03:51.34Z" }, - { url = "https://files.pythonhosted.org/packages/a5/a8/2a3ea6bacead963f7aeeba0c61815d9b27b0d638e6a74984aa5cc5d27733/ruff-0.8.5-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:7512e8cb038db7f5db6aae0e24735ff9ea03bb0ed6ae2ce534e9baa23c1dc9ea", size = 10457922, upload-time = "2025-01-02T12:03:55.212Z" }, - { url = "https://files.pythonhosted.org/packages/17/47/8f9514b670969aab57c5fc826fb500a16aee8feac1bcf8a91358f153a5ba/ruff-0.8.5-py3-none-musllinux_1_2_i686.whl", hash = "sha256:762f113232acd5b768d6b875d16aad6b00082add40ec91c927f0673a8ec4ede8", size = 10958347, upload-time = "2025-01-02T12:03:59.214Z" }, - { url = "https://files.pythonhosted.org/packages/0d/d6/78a9af8209ad99541816d74f01ce678fc01ebb3f37dd7ab8966646dcd92b/ruff-0.8.5-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:03a90200c5dfff49e4c967b405f27fdfa81594cbb7c5ff5609e42d7fe9680da5", size = 11328882, upload-time = "2025-01-02T12:04:02.224Z" }, - { url = "https://files.pythonhosted.org/packages/54/77/5c8072ec7afdfdf42c7a4019044486a2b6c85ee73617f8875ec94b977fed/ruff-0.8.5-py3-none-win32.whl", hash = "sha256:8710ffd57bdaa6690cbf6ecff19884b8629ec2a2a2a2f783aa94b1cc795139ed", size = 8802515, upload-time = "2025-01-02T12:04:05.399Z" }, - { url = "https://files.pythonhosted.org/packages/bc/b6/47d2b06784de8ae992c45cceb2a30f3f205b3236a629d7ca4c0c134839a2/ruff-0.8.5-py3-none-win_amd64.whl", hash = "sha256:4020d8bf8d3a32325c77af452a9976a9ad6455773bcb94991cf15bd66b347e47", size = 9684231, upload-time = "2025-01-02T12:04:08.414Z" }, - { url = "https://files.pythonhosted.org/packages/bf/5e/ffee22bf9f9e4b2669d1f0179ae8804584939fb6502b51f2401e26b1e028/ruff-0.8.5-py3-none-win_arm64.whl", hash = "sha256:134ae019ef13e1b060ab7136e7828a6d83ea727ba123381307eb37c6bd5e01cb", size = 9124741, upload-time = "2025-01-02T12:04:11.189Z" }, +version = "0.12.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/6c/3d/d9a195676f25d00dbfcf3cf95fdd4c685c497fcfa7e862a44ac5e4e96480/ruff-0.12.2.tar.gz", hash = "sha256:d7b4f55cd6f325cb7621244f19c873c565a08aff5a4ba9c69aa7355f3f7afd3e", size = 4432239, upload-time = "2025-07-03T16:40:19.566Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/74/b6/2098d0126d2d3318fd5bec3ad40d06c25d377d95749f7a0c5af17129b3b1/ruff-0.12.2-py3-none-linux_armv6l.whl", hash = "sha256:093ea2b221df1d2b8e7ad92fc6ffdca40a2cb10d8564477a987b44fd4008a7be", size = 10369761, upload-time = "2025-07-03T16:39:38.847Z" }, + { url = "https://files.pythonhosted.org/packages/b1/4b/5da0142033dbe155dc598cfb99262d8ee2449d76920ea92c4eeb9547c208/ruff-0.12.2-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:09e4cf27cc10f96b1708100fa851e0daf21767e9709e1649175355280e0d950e", size = 11155659, upload-time = "2025-07-03T16:39:42.294Z" }, + { url = "https://files.pythonhosted.org/packages/3e/21/967b82550a503d7c5c5c127d11c935344b35e8c521f52915fc858fb3e473/ruff-0.12.2-py3-none-macosx_11_0_arm64.whl", hash = "sha256:8ae64755b22f4ff85e9c52d1f82644abd0b6b6b6deedceb74bd71f35c24044cc", size = 10537769, upload-time = "2025-07-03T16:39:44.75Z" }, + { url = "https://files.pythonhosted.org/packages/33/91/00cff7102e2ec71a4890fb7ba1803f2cdb122d82787c7d7cf8041fe8cbc1/ruff-0.12.2-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3eb3a6b2db4d6e2c77e682f0b988d4d61aff06860158fdb413118ca133d57922", size = 10717602, upload-time = "2025-07-03T16:39:47.652Z" }, + { url = "https://files.pythonhosted.org/packages/9b/eb/928814daec4e1ba9115858adcda44a637fb9010618721937491e4e2283b8/ruff-0.12.2-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:73448de992d05517170fc37169cbca857dfeaeaa8c2b9be494d7bcb0d36c8f4b", size = 10198772, upload-time = "2025-07-03T16:39:49.641Z" }, + { url = "https://files.pythonhosted.org/packages/50/fa/f15089bc20c40f4f72334f9145dde55ab2b680e51afb3b55422effbf2fb6/ruff-0.12.2-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3b8b94317cbc2ae4a2771af641739f933934b03555e51515e6e021c64441532d", size = 11845173, upload-time = "2025-07-03T16:39:52.069Z" }, + { url = "https://files.pythonhosted.org/packages/43/9f/1f6f98f39f2b9302acc161a4a2187b1e3a97634fe918a8e731e591841cf4/ruff-0.12.2-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:45fc42c3bf1d30d2008023a0a9a0cfb06bf9835b147f11fe0679f21ae86d34b1", size = 12553002, upload-time = "2025-07-03T16:39:54.551Z" }, + { url = "https://files.pythonhosted.org/packages/d8/70/08991ac46e38ddd231c8f4fd05ef189b1b94be8883e8c0c146a025c20a19/ruff-0.12.2-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ce48f675c394c37e958bf229fb5c1e843e20945a6d962cf3ea20b7a107dcd9f4", size = 12171330, upload-time = "2025-07-03T16:39:57.55Z" }, + { url = "https://files.pythonhosted.org/packages/88/a9/5a55266fec474acfd0a1c73285f19dd22461d95a538f29bba02edd07a5d9/ruff-0.12.2-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:793d8859445ea47591272021a81391350205a4af65a9392401f418a95dfb75c9", size = 11774717, upload-time = "2025-07-03T16:39:59.78Z" }, + { url = "https://files.pythonhosted.org/packages/87/e5/0c270e458fc73c46c0d0f7cf970bb14786e5fdb88c87b5e423a4bd65232b/ruff-0.12.2-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6932323db80484dda89153da3d8e58164d01d6da86857c79f1961934354992da", size = 11646659, upload-time = "2025-07-03T16:40:01.934Z" }, + { url = "https://files.pythonhosted.org/packages/b7/b6/45ab96070c9752af37f0be364d849ed70e9ccede07675b0ec4e3ef76b63b/ruff-0.12.2-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:6aa7e623a3a11538108f61e859ebf016c4f14a7e6e4eba1980190cacb57714ce", size = 10604012, upload-time = "2025-07-03T16:40:04.363Z" }, + { url = "https://files.pythonhosted.org/packages/86/91/26a6e6a424eb147cc7627eebae095cfa0b4b337a7c1c413c447c9ebb72fd/ruff-0.12.2-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:2a4a20aeed74671b2def096bdf2eac610c7d8ffcbf4fb0e627c06947a1d7078d", size = 10176799, upload-time = "2025-07-03T16:40:06.514Z" }, + { url = "https://files.pythonhosted.org/packages/f5/0c/9f344583465a61c8918a7cda604226e77b2c548daf8ef7c2bfccf2b37200/ruff-0.12.2-py3-none-musllinux_1_2_i686.whl", hash = "sha256:71a4c550195612f486c9d1f2b045a600aeba851b298c667807ae933478fcef04", size = 11241507, upload-time = "2025-07-03T16:40:08.708Z" }, + { url = "https://files.pythonhosted.org/packages/1c/b7/99c34ded8fb5f86c0280278fa89a0066c3760edc326e935ce0b1550d315d/ruff-0.12.2-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:4987b8f4ceadf597c927beee65a5eaf994c6e2b631df963f86d8ad1bdea99342", size = 11717609, upload-time = "2025-07-03T16:40:10.836Z" }, + { url = "https://files.pythonhosted.org/packages/51/de/8589fa724590faa057e5a6d171e7f2f6cffe3287406ef40e49c682c07d89/ruff-0.12.2-py3-none-win32.whl", hash = "sha256:369ffb69b70cd55b6c3fc453b9492d98aed98062db9fec828cdfd069555f5f1a", size = 10523823, upload-time = "2025-07-03T16:40:13.203Z" }, + { url = "https://files.pythonhosted.org/packages/94/47/8abf129102ae4c90cba0c2199a1a9b0fa896f6f806238d6f8c14448cc748/ruff-0.12.2-py3-none-win_amd64.whl", hash = "sha256:dca8a3b6d6dc9810ed8f328d406516bf4d660c00caeaef36eb831cf4871b0639", size = 11629831, upload-time = "2025-07-03T16:40:15.478Z" }, + { url = "https://files.pythonhosted.org/packages/e2/1f/72d2946e3cc7456bb837e88000eb3437e55f80db339c840c04015a11115d/ruff-0.12.2-py3-none-win_arm64.whl", hash = "sha256:48d6c6bfb4761df68bc05ae630e24f506755e702d4fb08f08460be778c7ccb12", size = 10735334, upload-time = "2025-07-03T16:40:17.677Z" }, ] [[package]]