diff --git a/packages/gooddata-dbt/src/gooddata_dbt/dbt_plugin.py b/packages/gooddata-dbt/src/gooddata_dbt/dbt_plugin.py index 6b67030b3..c485966c6 100644 --- a/packages/gooddata-dbt/src/gooddata_dbt/dbt_plugin.py +++ b/packages/gooddata-dbt/src/gooddata_dbt/dbt_plugin.py @@ -216,7 +216,7 @@ def create_localized_workspaces( if data_product.localization is None: return try: - from deep_translator import GoogleTranslator + from deep_translator import GoogleTranslator # noqa: PLC0415 except ImportError: logger.warning( "create_localized_workspaces: deep_translator module not found, will not be able to localize workspaces" diff --git a/packages/gooddata-dbt/src/gooddata_dbt/utils.py b/packages/gooddata-dbt/src/gooddata_dbt/utils.py index 2a13a11d8..625339e5b 100644 --- a/packages/gooddata-dbt/src/gooddata_dbt/utils.py +++ b/packages/gooddata-dbt/src/gooddata_dbt/utils.py @@ -28,7 +28,7 @@ def report_message_to_merge_request(token: str, merge_request_id: str, text: str def report_message_to_pull_request(logger: Logger, token: str, pull_request_id: int, text: str) -> None: try: - from github import Auth, Github + from github import Auth, Github # noqa: PLC0415 auth = Auth.Token(token) g = Github(auth=auth) diff --git a/packages/gooddata-fdw/src/gooddata_fdw/environment.py b/packages/gooddata-fdw/src/gooddata_fdw/environment.py index 33e216689..0db0d0a2a 100644 --- a/packages/gooddata-fdw/src/gooddata_fdw/environment.py +++ b/packages/gooddata-fdw/src/gooddata_fdw/environment.py @@ -33,6 +33,7 @@ # package-specific global variable would inevitably lead to evaluation of __init__ which imports the FDW code # which will then try to import from this file before the variable is even set import sys + from logging import getLevelName if "pytest" not in sys.modules and "sphinx" not in sys.modules: # multicorn stuff cannot be imported & the FDW code is not currently under test or as documentation build. @@ -40,8 +41,6 @@ raise e def _log_to_console(msg: str, level: int) -> None: - from logging import getLevelName - print(f"{getLevelName(level)}: {msg}") log_to_postgres = _log_to_console diff --git a/packages/gooddata-flight-server/src/gooddata_flight_server/utils/otel_tracing.py b/packages/gooddata-flight-server/src/gooddata_flight_server/utils/otel_tracing.py index 330d87402..e3ba4e18c 100644 --- a/packages/gooddata-flight-server/src/gooddata_flight_server/utils/otel_tracing.py +++ b/packages/gooddata-flight-server/src/gooddata_flight_server/utils/otel_tracing.py @@ -41,7 +41,7 @@ def _create_console_span_exporter() -> SpanExporter: def _create_zipkin_span_exporter() -> SpanExporter: - from opentelemetry.exporter.zipkin.json import ( + from opentelemetry.exporter.zipkin.json import ( # noqa: PLC0415 ZipkinExporter, ) @@ -49,7 +49,7 @@ def _create_zipkin_span_exporter() -> SpanExporter: def _create_otlp_grpc_exporter() -> SpanExporter: - from opentelemetry.exporter.otlp.proto.grpc.trace_exporter import ( + from opentelemetry.exporter.otlp.proto.grpc.trace_exporter import ( # noqa: PLC0415 OTLPSpanExporter, ) @@ -57,7 +57,7 @@ def _create_otlp_grpc_exporter() -> SpanExporter: def _create_otlp_http_exporter() -> SpanExporter: - from opentelemetry.exporter.otlp.proto.http.trace_exporter import ( + from opentelemetry.exporter.otlp.proto.http.trace_exporter import ( # noqa: PLC0415 OTLPSpanExporter, ) diff --git a/packages/gooddata-pipelines/src/gooddata_pipelines/provisioning/entities/workspaces/workspace_data_filters.py b/packages/gooddata-pipelines/src/gooddata_pipelines/provisioning/entities/workspaces/workspace_data_filters.py index 30c1ae220..d0fd8f2e9 100644 --- a/packages/gooddata-pipelines/src/gooddata_pipelines/provisioning/entities/workspaces/workspace_data_filters.py +++ b/packages/gooddata-pipelines/src/gooddata_pipelines/provisioning/entities/workspaces/workspace_data_filters.py @@ -3,6 +3,7 @@ """Module for managing workspace data filter settings in GoodData Cloud.""" import json +import os from typing import Any from uuid import uuid4 @@ -40,8 +41,6 @@ def _create_wdf_setting_dict( """Loads a JSON template of a WDF setting and fills it with the given values.""" values = [str(value) for value in wdf_values] - import os - wdf_setting_path = os.path.join( os.path.dirname(__file__), "../../assets/wdf_setting.json" ) diff --git a/packages/gooddata-sdk/src/gooddata_sdk/client.py b/packages/gooddata-sdk/src/gooddata_sdk/client.py index 0c363b17d..0fd65a276 100644 --- a/packages/gooddata-sdk/src/gooddata_sdk/client.py +++ b/packages/gooddata-sdk/src/gooddata_sdk/client.py @@ -3,6 +3,7 @@ from __future__ import annotations +import os from pathlib import Path import gooddata_api_client as api_client @@ -59,8 +60,6 @@ def __init__( ) if proxy is None: - import os - proxy = ( os.environ.get("HTTPS_PROXY") or os.environ.get("https_proxy") diff --git a/packages/gooddata-sdk/tests/catalog/test_aac.py b/packages/gooddata-sdk/tests/catalog/test_aac.py index dd5111d65..69fe7a75e 100644 --- a/packages/gooddata-sdk/tests/catalog/test_aac.py +++ b/packages/gooddata-sdk/tests/catalog/test_aac.py @@ -1,6 +1,8 @@ # (C) 2026 GoodData Corporation from __future__ import annotations +import shutil +import tempfile from pathlib import Path import yaml @@ -16,6 +18,9 @@ load_aac_workspace_from_disk, store_aac_workspace_to_disk, ) +from gooddata_sdk.catalog.workspace.declarative_model.workspace.workspace import ( + CatalogDeclarativeWorkspaceModel, +) from gooddata_sdk.config import AacConfig _FIXTURES_DIR = Path(__file__).parent / "unit_tests" / "aac_tests" @@ -243,9 +248,6 @@ class TestWorkspaceLoadStore: def test_load_aac_workspace_from_fixtures(self) -> None: """Load fixtures excluding dashboards (WASM crypto limitation).""" # Use a temp dir with only datasets, metrics, visualizations - import shutil - import tempfile - with tempfile.TemporaryDirectory() as tmp: tmp_path = Path(tmp) for subdir in ("datasets", "metrics", "visualisations"): @@ -280,10 +282,6 @@ def test_store_and_reload_metrics(self, tmp_path: Path) -> None: metrics_declarative = [aac_metric_to_declarative(m) for m in aac_metrics] model_dict = {"analytics": {"metrics": metrics_declarative}} - from gooddata_sdk.catalog.workspace.declarative_model.workspace.workspace import ( - CatalogDeclarativeWorkspaceModel, - ) - model = CatalogDeclarativeWorkspaceModel.from_dict(model_dict) store_aac_workspace_to_disk(model, tmp_path) @@ -316,10 +314,6 @@ def test_store_and_reload_visualizations(self, tmp_path: Path) -> None: vis_declarative = [aac_visualization_to_declarative(aac_vis)] model_dict = {"analytics": {"visualizationObjects": vis_declarative}} - from gooddata_sdk.catalog.workspace.declarative_model.workspace.workspace import ( - CatalogDeclarativeWorkspaceModel, - ) - model = CatalogDeclarativeWorkspaceModel.from_dict(model_dict) store_aac_workspace_to_disk(model, tmp_path) @@ -334,9 +328,6 @@ def test_store_and_reload_visualizations(self, tmp_path: Path) -> None: def test_store_and_reload_from_fixtures(self, tmp_path: Path) -> None: """Load fixtures, store to disk, reload — full round-trip.""" - import shutil - import tempfile - with tempfile.TemporaryDirectory() as tmp: fixture_path = Path(tmp) for subdir in ("datasets", "metrics", "visualisations"): diff --git a/packages/gooddata-sdk/tests/catalog/test_catalog_user_service.py b/packages/gooddata-sdk/tests/catalog/test_catalog_user_service.py index d97f032ff..d29302a23 100644 --- a/packages/gooddata-sdk/tests/catalog/test_catalog_user_service.py +++ b/packages/gooddata-sdk/tests/catalog/test_catalog_user_service.py @@ -37,11 +37,12 @@ GoodDataApiClient, GoodDataSdk, ) +from gooddata_sdk.catalog.permission.declarative_model.permission import CatalogDeclarativeWorkspacePermissions from gooddata_sdk.utils import recreate_directory from tests_support.file_utils import load_json from tests_support.vcrpy_utils import get_vcr -from .conftest import safe_delete +from .conftest import load_expected_data_sources, safe_delete gd_vcr = get_vcr() @@ -194,8 +195,6 @@ def _restore_demo2_permissions(sdk: GoodDataSdk, test_config: dict) -> None: Note: This function makes HTTP calls. When used in tests with VCR cassettes, ensure the cassette includes the restoration calls (in finally blocks). """ - from .conftest import load_expected_data_sources - # Restore data source permissions expected_ds_path = _current_dir / "expected" / "declarative_data_sources.json" credentials_path = _current_dir / "load" / "data_source_credentials" / "data_sources_credentials.yaml" @@ -203,8 +202,6 @@ def _restore_demo2_permissions(sdk: GoodDataSdk, test_config: dict) -> None: sdk.catalog_data_source.put_declarative_data_sources(data_sources, credentials_path) # Restore workspace permissions - from gooddata_sdk.catalog.permission.declarative_model.permission import CatalogDeclarativeWorkspacePermissions - expected_ws_path = _current_dir / "expected" / "declarative_workspace_permissions.json" ws_data = load_json(expected_ws_path) ws_permissions = CatalogDeclarativeWorkspacePermissions.from_dict(ws_data, camel_case=True) diff --git a/packages/gooddata-sdk/tests/catalog/test_tabbed_dashboard_translations.py b/packages/gooddata-sdk/tests/catalog/test_tabbed_dashboard_translations.py index 8bfeedd02..a9f9115f9 100644 --- a/packages/gooddata-sdk/tests/catalog/test_tabbed_dashboard_translations.py +++ b/packages/gooddata-sdk/tests/catalog/test_tabbed_dashboard_translations.py @@ -12,6 +12,7 @@ from __future__ import annotations +import copy from unittest.mock import MagicMock from gooddata_sdk.catalog.workspace.service import CatalogWorkspaceService @@ -309,7 +310,6 @@ def _service(self): def test_translates_tab_titles(self): """Tab titles are translated.""" - import copy content = { "tabs": [ @@ -349,7 +349,6 @@ def test_translates_tab_titles(self): def test_translates_widgets_in_tabs(self): """Widget titles/descriptions inside tabs are translated.""" - import copy content = { "tabs": [ @@ -392,7 +391,6 @@ def test_translates_widgets_in_tabs(self): def test_legacy_layout_still_works(self): """Legacy layout dashboards still get their widgets translated.""" - import copy content = { "layout": { diff --git a/packages/gooddata-sdk/tests/compute/test_bare_execution_response.py b/packages/gooddata-sdk/tests/compute/test_bare_execution_response.py index 463086331..9eac42c2b 100644 --- a/packages/gooddata-sdk/tests/compute/test_bare_execution_response.py +++ b/packages/gooddata-sdk/tests/compute/test_bare_execution_response.py @@ -8,12 +8,14 @@ pyarrow = pytest.importorskip("pyarrow") +import pyarrow as pa # noqa: E402 +from gooddata_sdk.compute.model import execution as _exec_mod # noqa: E402 +from gooddata_sdk.compute.model.execution import BareExecutionResponse # noqa: E402 +from pyarrow import ipc # noqa: E402 + def _make_ipc_stream_bytes() -> bytes: """Return minimal Arrow IPC stream bytes for a one-row table.""" - import pyarrow as pa - from pyarrow import ipc - table = pa.table({"x": pa.array([1.0])}) buf = io.BytesIO() with ipc.new_stream(buf, table.schema) as writer: @@ -44,8 +46,6 @@ def readinto(self, b: bytearray) -> int: def _make_bare(ipc_bytes: bytes): """Return a BareExecutionResponse backed by a mock API client.""" - from gooddata_sdk.compute.model.execution import BareExecutionResponse - mock_api_client = MagicMock() mock_response = _FakeResponse(ipc_bytes) mock_api_client.actions_api.api_client.call_api.return_value = mock_response @@ -66,8 +66,6 @@ def _make_bare(ipc_bytes: bytes): def test_read_result_arrow_returns_table() -> None: """read_result_arrow reads the stream from the binary endpoint and returns a pa.Table.""" - import pyarrow as pa - ipc_bytes = _make_ipc_stream_bytes() bare, mock_response = _make_bare(ipc_bytes) @@ -101,8 +99,6 @@ def test_read_result_arrow_without_cancel_token() -> None: def test_read_result_arrow_no_pyarrow_raises() -> None: """When pyarrow is not installed, read_result_arrow raises ImportError.""" - from gooddata_sdk.compute.model import execution as _exec_mod - ipc_bytes = _make_ipc_stream_bytes() bare, _ = _make_bare(ipc_bytes) diff --git a/packages/gooddata-sdk/tests/conftest.py b/packages/gooddata-sdk/tests/conftest.py index 76c03a3cc..541caafeb 100644 --- a/packages/gooddata-sdk/tests/conftest.py +++ b/packages/gooddata-sdk/tests/conftest.py @@ -6,6 +6,8 @@ import pytest import yaml +from gooddata_sdk import GoodDataSdk +from gooddata_sdk.catalog.data_source.service import CatalogDataSourceService from tests_support.vcrpy_utils import configure_normalization logger = logging.getLogger(__name__) @@ -77,8 +79,6 @@ def _patch_ds_credentials(test_config): yield return - from gooddata_sdk.catalog.data_source.service import CatalogDataSourceService - original = CatalogDataSourceService._credentials_from_file @staticmethod @@ -121,8 +121,6 @@ def staging_preflight(test_config, _patch_ds_credentials): yield return - from gooddata_sdk import GoodDataSdk - sdk = GoodDataSdk.create(host_=test_config["host"], token_=test_config["token"]) # 1. Connectivity check @@ -235,8 +233,6 @@ def staging_session_snapshot(test_config, staging_preflight): yield return - from gooddata_sdk import GoodDataSdk - sdk = GoodDataSdk.create(host_=test_config["host"], token_=test_config["token"]) # --- Capture --- diff --git a/pyproject.toml b/pyproject.toml index acd534f8d..cfd8b63da 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -93,6 +93,7 @@ lint.select = [ "I", # isort "PERF", # perflint "PIE", + "PLC0415", # force imports at module top level "PLR0402", # prevent unnecessary manual import aliases "PLR1711", # prevent useless returns "SIM", diff --git a/scripts/docs/tests/test_griffe_builder.py b/scripts/docs/tests/test_griffe_builder.py index 09fc98034..3b079dc0f 100644 --- a/scripts/docs/tests/test_griffe_builder.py +++ b/scripts/docs/tests/test_griffe_builder.py @@ -19,7 +19,7 @@ def _setup_path(monkeypatch: pytest.MonkeyPatch) -> None: @pytest.fixture() def _mod(): - import griffe_builder as mod + import griffe_builder as mod # noqa: PLC0415 return mod diff --git a/scripts/docs/tests/test_method_page_renderer.py b/scripts/docs/tests/test_method_page_renderer.py index 27b887229..fba8ce4ff 100644 --- a/scripts/docs/tests/test_method_page_renderer.py +++ b/scripts/docs/tests/test_method_page_renderer.py @@ -17,7 +17,7 @@ def _setup_path(monkeypatch: pytest.MonkeyPatch) -> None: @pytest.fixture() def _mod(): - import method_page_renderer as mod + import method_page_renderer as mod # noqa: PLC0415 return mod diff --git a/scripts/docs/tests/test_python_ref_builder.py b/scripts/docs/tests/test_python_ref_builder.py index 1278b9921..cb4935314 100644 --- a/scripts/docs/tests/test_python_ref_builder.py +++ b/scripts/docs/tests/test_python_ref_builder.py @@ -23,7 +23,7 @@ def _chdir_to_docs(monkeypatch: pytest.MonkeyPatch) -> None: @pytest.fixture() def _mod(): """Lazily import the module (after cwd/syspath are set).""" - import python_ref_builder as mod + import python_ref_builder as mod # noqa: PLC0415 return mod diff --git a/uv.lock b/uv.lock index 7cb997fb5..21ab53e36 100644 --- a/uv.lock +++ b/uv.lock @@ -2508,27 +2508,27 @@ wheels = [ [[package]] name = "ruff" -version = "0.15.10" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/e7/d9/aa3f7d59a10ef6b14fe3431706f854dbf03c5976be614a9796d36326810c/ruff-0.15.10.tar.gz", hash = "sha256:d1f86e67ebfdef88e00faefa1552b5e510e1d35f3be7d423dc7e84e63788c94e", size = 4631728, upload-time = "2026-04-09T14:06:09.884Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/eb/00/a1c2fdc9939b2c03691edbda290afcd297f1f389196172826b03d6b6a595/ruff-0.15.10-py3-none-linux_armv6l.whl", hash = "sha256:0744e31482f8f7d0d10a11fcbf897af272fefdfcb10f5af907b18c2813ff4d5f", size = 10563362, upload-time = "2026-04-09T14:06:21.189Z" }, - { url = "https://files.pythonhosted.org/packages/5c/15/006990029aea0bebe9d33c73c3e28c80c391ebdba408d1b08496f00d422d/ruff-0.15.10-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:b1e7c16ea0ff5a53b7c2df52d947e685973049be1cdfe2b59a9c43601897b22e", size = 10951122, upload-time = "2026-04-09T14:06:02.236Z" }, - { url = "https://files.pythonhosted.org/packages/f2/c0/4ac978fe874d0618c7da647862afe697b281c2806f13ce904ad652fa87e4/ruff-0.15.10-py3-none-macosx_11_0_arm64.whl", hash = "sha256:93cc06a19e5155b4441dd72808fdf84290d84ad8a39ca3b0f994363ade4cebb1", size = 10314005, upload-time = "2026-04-09T14:06:00.026Z" }, - { url = "https://files.pythonhosted.org/packages/da/73/c209138a5c98c0d321266372fc4e33ad43d506d7e5dd817dd89b60a8548f/ruff-0.15.10-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:83e1dd04312997c99ea6965df66a14fb4f03ba978564574ffc68b0d61fd3989e", size = 10643450, upload-time = "2026-04-09T14:05:42.137Z" }, - { url = "https://files.pythonhosted.org/packages/ec/76/0deec355d8ec10709653635b1f90856735302cb8e149acfdf6f82a5feb70/ruff-0.15.10-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:8154d43684e4333360fedd11aaa40b1b08a4e37d8ffa9d95fee6fa5b37b6fab1", size = 10379597, upload-time = "2026-04-09T14:05:49.984Z" }, - { url = "https://files.pythonhosted.org/packages/dc/be/86bba8fc8798c081e28a4b3bb6d143ccad3fd5f6f024f02002b8f08a9fa3/ruff-0.15.10-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8ab88715f3a6deb6bde6c227f3a123410bec7b855c3ae331b4c006189e895cef", size = 11146645, upload-time = "2026-04-09T14:06:12.246Z" }, - { url = "https://files.pythonhosted.org/packages/a8/89/140025e65911b281c57be1d385ba1d932c2366ca88ae6663685aed8d4881/ruff-0.15.10-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a768ff5969b4f44c349d48edf4ab4f91eddb27fd9d77799598e130fb628aa158", size = 12030289, upload-time = "2026-04-09T14:06:04.776Z" }, - { url = "https://files.pythonhosted.org/packages/88/de/ddacca9545a5e01332567db01d44bd8cf725f2db3b3d61a80550b48308ea/ruff-0.15.10-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0ee3ef42dab7078bda5ff6a1bcba8539e9857deb447132ad5566a038674540d0", size = 11496266, upload-time = "2026-04-09T14:05:55.485Z" }, - { url = "https://files.pythonhosted.org/packages/bc/bb/7ddb00a83760ff4a83c4e2fc231fd63937cc7317c10c82f583302e0f6586/ruff-0.15.10-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:51cb8cc943e891ba99989dd92d61e29b1d231e14811db9be6440ecf25d5c1609", size = 11256418, upload-time = "2026-04-09T14:05:57.69Z" }, - { url = "https://files.pythonhosted.org/packages/dc/8d/55de0d35aacf6cd50b6ee91ee0f291672080021896543776f4170fc5c454/ruff-0.15.10-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:e59c9bdc056a320fb9ea1700a8d591718b8faf78af065484e801258d3a76bc3f", size = 11288416, upload-time = "2026-04-09T14:05:44.695Z" }, - { url = "https://files.pythonhosted.org/packages/68/cf/9438b1a27426ec46a80e0a718093c7f958ef72f43eb3111862949ead3cc1/ruff-0.15.10-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:136c00ca2f47b0018b073f28cb5c1506642a830ea941a60354b0e8bc8076b151", size = 10621053, upload-time = "2026-04-09T14:05:52.782Z" }, - { url = "https://files.pythonhosted.org/packages/4c/50/e29be6e2c135e9cd4cb15fbade49d6a2717e009dff3766dd080fcb82e251/ruff-0.15.10-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:8b80a2f3c9c8a950d6237f2ca12b206bccff626139be9fa005f14feb881a1ae8", size = 10378302, upload-time = "2026-04-09T14:06:14.361Z" }, - { url = "https://files.pythonhosted.org/packages/18/2f/e0b36a6f99c51bb89f3a30239bc7bf97e87a37ae80aa2d6542d6e5150364/ruff-0.15.10-py3-none-musllinux_1_2_i686.whl", hash = "sha256:e3e53c588164dc025b671c9df2462429d60357ea91af7e92e9d56c565a9f1b07", size = 10850074, upload-time = "2026-04-09T14:06:16.581Z" }, - { url = "https://files.pythonhosted.org/packages/11/08/874da392558ce087a0f9b709dc6ec0d60cbc694c1c772dab8d5f31efe8cb/ruff-0.15.10-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:b0c52744cf9f143a393e284125d2576140b68264a93c6716464e129a3e9adb48", size = 11358051, upload-time = "2026-04-09T14:06:18.948Z" }, - { url = "https://files.pythonhosted.org/packages/e4/46/602938f030adfa043e67112b73821024dc79f3ab4df5474c25fa4c1d2d14/ruff-0.15.10-py3-none-win32.whl", hash = "sha256:d4272e87e801e9a27a2e8df7b21011c909d9ddd82f4f3281d269b6ba19789ca5", size = 10588964, upload-time = "2026-04-09T14:06:07.14Z" }, - { url = "https://files.pythonhosted.org/packages/25/b6/261225b875d7a13b33a6d02508c39c28450b2041bb01d0f7f1a83d569512/ruff-0.15.10-py3-none-win_amd64.whl", hash = "sha256:28cb32d53203242d403d819fd6983152489b12e4a3ae44993543d6fe62ab42ed", size = 11745044, upload-time = "2026-04-09T14:05:39.473Z" }, - { url = "https://files.pythonhosted.org/packages/58/ed/dea90a65b7d9e69888890fb14c90d7f51bf0c1e82ad800aeb0160e4bacfd/ruff-0.15.10-py3-none-win_arm64.whl", hash = "sha256:601d1610a9e1f1c2165a4f561eeaa2e2ea1e97f3287c5aa258d3dab8b57c6188", size = 11035607, upload-time = "2026-04-09T14:05:47.593Z" }, +version = "0.15.12" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/99/43/3291f1cc9106f4c63bdce7a8d0df5047fe8422a75b091c16b5e9355e0b11/ruff-0.15.12.tar.gz", hash = "sha256:ecea26adb26b4232c0c2ca19ccbc0083a68344180bba2a600605538ce51a40a6", size = 4643852, upload-time = "2026-04-24T18:17:14.305Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c3/6e/e78ffb61d4686f3d96ba3df2c801161843746dcbcbb17a1e927d4829312b/ruff-0.15.12-py3-none-linux_armv6l.whl", hash = "sha256:f86f176e188e94d6bdbc09f09bfd9dc729059ad93d0e7390b5a73efe19f8861c", size = 10640713, upload-time = "2026-04-24T18:17:22.841Z" }, + { url = "https://files.pythonhosted.org/packages/ae/08/a317bc231fb9e7b93e4ef3089501e51922ff88d6936ce5cf870c4fe55419/ruff-0.15.12-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:e3bcd123364c3770b8e1b7baaf343cc99a35f197c5c6e8af79015c666c423a6c", size = 11069267, upload-time = "2026-04-24T18:17:30.105Z" }, + { url = "https://files.pythonhosted.org/packages/aa/a4/f828e9718d3dce1f5f11c39c4f65afd32783c8b2aebb2e3d259e492c47bd/ruff-0.15.12-py3-none-macosx_11_0_arm64.whl", hash = "sha256:fe87510d000220aa1ed530d4448a7c696a0cae1213e5ec30e5874287b66557b5", size = 10397182, upload-time = "2026-04-24T18:17:07.177Z" }, + { url = "https://files.pythonhosted.org/packages/71/e0/3310fc6d1b5e1fdea22bf3b1b807c7e187b581021b0d7d4514cccdb5fb71/ruff-0.15.12-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:84a1630093121375a3e2a95b4a6dc7b59e2b4ee76216e32d81aae550a832d002", size = 10758012, upload-time = "2026-04-24T18:16:55.759Z" }, + { url = "https://files.pythonhosted.org/packages/11/c1/a606911aee04c324ddaa883ae418f3569792fd3c4a10c50e0dd0a2311e1e/ruff-0.15.12-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:fb129f40f114f089ebe0ca56c0d251cf2061b17651d464bb6478dc01e69f11f5", size = 10447479, upload-time = "2026-04-24T18:16:51.677Z" }, + { url = "https://files.pythonhosted.org/packages/9d/68/4201e8444f0894f21ab4aeeaee68aa4f10b51613514a20d80bd628d57e88/ruff-0.15.12-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b0c862b172d695db7598426b8af465e7e9ac00a3ea2a3630ee67eb82e366aaa6", size = 11234040, upload-time = "2026-04-24T18:17:16.529Z" }, + { url = "https://files.pythonhosted.org/packages/34/ff/8a6d6cf4ccc23fd67060874e832c18919d1557a0611ebef03fdb01fff11e/ruff-0.15.12-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2849ea9f3484c3aca43a82f484210370319e7170df4dfe4843395ddf6c57bc33", size = 12087377, upload-time = "2026-04-24T18:17:04.944Z" }, + { url = "https://files.pythonhosted.org/packages/85/f6/c669cf73f5152f623d34e69866a46d5e6185816b19fcd5b6dd8a2d299922/ruff-0.15.12-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9e77c7e51c07fe396826d5969a5b846d9cd4c402535835fb6e21ce8b28fef847", size = 11367784, upload-time = "2026-04-24T18:17:25.409Z" }, + { url = "https://files.pythonhosted.org/packages/e8/39/c61d193b8a1daaa8977f7dea9e8d8ba866e02ea7b65d32f6861693aa4c12/ruff-0.15.12-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:83b2f4f2f3b1026b5fb449b467d9264bf22067b600f7b6f41fc5958909f449d0", size = 11344088, upload-time = "2026-04-24T18:17:12.258Z" }, + { url = "https://files.pythonhosted.org/packages/c2/8d/49afab3645e31e12c590acb6d3b5b69d7aab5b81926dbaf7461f9441f37a/ruff-0.15.12-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:9ba3b8f1afd7e2e43d8943e55f249e13f9682fde09711644a6e7290eb4f3e339", size = 11271770, upload-time = "2026-04-24T18:17:02.457Z" }, + { url = "https://files.pythonhosted.org/packages/46/06/33f41fe94403e2b755481cdfb9b7ef3e4e0ed031c4581124658d935d52b4/ruff-0.15.12-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:e852ba9fdc890655e1d78f2df1499efbe0e54126bd405362154a75e2bde159c5", size = 10719355, upload-time = "2026-04-24T18:17:27.648Z" }, + { url = "https://files.pythonhosted.org/packages/0d/59/18aa4e014debbf559670e4048e39260a85c7fcee84acfd761ac01e7b8d35/ruff-0.15.12-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:dd8aed930da53780d22fc70bdf84452c843cf64f8cb4eb38984319c24c5cd5fd", size = 10462758, upload-time = "2026-04-24T18:17:32.347Z" }, + { url = "https://files.pythonhosted.org/packages/25/e7/cc9f16fd0f3b5fddcbd7ec3d6ae30c8f3fde1047f32a4093a98d633c6570/ruff-0.15.12-py3-none-musllinux_1_2_i686.whl", hash = "sha256:01da3988d225628b709493d7dc67c3b9b12c0210016b08690ef9bd27970b262b", size = 10953498, upload-time = "2026-04-24T18:17:20.674Z" }, + { url = "https://files.pythonhosted.org/packages/72/7a/a9ba7f98c7a575978698f4230c5e8cc54bbc761af34f560818f933dafa0c/ruff-0.15.12-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:9cae0f92bd5700d1213188b31cd3bdd2b315361296d10b96b8e2337d3d11f53e", size = 11447765, upload-time = "2026-04-24T18:17:09.755Z" }, + { url = "https://files.pythonhosted.org/packages/ea/f9/0ae446942c846b8266059ad8a30702a35afae55f5cdc54c5adf8d7afdc27/ruff-0.15.12-py3-none-win32.whl", hash = "sha256:d0185894e038d7043ba8fd6aee7499ece6462dc0ea9f1e260c7451807c714c20", size = 10657277, upload-time = "2026-04-24T18:17:18.591Z" }, + { url = "https://files.pythonhosted.org/packages/33/f1/9614e03e1cdcbf9437570b5400ced8a720b5db22b28d8e0f1bda429f660d/ruff-0.15.12-py3-none-win_amd64.whl", hash = "sha256:c87a162d61ab3adca47c03f7f717c68672edec7d1b5499e652331780fe74950d", size = 11837758, upload-time = "2026-04-24T18:17:00.113Z" }, + { url = "https://files.pythonhosted.org/packages/c0/98/6beb4b351e472e5f4c4613f7c35a5290b8be2497e183825310c4c3a3984b/ruff-0.15.12-py3-none-win_arm64.whl", hash = "sha256:a538f7a82d061cee7be55542aca1d86d1393d55d81d4fcc314370f4340930d4f", size = 11120821, upload-time = "2026-04-24T18:16:57.979Z" }, ] [[package]]