From 3c5711bf0510232f70950bd96b8b13a738bf4c0f Mon Sep 17 00:00:00 2001 From: William Bergamin Date: Tue, 1 Sep 2026 13:56:26 -0400 Subject: [PATCH 1/2] chore: replace flake8 and black with ruff Swap the two separate dev tools -- flake8 (lint) and black (format) -- for a single ruff binary that does both. - pyproject.toml: add [tool.ruff] (line-length = 125) and [tool.ruff.lint] with select = ["E", "W", "F"]; ignore = ["E402"] (the only code that fires, all in the generated legacy_client.py header region). Drop [tool.black]. - requirements/tools.txt: replace flake8 and black with ruff==0.16.4. - delete .flake8 (its only setting, max-line-length, now lives in [tool.ruff]). - scripts/format.sh: ruff check --fix + ruff format. - scripts/lint.sh: ruff format --check + ruff check. - scripts/{run_tests,run_validation,run_integration_tests}.sh: update the "Running black" echo to reference ruff. - scripts/codegen.py: emit `ruff format slack_sdk/` in the generated-file header; regenerate async_client.py, legacy_client.py, async_chat_stream.py. - .vscode/settings.json: use the ruff extension for formatting/linting. - AGENTS.md: update formatter/linter/tooling references to ruff. Co-Authored-By: Claude --- .flake8 | 2 -- .vscode/settings.json | 12 +++++++----- AGENTS.md | 11 +++++------ pyproject.toml | 6 +++++- requirements/tools.txt | 7 ++----- scripts/codegen.py | 2 +- scripts/format.sh | 3 ++- scripts/lint.sh | 4 ++-- scripts/run_integration_tests.sh | 2 +- scripts/run_tests.sh | 2 +- scripts/run_validation.sh | 2 +- slack_sdk/web/async_chat_stream.py | 2 +- slack_sdk/web/async_client.py | 2 +- slack_sdk/web/legacy_client.py | 2 +- 14 files changed, 30 insertions(+), 29 deletions(-) delete mode 100644 .flake8 diff --git a/.flake8 b/.flake8 deleted file mode 100644 index 308e748f4..000000000 --- a/.flake8 +++ /dev/null @@ -1,2 +0,0 @@ -[flake8] -max-line-length = 125 \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json index 08726984d..1c4399b26 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,9 +1,11 @@ // Place your settings in this file to overwrite default and user settings. { - "python.linting.pylintEnabled": false, - "python.linting.flake8Enabled": true, "python.venvPath": "${workspaceFolder}/env", - "python.formatting.provider": "black", "editor.formatOnSave": true, - "python.linting.enabled": true, -} \ No newline at end of file + "[python]": { + "editor.defaultFormatter": "charliermarsh.ruff", + "editor.codeActionsOnSave": { + "source.fixAll.ruff": "explicit" + } + } +} diff --git a/AGENTS.md b/AGENTS.md index c84747d9f..ca1be9139 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -64,7 +64,7 @@ Each contains a header warning: # DO NOT EDIT THIS FILE # 1) Modify slack_sdk/web/client.py # 2) Run `python scripts/codegen.py` -# 3) Run `black slack_sdk/` +# 3) Run `ruff format slack_sdk/` ``` **How it works:** @@ -215,8 +215,8 @@ Available scripts in the `scripts/` directory: All tooling configuration is defined in the following files: -- **Formatter**: `black` — see `[tool.black]` in `pyproject.toml` -- **Linter**: `flake8` — see `.flake8` +- **Formatter**: `ruff format` — see `[tool.ruff]` in `pyproject.toml` +- **Linter**: `ruff check` — see `[tool.ruff.lint]` in `pyproject.toml` - **Type checker**: `mypy` — see `[tool.mypy]` in `pyproject.toml` - **Test runner**: `pytest` — see `[tool.pytest.ini_options]` in `pyproject.toml` - **Coverage**: `pytest-cov` reporting to Codecov @@ -226,7 +226,7 @@ All tooling configuration is defined in the following files: - Testing: `requirements/testing.txt` - Optional runtime: `requirements/optional.txt` -- Dev tools (black, flake8, mypy): `requirements/tools.txt` +- Dev tools (ruff, mypy): `requirements/tools.txt` ## CI Pipeline (GitHub Actions) @@ -244,8 +244,7 @@ Defined in `.github/workflows/ci-build.yml`, runs on push to `main`, all PRs, an **Configuration:** -- `pyproject.toml` — Project metadata, build config, tool settings (black, pytest, mypy) -- `.flake8` — Flake8 linter configuration +- `pyproject.toml` — Project metadata, build config, tool settings (ruff, pytest, mypy) - `requirements/*.txt` — Dependency specifications **Tooling:** diff --git a/pyproject.toml b/pyproject.toml index 8a74a0d93..5883eb1b8 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -55,9 +55,13 @@ optional-dependencies.optional = { file = ["requirements/optional.txt"] } [tool.distutils.bdist_wheel] universal = true -[tool.black] +[tool.ruff] line-length = 125 +[tool.ruff.lint] +select = ["E", "W", "F"] +ignore = ["E402"] + [tool.pytest.ini_options] testpaths = ["tests"] log_file = "logs/pytest.log" diff --git a/requirements/tools.txt b/requirements/tools.txt index 0308df3af..49b98e954 100644 --- a/requirements/tools.txt +++ b/requirements/tools.txt @@ -3,8 +3,5 @@ # mypy mypy<=2.1.0 -# flake8 -flake8>=7.3.0,<8 - -# black -black==26.3.1 +# ruff +ruff==0.16.4 diff --git a/scripts/codegen.py b/scripts/codegen.py index 3633faf35..9abce2156 100644 --- a/scripts/codegen.py +++ b/scripts/codegen.py @@ -15,7 +15,7 @@ "#\n" "# 1) Modify slack_sdk/web/client.py\n" "# 2) Run `python scripts/codegen.py`\n" - "# 3) Run `black slack_sdk/`\n" + "# 3) Run `ruff format slack_sdk/`\n" "#\n" "# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n" "\n" diff --git a/scripts/format.sh b/scripts/format.sh index aa18459ab..f0b3f0b1c 100755 --- a/scripts/format.sh +++ b/scripts/format.sh @@ -9,4 +9,5 @@ if [[ "$1" != "--no-install" ]]; then pip install -U -r requirements/tools.txt fi -black slack/ slack_sdk/ tests/ integration_tests/ +ruff check --fix slack/ slack_sdk/ +ruff format slack/ slack_sdk/ tests/ integration_tests/ diff --git a/scripts/lint.sh b/scripts/lint.sh index 8fac67888..9b3aef512 100755 --- a/scripts/lint.sh +++ b/scripts/lint.sh @@ -10,5 +10,5 @@ if [[ "$1" != "--no-install" ]]; then pip install -U -r requirements/tools.txt fi -black --check slack/ slack_sdk/ tests/ integration_tests/ -flake8 slack/ slack_sdk/ +ruff format --check slack/ slack_sdk/ tests/ integration_tests/ +ruff check slack/ slack_sdk/ diff --git a/scripts/run_integration_tests.sh b/scripts/run_integration_tests.sh index 7fa598a9b..1f7a9eb98 100755 --- a/scripts/run_integration_tests.sh +++ b/scripts/run_integration_tests.sh @@ -11,7 +11,7 @@ cd ${script_dir}/.. ./scripts/install.sh echo "Generating code ..." && python scripts/codegen.py --path . -echo "Running black (code formatter) ..." && ./scripts/format.sh --no-install +echo "Running ruff (code formatter) ..." && ./scripts/format.sh --no-install test_target="${1:-tests/integration_tests/}" PYTHONPATH=$PWD:$PYTHONPATH pytest $test_target diff --git a/scripts/run_tests.sh b/scripts/run_tests.sh index 898be91a7..995cd5226 100755 --- a/scripts/run_tests.sh +++ b/scripts/run_tests.sh @@ -11,7 +11,7 @@ cd ${script_dir}/.. test_target="${1:-tests/}" echo "Generating code ..." && python scripts/codegen.py --path . -echo "Running black (code formatter) ..." && ./scripts/format.sh --no-install +echo "Running ruff (code formatter) ..." && ./scripts/format.sh --no-install echo "Running tests ..." PYTHONPATH=$PWD:$PYTHONPATH pytest $test_target diff --git a/scripts/run_validation.sh b/scripts/run_validation.sh index 2de6cace0..633c40c0b 100755 --- a/scripts/run_validation.sh +++ b/scripts/run_validation.sh @@ -17,7 +17,7 @@ echo "Generating code ..." && python scripts/codegen.py --path . # Run mypy type checking only on the latest supported Python version if [[ "$current_py" == "$LATEST_SUPPORTED_PY" ]]; then - echo "Running black (code formatter) ..." && ./scripts/format.sh --no-install + echo "Running ruff (code formatter) ..." && ./scripts/format.sh --no-install echo "Running linting checks ..." && ./scripts/lint.sh --no-install echo "Running mypy type checking ..." && ./scripts/run_mypy.sh --no-install else diff --git a/slack_sdk/web/async_chat_stream.py b/slack_sdk/web/async_chat_stream.py index f5848b31e..b74a7ff43 100644 --- a/slack_sdk/web/async_chat_stream.py +++ b/slack_sdk/web/async_chat_stream.py @@ -4,7 +4,7 @@ # # 1) Modify slack_sdk/web/client.py # 2) Run `python scripts/codegen.py` -# 3) Run `black slack_sdk/` +# 3) Run `ruff format slack_sdk/` # # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! diff --git a/slack_sdk/web/async_client.py b/slack_sdk/web/async_client.py index 34f4ef934..e485a9609 100644 --- a/slack_sdk/web/async_client.py +++ b/slack_sdk/web/async_client.py @@ -4,7 +4,7 @@ # # 1) Modify slack_sdk/web/client.py # 2) Run `python scripts/codegen.py` -# 3) Run `black slack_sdk/` +# 3) Run `ruff format slack_sdk/` # # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! diff --git a/slack_sdk/web/legacy_client.py b/slack_sdk/web/legacy_client.py index c538e67af..e1da45db1 100644 --- a/slack_sdk/web/legacy_client.py +++ b/slack_sdk/web/legacy_client.py @@ -4,7 +4,7 @@ # # 1) Modify slack_sdk/web/client.py # 2) Run `python scripts/codegen.py` -# 3) Run `black slack_sdk/` +# 3) Run `ruff format slack_sdk/` # # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! From 23b4ae4a1298a80a5833d504f58fcab91a4e8342 Mon Sep 17 00:00:00 2001 From: William Bergamin Date: Tue, 1 Sep 2026 15:15:12 -0400 Subject: [PATCH 2/2] style: apply ruff format across the codebase One-time mechanical reformat from adopting `ruff format` in place of black. Only the documented ruff-vs-black differences (implicit string-concat joining, f-string inner-quote normalization, blank-line-at-block-start removal, subscript/lambda reflow) plus ruff's formatting of Python code blocks inside Markdown. No behavior changes. Co-Authored-By: Claude --- integration_tests/rtm/test_issue_530.py | 4 +-- .../samples/conversations/open_dm.py | 4 +-- ...test_admin_conversations_restrictAccess.py | 4 +-- integration_tests/web/test_calls.py | 4 +-- slack/web/classes/readme.md | 12 ++++----- slack_sdk/audit_logs/v1/async_client.py | 2 +- slack_sdk/models/AGENTS.md | 9 ++++++- slack_sdk/models/basic_objects.py | 2 +- slack_sdk/models/blocks/block_elements.py | 2 +- slack_sdk/models/messages/message.py | 2 +- .../oauth/authorize_url_generator/__init__.py | 8 +----- slack_sdk/oauth/state_utils/__init__.py | 4 +-- slack_sdk/rtm_v2/__init__.py | 14 +++++------ slack_sdk/scim/v1/async_client.py | 2 +- slack_sdk/socket_mode/aiohttp/__init__.py | 4 +-- slack_sdk/socket_mode/async_client.py | 5 +--- slack_sdk/socket_mode/builtin/client.py | 12 ++++----- slack_sdk/socket_mode/builtin/connection.py | 25 ++++++++----------- slack_sdk/web/async_internal_utils.py | 6 ++--- slack_sdk/web/internal_utils.py | 7 +----- slack_sdk/web/legacy_client.py | 1 + slack_sdk/web/legacy_slack_response.py | 5 +--- slack_sdk/webhook/async_client.py | 2 +- tests/mock_web_api_server/__init__.py | 12 ++++----- tests/rtm/test_rtm_client.py | 2 +- tests/slack_sdk/models/test_attachments.py | 2 +- tests/slack_sdk/models/test_blocks.py | 4 +-- tests/web/classes/test_attachments.py | 2 +- tests/web/test_web_client.py | 2 +- tests/web/test_web_client_issue_829.py | 2 +- 30 files changed, 71 insertions(+), 95 deletions(-) diff --git a/integration_tests/rtm/test_issue_530.py b/integration_tests/rtm/test_issue_530.py index cd992b7c3..0c0e25c5d 100644 --- a/integration_tests/rtm/test_issue_530.py +++ b/integration_tests/rtm/test_issue_530.py @@ -27,7 +27,7 @@ def test_issue_530(self): self.fail("Raising an error here was expected") except Exception as e: self.assertEqual( - "The request to the Slack API failed.\n" "The server responded with: {'ok': False, 'error': 'invalid_auth'}", + "The request to the Slack API failed.\nThe server responded with: {'ok': False, 'error': 'invalid_auth'}", str(e), ) finally: @@ -42,7 +42,7 @@ async def test_issue_530_async(self): self.fail("Raising an error here was expected") except Exception as e: self.assertEqual( - "The request to the Slack API failed.\n" "The server responded with: {'ok': False, 'error': 'invalid_auth'}", + "The request to the Slack API failed.\nThe server responded with: {'ok': False, 'error': 'invalid_auth'}", str(e), ) finally: diff --git a/integration_tests/samples/conversations/open_dm.py b/integration_tests/samples/conversations/open_dm.py index 86786c885..e5c690253 100644 --- a/integration_tests/samples/conversations/open_dm.py +++ b/integration_tests/samples/conversations/open_dm.py @@ -11,8 +11,8 @@ client = WebClient(token=os.environ["SLACK_API_TOKEN"]) all_users = client.users_list(limit=100)["members"] -joinable_only = ( - lambda u: u["id"] != "USLACKBOT" +joinable_only = lambda u: ( + u["id"] != "USLACKBOT" and not u["is_bot"] and not u["is_app_user"] and not u["deleted"] diff --git a/integration_tests/web/test_admin_conversations_restrictAccess.py b/integration_tests/web/test_admin_conversations_restrictAccess.py index 97915abe5..8a9d0031a 100644 --- a/integration_tests/web/test_admin_conversations_restrictAccess.py +++ b/integration_tests/web/test_admin_conversations_restrictAccess.py @@ -43,9 +43,7 @@ def setUp(self): self.channel_id = client.conversations_create( name=channel_name, is_private=True, - )[ - "channel" - ]["id"] + )["channel"]["id"] def tearDown(self): pass diff --git a/integration_tests/web/test_calls.py b/integration_tests/web/test_calls.py index d285c03f0..78df5a46d 100644 --- a/integration_tests/web/test_calls.py +++ b/integration_tests/web/test_calls.py @@ -29,9 +29,7 @@ def test_sync(self): lambda u: not u["deleted"] and "bot_id" not in u, client.users_list(limit=50)["members"], ) - )[ - 0 - ]["id"] + )[0]["id"] new_call = client.calls_add( external_unique_id=str(uuid.uuid4()), diff --git a/slack/web/classes/readme.md b/slack/web/classes/readme.md index 27ca73714..d6c4271a1 100644 --- a/slack/web/classes/readme.md +++ b/slack/web/classes/readme.md @@ -35,12 +35,12 @@ from slack.web.classes import dialogs builder = ( dialogs.DialogBuilder() - .title("My Cool Dialog") - .callback_id("myCoolDialog") - .state({'value': 123, 'key': "something"}) - .conversation_selector(name="target", label="Choose Target") - .text_area(name="message", label="Message", hint="Enter a message", max_length=500) - .text_field(name="signature", label="Signature", optional=True, max_length=50) + .title("My Cool Dialog") + .callback_id("myCoolDialog") + .state({"value": 123, "key": "something"}) + .conversation_selector(name="target", label="Choose Target") + .text_area(name="message", label="Message", hint="Enter a message", max_length=500) + .text_field(name="signature", label="Signature", optional=True, max_length=50) ) client = WebClient(token="abc") diff --git a/slack_sdk/audit_logs/v1/async_client.py b/slack_sdk/audit_logs/v1/async_client.py index 7de8fd5b2..098e712f0 100644 --- a/slack_sdk/audit_logs/v1/async_client.py +++ b/slack_sdk/audit_logs/v1/async_client.py @@ -337,7 +337,7 @@ async def _perform_http_request( ): if self.logger.level <= logging.DEBUG: self.logger.info( - f"A retry handler found: {type(handler).__name__} " f"for {http_verb} {url} - {e}" + f"A retry handler found: {type(handler).__name__} for {http_verb} {url} - {e}" ) await handler.prepare_for_next_attempt_async( state=retry_state, diff --git a/slack_sdk/models/AGENTS.md b/slack_sdk/models/AGENTS.md index 6d3cec16b..dee8441c6 100644 --- a/slack_sdk/models/AGENTS.md +++ b/slack_sdk/models/AGENTS.md @@ -41,7 +41,14 @@ Choose the base class that matches the type you're adding. def attributes(self) -> Set[str]: return super().attributes.union({"text", "optional_field"}) - def __init__(self, *, text: Union[str, dict, TextObject], optional_field: Optional[str] = None, block_id: Optional[str] = None, **others: dict): + def __init__( + self, + *, + text: Union[str, dict, TextObject], + optional_field: Optional[str] = None, + block_id: Optional[str] = None, + **others: dict, + ): super().__init__(type=self.type, block_id=block_id) show_unknown_key_warning(self, others) self.text = TextObject.parse(text, default_type=PlainTextObject.type) diff --git a/slack_sdk/models/basic_objects.py b/slack_sdk/models/basic_objects.py index 4feefe3f6..8f1de85b9 100644 --- a/slack_sdk/models/basic_objects.py +++ b/slack_sdk/models/basic_objects.py @@ -132,4 +132,4 @@ def wrapped_f(*args, **kwargs): class EnumValidator(JsonValidator): def __init__(self, attribute: str, enum: Iterable[str]): - super().__init__(f"{attribute} attribute must be one of the following values: " f"{', '.join(enum)}") + super().__init__(f"{attribute} attribute must be one of the following values: {', '.join(enum)}") diff --git a/slack_sdk/models/blocks/block_elements.py b/slack_sdk/models/blocks/block_elements.py index 7b52b0f95..5ffa1f0d6 100644 --- a/slack_sdk/models/blocks/block_elements.py +++ b/slack_sdk/models/blocks/block_elements.py @@ -1916,7 +1916,7 @@ def __init__( self.options = options self.confirm = ConfirmObject.parse(confirm) # type: ignore[arg-type] - @JsonValidator(f"options attribute must have between {options_min_length} " f"and {options_max_length} items") + @JsonValidator(f"options attribute must have between {options_min_length} and {options_max_length} items") def _validate_options_length(self) -> bool: return self.options_min_length <= len(self.options) <= self.options_max_length diff --git a/slack_sdk/models/messages/message.py b/slack_sdk/models/messages/message.py index d4744aae7..6d510dac1 100644 --- a/slack_sdk/models/messages/message.py +++ b/slack_sdk/models/messages/message.py @@ -15,7 +15,7 @@ skip_warn = os.environ.get("SLACKCLIENT_SKIP_DEPRECATION") # for unit tests etc. if not skip_warn: - message = "This class is no longer actively maintained. " "Please use a dict object for building message data instead." + message = "This class is no longer actively maintained. Please use a dict object for building message data instead." warnings.warn(message) diff --git a/slack_sdk/oauth/authorize_url_generator/__init__.py b/slack_sdk/oauth/authorize_url_generator/__init__.py index f2617bec6..652fe7dc4 100644 --- a/slack_sdk/oauth/authorize_url_generator/__init__.py +++ b/slack_sdk/oauth/authorize_url_generator/__init__.py @@ -20,13 +20,7 @@ def __init__( def generate(self, state: str, team: Optional[str] = None) -> str: scopes = ",".join(self.scopes) if self.scopes else "" user_scopes = ",".join(self.user_scopes) if self.user_scopes else "" - url = ( - f"{self.authorization_url}?" - f"state={state}&" - f"client_id={self.client_id}&" - f"scope={scopes}&" - f"user_scope={user_scopes}" - ) + url = f"{self.authorization_url}?state={state}&client_id={self.client_id}&scope={scopes}&user_scope={user_scopes}" if self.redirect_uri is not None: url += f"&redirect_uri={self.redirect_uri}" if team is not None: diff --git a/slack_sdk/oauth/state_utils/__init__.py b/slack_sdk/oauth/state_utils/__init__.py index cfdb66bcb..8c12707ae 100644 --- a/slack_sdk/oauth/state_utils/__init__.py +++ b/slack_sdk/oauth/state_utils/__init__.py @@ -18,10 +18,10 @@ def __init__( self.expiration_seconds = expiration_seconds def build_set_cookie_for_new_state(self, state: str) -> str: - return f"{self.cookie_name}={state}; " "Secure; " "HttpOnly; " "Path=/; " f"Max-Age={self.expiration_seconds}" + return f"{self.cookie_name}={state}; Secure; HttpOnly; Path=/; Max-Age={self.expiration_seconds}" def build_set_cookie_for_deletion(self) -> str: - return f"{self.cookie_name}=deleted; " "Secure; " "HttpOnly; " "Path=/; " "Expires=Thu, 01 Jan 1970 00:00:00 GMT" + return f"{self.cookie_name}=deleted; Secure; HttpOnly; Path=/; Expires=Thu, 01 Jan 1970 00:00:00 GMT" def is_valid_browser( self, diff --git a/slack_sdk/rtm_v2/__init__.py b/slack_sdk/rtm_v2/__init__.py index be059303d..f54cb35b7 100644 --- a/slack_sdk/rtm_v2/__init__.py +++ b/slack_sdk/rtm_v2/__init__.py @@ -348,7 +348,7 @@ def run_all_message_listeners(self, message: str): def run_all_error_listeners(self, error: Exception): self.logger.exception( - f"on_error invoked (session id: {self.session_id()}, " f"error: {type(error).__name__}, message: {error})" + f"on_error invoked (session id: {self.session_id()}, error: {type(error).__name__}, message: {error})" ) for listener in self.on_error_listeners: listener(error) @@ -357,7 +357,7 @@ def run_all_close_listeners(self, code: int, reason: Optional[str] = None): if self.logger.level <= logging.DEBUG: self.logger.debug(f"on_close invoked (session id: {self.session_id()})") if self.auto_reconnect_enabled: - self.logger.info("Received CLOSE event. Going to reconnect... " f"(session id: {self.session_id()})") + self.logger.info(f"Received CLOSE event. Going to reconnect... (session id: {self.session_id()})") self.connect_to_new_endpoint() for listener in self.on_close_listeners: listener(code, reason) @@ -366,14 +366,12 @@ def _run_current_session(self): if self.current_session is not None and self.current_session.is_active(): session_id = self.session_id() try: - self.logger.info("Starting to receive messages from a new connection" f" (session id: {session_id})") + self.logger.info(f"Starting to receive messages from a new connection (session id: {session_id})") self.current_session_state.terminated = False self.current_session.run_until_completion(self.current_session_state) - self.logger.info("Stopped receiving messages from a connection" f" (session id: {session_id})") + self.logger.info(f"Stopped receiving messages from a connection (session id: {session_id})") except Exception as e: - self.logger.exception( - "Failed to start or stop the current session" f" (session id: {session_id}, error: {e})" - ) + self.logger.exception(f"Failed to start or stop the current session (session id: {session_id}, error: {e})") def _monitor_current_session(self): if self.current_app_monitor_started: @@ -382,7 +380,7 @@ def _monitor_current_session(self): if self.auto_reconnect_enabled and (self.current_session is None or not self.current_session.is_active()): self.logger.info( - "The session seems to be already closed. Going to reconnect... " f"(session id: {self.session_id()})" + f"The session seems to be already closed. Going to reconnect... (session id: {self.session_id()})" ) self.connect_to_new_endpoint() except Exception as e: diff --git a/slack_sdk/scim/v1/async_client.py b/slack_sdk/scim/v1/async_client.py index ad92ac49f..c18128366 100644 --- a/slack_sdk/scim/v1/async_client.py +++ b/slack_sdk/scim/v1/async_client.py @@ -380,7 +380,7 @@ async def _perform_http_request( ): if self.logger.level <= logging.DEBUG: self.logger.info( - f"A retry handler found: {type(handler).__name__} " f"for {http_verb} {url} - {e}" + f"A retry handler found: {type(handler).__name__} for {http_verb} {url} - {e}" ) await handler.prepare_for_next_attempt_async( state=retry_state, diff --git a/slack_sdk/socket_mode/aiohttp/__init__.py b/slack_sdk/socket_mode/aiohttp/__init__.py index 761683020..a31fd2c15 100644 --- a/slack_sdk/socket_mode/aiohttp/__init__.py +++ b/slack_sdk/socket_mode/aiohttp/__init__.py @@ -435,9 +435,7 @@ async def send_message(self, message: str): if await self.is_connected(): await self.current_session.send_str(message) # type: ignore[union-attr] else: - self.logger.warning( - f"The current session ({session_id}) is no longer active. " "Failed to send a message" - ) + self.logger.warning(f"The current session ({session_id}) is no longer active. Failed to send a message") raise e finally: if self.connect_operation_lock.locked() is True: diff --git a/slack_sdk/socket_mode/async_client.py b/slack_sdk/socket_mode/async_client.py index 67d27e0f9..32e60ae3d 100644 --- a/slack_sdk/socket_mode/async_client.py +++ b/slack_sdk/socket_mode/async_client.py @@ -168,8 +168,5 @@ async def run_message_listeners(self, message: dict, raw_message: str) -> None: finally: if self.logger.level <= logging.DEBUG: self.logger.debug( - f"Message processing completed (" - f"type: {type}, " - f"envelope_id: {envelope_id}, " - f"session: {session_id})" + f"Message processing completed (type: {type}, envelope_id: {envelope_id}, session: {session_id})" ) diff --git a/slack_sdk/socket_mode/builtin/client.py b/slack_sdk/socket_mode/builtin/client.py index be80e0526..43967ff29 100644 --- a/slack_sdk/socket_mode/builtin/client.py +++ b/slack_sdk/socket_mode/builtin/client.py @@ -240,7 +240,7 @@ def _on_message(self, message: str): def _on_error(self, error: Exception): error_message = ( - f"on_error invoked (session id: {self.session_id()}, " f"error: {type(error).__name__}, message: {error})" + f"on_error invoked (session id: {self.session_id()}, error: {type(error).__name__}, message: {error})" ) if self.trace_enabled: self.logger.exception(error_message) @@ -254,7 +254,7 @@ def _on_close(self, code: int, reason: Optional[str] = None): if self.logger.level <= logging.DEBUG: self.logger.debug(f"on_close invoked (session id: {self.session_id()})") if self.auto_reconnect_enabled: - self.logger.info("Received CLOSE event. Reconnecting... " f"(session id: {self.session_id()})") + self.logger.info(f"Received CLOSE event. Reconnecting... (session id: {self.session_id()})") self.connect_to_new_endpoint() for listener in self.on_close_listeners: listener(code, reason) @@ -263,12 +263,12 @@ def _run_current_session(self): if self.current_session is not None and self.current_session.is_active(): session_id = self.session_id() try: - self.logger.info("Starting to receive messages from a new connection" f" (session id: {session_id})") + self.logger.info(f"Starting to receive messages from a new connection (session id: {session_id})") self.current_session_state.terminated = False self.current_session.run_until_completion(self.current_session_state) - self.logger.info("Stopped receiving messages from a connection" f" (session id: {session_id})") + self.logger.info(f"Stopped receiving messages from a connection (session id: {session_id})") except Exception as e: - error_message = "Failed to start or stop the current session" f" (session id: {session_id}, error: {e})" + error_message = f"Failed to start or stop the current session (session id: {session_id}, error: {e})" if self.trace_enabled: self.logger.exception(error_message) else: @@ -281,7 +281,7 @@ def _monitor_current_session(self): if self.auto_reconnect_enabled and (self.current_session is None or not self.current_session.is_active()): self.logger.info( - "The session seems to be already closed. Reconnecting... " f"(session id: {self.session_id()})" + f"The session seems to be already closed. Reconnecting... (session id: {self.session_id()})" ) self.connect_to_new_endpoint() except Exception as e: diff --git a/slack_sdk/socket_mode/builtin/connection.py b/slack_sdk/socket_mode/builtin/connection.py index c8b9c437e..588f50497 100644 --- a/slack_sdk/socket_mode/builtin/connection.py +++ b/slack_sdk/socket_mode/builtin/connection.py @@ -102,7 +102,7 @@ def connect(self) -> None: port: int = parsed_url.port or (443 if parsed_url.scheme == "wss" else 80) if self.trace_enabled: self.logger.debug( - f"Connecting to the address for handshake: {hostname}:{port} " f"(session id: {self.session_id})" + f"Connecting to the address for handshake: {hostname}:{port} (session id: {self.session_id})" ) sock: Union[ssl.SSLSocket, socket] = _establish_new_socket_connection( # type: ignore[valid-type] session_id=self.session_id, @@ -204,7 +204,7 @@ def ping(self, payload: Union[str, bytes] = "") -> None: if self.trace_enabled and self.ping_pong_trace_enabled: if isinstance(payload, bytes): payload = payload.decode("utf-8") - self.logger.debug("Sending a ping data frame " f"(session id: {self.session_id}, payload: {payload})") + self.logger.debug(f"Sending a ping data frame (session id: {self.session_id}, payload: {payload})") data = _build_data_frame_for_sending(payload, FrameHeader.OPCODE_PING) with self.sock_send_lock: if self.sock is not None: @@ -217,7 +217,7 @@ def pong(self, payload: Union[str, bytes] = "") -> None: if self.trace_enabled and self.ping_pong_trace_enabled: if isinstance(payload, bytes): payload = payload.decode("utf-8") - self.logger.debug("Sending a pong data frame " f"(session id: {self.session_id}, payload: {payload})") + self.logger.debug(f"Sending a pong data frame (session id: {self.session_id}, payload: {payload})") data = _build_data_frame_for_sending(payload, FrameHeader.OPCODE_PONG) with self.sock_send_lock: if self.sock is not None: @@ -230,7 +230,7 @@ def send(self, payload: str) -> None: if self.trace_enabled: if isinstance(payload, bytes): payload = payload.decode("utf-8") - self.logger.debug("Sending a text data frame " f"(session id: {self.session_id}, payload: {payload})") + self.logger.debug(f"Sending a text data frame (session id: {self.session_id}, payload: {payload})") data = _build_data_frame_for_sending(payload, FrameHeader.OPCODE_TEXT) with self.sock_send_lock: try: @@ -278,12 +278,11 @@ def check_state(self) -> None: self.disconnect() return else: - self.logger.debug("This connection is already closed." f" (session id: {self.session_id})") + self.logger.debug(f"This connection is already closed. (session id: {self.session_id})") self.consecutive_check_state_error_count = 0 except Exception as e: error_message = ( - "Failed to check the state of sock " - f"(session id: {self.session_id}, error: {type(e).__name__}, message: {e})" + f"Failed to check the state of sock (session id: {self.session_id}, error: {type(e).__name__}, message: {e})" ) if self.trace_enabled: self.logger.exception(error_message) @@ -375,7 +374,7 @@ def run_until_completion(self, state: ConnectionState) -> None: self.last_ping_pong_time = float(ping_time) except Exception as e: self.logger.debug( - "Failed to parse a pong message " f" (message: {str_message}, error: {e}" + f"Failed to parse a pong message (message: {str_message}, error: {e}" ) elif header.opcode == FrameHeader.OPCODE_TEXT: if self.on_message_listener is not None: @@ -413,13 +412,13 @@ def run_until_completion(self, state: ConnectionState) -> None: # getting errno.EBADF and the socket is no longer available if e.errno == 9 and state.terminated: self.logger.debug( - "The reason why you got [Errno 9] Bad file descriptor here is " "the socket is no longer available." + "The reason why you got [Errno 9] Bad file descriptor here is the socket is no longer available." ) else: if self.on_error_listener is not None: self.on_error_listener(e) else: - error_message = "Got an OSError while receiving data" f" (session id: {self.session_id}, error: {e})" + error_message = f"Got an OSError while receiving data (session id: {self.session_id}, error: {e})" if self.trace_enabled: self.logger.exception(error_message) else: @@ -430,9 +429,7 @@ def run_until_completion(self, state: ConnectionState) -> None: try: self.disconnect() except Exception as disconnection_error: - error_message = ( - "Failed to disconnect" f" (session id: {self.session_id}, error: {disconnection_error})" - ) + error_message = f"Failed to disconnect (session id: {self.session_id}, error: {disconnection_error})" if self.trace_enabled: self.logger.exception(error_message) else: @@ -443,7 +440,7 @@ def run_until_completion(self, state: ConnectionState) -> None: if self.on_error_listener is not None: self.on_error_listener(e) else: - error_message = "Got an exception while receiving data" f" (session id: {self.session_id}, error: {e})" + error_message = f"Got an exception while receiving data (session id: {self.session_id}, error: {e})" if self.trace_enabled: self.logger.exception(error_message) else: diff --git a/slack_sdk/web/async_internal_utils.py b/slack_sdk/web/async_internal_utils.py index 01e214cb3..d41b34938 100644 --- a/slack_sdk/web/async_internal_utils.py +++ b/slack_sdk/web/async_internal_utils.py @@ -168,7 +168,7 @@ def convert_params(values: dict) -> dict: response=retry_response, ): if logger.level <= logging.DEBUG: - logger.info(f"A retry handler found: {type(handler).__name__} " f"for {http_verb} {api_url}") + logger.info(f"A retry handler found: {type(handler).__name__} for {http_verb} {api_url}") await handler.prepare_for_next_attempt_async( state=retry_state, request=retry_request, @@ -194,9 +194,7 @@ def convert_params(values: dict) -> dict: error=e, ): if logger.level <= logging.DEBUG: - logger.info( - f"A retry handler found: {type(handler).__name__} " f"for {http_verb} {api_url} - {e}" - ) + logger.info(f"A retry handler found: {type(handler).__name__} for {http_verb} {api_url} - {e}") await handler.prepare_for_next_attempt_async( state=retry_state, request=retry_request, diff --git a/slack_sdk/web/internal_utils.py b/slack_sdk/web/internal_utils.py index cb48d9fa9..8e725f138 100644 --- a/slack_sdk/web/internal_utils.py +++ b/slack_sdk/web/internal_utils.py @@ -415,12 +415,7 @@ def _upload_file_via_v2_url( # read the response body here body: str = resp.read().decode(charset) if logger.level <= logging.DEBUG: - message = ( - "Received the following response - " - f"status: {resp.status}, " - f"headers: {dict(resp.headers)}, " - f"body: {body}" - ) + message = f"Received the following response - status: {resp.status}, headers: {dict(resp.headers)}, body: {body}" logger.debug(message) return {"status": resp.status, "headers": resp.headers, "body": body} diff --git a/slack_sdk/web/legacy_client.py b/slack_sdk/web/legacy_client.py index e1da45db1..4b6b0b480 100644 --- a/slack_sdk/web/legacy_client.py +++ b/slack_sdk/web/legacy_client.py @@ -9,6 +9,7 @@ # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! from asyncio import Future + """A Python module for interacting with Slack's Web API.""" import json diff --git a/slack_sdk/web/legacy_slack_response.py b/slack_sdk/web/legacy_slack_response.py index d665a5050..3942389a2 100644 --- a/slack_sdk/web/legacy_slack_response.py +++ b/slack_sdk/web/legacy_slack_response.py @@ -195,10 +195,7 @@ def validate(self): if self._logger.level <= logging.DEBUG: body = self.data if isinstance(self.data, dict) else "(binary)" self._logger.debug( - "Received the following response - " - f"status: {self.status_code}, " - f"headers: {dict(self.headers)}, " - f"body: {body}" + f"Received the following response - status: {self.status_code}, headers: {dict(self.headers)}, body: {body}" ) if self.status_code == 200 and self.data and (isinstance(self.data, bytes) or self.data.get("ok", False)): return self diff --git a/slack_sdk/webhook/async_client.py b/slack_sdk/webhook/async_client.py index dded0491f..9e2965c1d 100644 --- a/slack_sdk/webhook/async_client.py +++ b/slack_sdk/webhook/async_client.py @@ -247,7 +247,7 @@ async def _perform_http_request(self, *, body: Dict[str, Any], headers: Dict[str ): if self.logger.level <= logging.DEBUG: self.logger.info( - f"A retry handler found: {type(handler).__name__} " f"for POST {self.url} - {e}" + f"A retry handler found: {type(handler).__name__} for POST {self.url} - {e}" ) await handler.prepare_for_next_attempt_async( state=retry_state, diff --git a/tests/mock_web_api_server/__init__.py b/tests/mock_web_api_server/__init__.py index 0c582ae40..d7b0b60b0 100644 --- a/tests/mock_web_api_server/__init__.py +++ b/tests/mock_web_api_server/__init__.py @@ -32,9 +32,9 @@ def assert_received_request_count(test: TestCase, path: str, min_count: int, tim while time.time() - start_time < timeout: try: received_count = test.received_requests.get(path, 0) - assert ( - received_count == min_count - ), f"Expected {min_count} '{path}' {'requests' if min_count > 1 else 'request'}, but got {received_count}!" + assert received_count == min_count, ( + f"Expected {min_count} '{path}' {'requests' if min_count > 1 else 'request'}, but got {received_count}!" + ) return except Exception as e: error = e @@ -76,9 +76,9 @@ async def assert_received_request_count_async(test: TestCase, path: str, min_cou while time.time() - start_time < timeout: try: received_count = await test.received_requests.get_async(path, 0) - assert ( - received_count == min_count - ), f"Expected {min_count} '{path}' {'requests' if min_count > 1 else 'request'}, but got {received_count}!" + assert received_count == min_count, ( + f"Expected {min_count} '{path}' {'requests' if min_count > 1 else 'request'}, but got {received_count}!" + ) return except Exception as e: error = e diff --git a/tests/rtm/test_rtm_client.py b/tests/rtm/test_rtm_client.py index ece3e57ac..c9b3776a4 100644 --- a/tests/rtm/test_rtm_client.py +++ b/tests/rtm/test_rtm_client.py @@ -86,6 +86,6 @@ def test_start_raises_an_error_if_rtm_ws_url_is_not_returned(self): slack.RTMClient(token="xoxp-1234", auto_reconnect=False).start() expected_error = ( - "The request to the Slack API failed.\n" "The server responded with: {'ok': False, 'error': 'invalid_auth'}" + "The request to the Slack API failed.\nThe server responded with: {'ok': False, 'error': 'invalid_auth'}" ) self.assertIn(expected_error, str(context.exception)) diff --git a/tests/slack_sdk/models/test_attachments.py b/tests/slack_sdk/models/test_attachments.py index 7fbce0eeb..22353f1c3 100644 --- a/tests/slack_sdk/models/test_attachments.py +++ b/tests/slack_sdk/models/test_attachments.py @@ -198,7 +198,7 @@ def test_actions_length(self): actions = [ActionButton(name="button_1", text="Click me", value="button_value_1")] * 6 with self.assertRaises(SlackObjectFormationError): - InteractiveAttachment(text="some text", callback_id="abc123", actions=actions).to_dict(), + (InteractiveAttachment(text="some text", callback_id="abc123", actions=actions).to_dict(),) class BlockAttachmentTests(unittest.TestCase): diff --git a/tests/slack_sdk/models/test_blocks.py b/tests/slack_sdk/models/test_blocks.py index a7513aecb..e0a523cfd 100644 --- a/tests/slack_sdk/models/test_blocks.py +++ b/tests/slack_sdk/models/test_blocks.py @@ -1481,9 +1481,7 @@ def test_with_column_settings_objects(self): def test_with_rich_text_cell_objects(self): """Test table using typed RichTextBlock objects""" - cell = RichTextBlock( - elements=[RichTextSectionElement(elements=[RichTextElementParts.Text(text="Hello")])] - ) + cell = RichTextBlock(elements=[RichTextSectionElement(elements=[RichTextElementParts.Text(text="Hello")])]) block = TableBlock( rows=[ [RawTextObject(text="Header"), cell], diff --git a/tests/web/classes/test_attachments.py b/tests/web/classes/test_attachments.py index ede2900fe..e705a682c 100644 --- a/tests/web/classes/test_attachments.py +++ b/tests/web/classes/test_attachments.py @@ -193,7 +193,7 @@ def test_actions_length(self): actions = [ActionButton(name="button_1", text="Click me", value="button_value_1")] * 6 with self.assertRaises(SlackObjectFormationError): - InteractiveAttachment(text="some text", callback_id="abc123", actions=actions).to_dict(), + (InteractiveAttachment(text="some text", callback_id="abc123", actions=actions).to_dict(),) class BlockAttachmentTests(unittest.TestCase): diff --git a/tests/web/test_web_client.py b/tests/web/test_web_client.py index 71c8b6287..c0bcaf35a 100644 --- a/tests/web/test_web_client.py +++ b/tests/web/test_web_client.py @@ -271,7 +271,7 @@ async def test_html_response_body_issue_718_async(self): self.fail("SlackApiError expected here") except err.SlackApiError as e: self.assertEqual( - "The request to the Slack API failed.\n" "The server responded with: {}", + "The request to the Slack API failed.\nThe server responded with: {}", str(e), ) diff --git a/tests/web/test_web_client_issue_829.py b/tests/web/test_web_client_issue_829.py index d728b8404..5f6e6c732 100644 --- a/tests/web/test_web_client_issue_829.py +++ b/tests/web/test_web_client_issue_829.py @@ -42,6 +42,6 @@ async def test_html_response_body_issue_829_async(self): self.fail("SlackApiError expected here") except err.SlackApiError as e: self.assertEqual( - "The request to the Slack API failed.\n" "The server responded with: {}", + "The request to the Slack API failed.\nThe server responded with: {}", str(e), )