From 07e8ac9d98c535ade20040883a04734b4c9d04b8 Mon Sep 17 00:00:00 2001 From: William Bergamin Date: Thu, 27 Aug 2026 14:02:49 -0400 Subject: [PATCH 1/4] 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). No behavior changes; verified to still compile on Python 3.7. Co-Authored-By: Claude --- slack_bolt/adapter/django/handler.py | 3 +- slack_bolt/authorization/async_authorize.py | 2 +- slack_bolt/authorization/authorize.py | 2 +- .../thread_context_store/file/__init__.py | 1 - slack_bolt/logger/messages.py | 58 ++++++----- slack_bolt/middleware/assistant/assistant.py | 4 +- .../async_attaching_conversation_kwargs.py | 1 - .../attaching_conversation_kwargs.py | 1 - .../request_verification.py | 2 +- slack_bolt/oauth/internals.py | 2 +- tests/mock_web_api_server/__init__.py | 12 +-- .../test_app_actor_user_token.py | 61 ++++++------ .../test_app_installation_store.py | 45 +++++---- tests/scenario_tests/test_function.py | 3 +- .../test_app_actor_user_token.py | 61 ++++++------ tests/scenario_tests_async/test_function.py | 2 +- .../logger/test_unmatched_suggestions.py | 4 +- .../slack_bolt/request/test_payload_utils.py | 54 +++++----- .../context/test_async_complete.py | 1 - .../context/test_async_respond.py | 1 - .../context/test_async_say.py | 1 - .../context/test_async_set_status.py | 1 - .../test_async_set_suggested_prompts.py | 1 - .../logger/test_unmatched_suggestions.py | 98 +++++++++++++------ .../test_single_team_authorization.py | 1 - .../oauth/test_async_oauth_flow.py | 1 - .../oauth/test_async_oauth_flow_sqlite3.py | 1 - 27 files changed, 230 insertions(+), 194 deletions(-) diff --git a/slack_bolt/adapter/django/handler.py b/slack_bolt/adapter/django/handler.py index 4ede5fde3..8f5b0d372 100644 --- a/slack_bolt/adapter/django/handler.py +++ b/slack_bolt/adapter/django/handler.py @@ -66,8 +66,7 @@ def release_thread_local_connections(logger: Logger, execution_timing: str): if logger.level <= logging.DEBUG: current: Thread = current_thread() logger.debug( - "Released thread-bound old DB connections " - f"(thread name: {current.name}, execution timing: {execution_timing})" + f"Released thread-bound old DB connections (thread name: {current.name}, execution timing: {execution_timing})" ) diff --git a/slack_bolt/authorization/async_authorize.py b/slack_bolt/authorization/async_authorize.py index f3303e429..7fa04a304 100644 --- a/slack_bolt/authorization/async_authorize.py +++ b/slack_bolt/authorization/async_authorize.py @@ -356,7 +356,7 @@ async def __call__( # ------------------------------------------------ def _debug_log_for_not_found(self, enterprise_id: Optional[str], team_id: Optional[str]): - self.logger.debug("No installation data found " f"for enterprise_id: {enterprise_id} team_id: {team_id}") + self.logger.debug(f"No installation data found for enterprise_id: {enterprise_id} team_id: {team_id}") async def _rotate_and_save_tokens_if_necessary(self, installation: Optional[Installation]) -> Optional[Installation]: if installation is None or (installation.user_refresh_token is None and installation.bot_refresh_token is None): diff --git a/slack_bolt/authorization/authorize.py b/slack_bolt/authorization/authorize.py index afed6fa8b..e0f62fed4 100644 --- a/slack_bolt/authorization/authorize.py +++ b/slack_bolt/authorization/authorize.py @@ -353,7 +353,7 @@ def __call__( # ------------------------------------------------ def _debug_log_for_not_found(self, enterprise_id: Optional[str], team_id: Optional[str]): - self.logger.debug("No installation data found " f"for enterprise_id: {enterprise_id} team_id: {team_id}") + self.logger.debug(f"No installation data found for enterprise_id: {enterprise_id} team_id: {team_id}") def _rotate_and_save_tokens_if_necessary(self, installation: Optional[Installation]) -> Optional[Installation]: if installation is None or (installation.user_refresh_token is None and installation.bot_refresh_token is None): diff --git a/slack_bolt/context/assistant/thread_context_store/file/__init__.py b/slack_bolt/context/assistant/thread_context_store/file/__init__.py index a29f3b2c0..3590e6709 100644 --- a/slack_bolt/context/assistant/thread_context_store/file/__init__.py +++ b/slack_bolt/context/assistant/thread_context_store/file/__init__.py @@ -6,7 +6,6 @@ class FileAssistantThreadContextStore(AssistantThreadContextStore): - def __init__( self, base_dir: str = str(Path.home()) + "/.bolt-app-assistant-thread-contexts", diff --git a/slack_bolt/logger/messages.py b/slack_bolt/logger/messages.py index 80e68d022..8c7439683 100644 --- a/slack_bolt/logger/messages.py +++ b/slack_bolt/logger/messages.py @@ -45,7 +45,7 @@ def error_auth_test_failure(error_response: SlackResponse) -> str: def error_token_required() -> str: - return "Either an env variable `SLACK_BOT_TOKEN` " "or `token` argument in the constructor is required." + return "Either an env variable `SLACK_BOT_TOKEN` or `token` argument in the constructor is required." def error_unexpected_listener_middleware(middleware_type) -> str: @@ -89,9 +89,7 @@ def warning_client_prioritized_and_token_skipped() -> str: def warning_token_skipped() -> str: - return ( - "As `installation_store` or `authorize` has been used, " "`token` (or SLACK_BOT_TOKEN env variable) will be ignored." - ) + return "As `installation_store` or `authorize` has been used, `token` (or SLACK_BOT_TOKEN env variable) will be ignored." def warning_installation_store_conflicts() -> str: @@ -99,7 +97,8 @@ def warning_installation_store_conflicts() -> str: def warning_unhandled_by_global_middleware( - name: str, req: Union[BoltRequest, "AsyncBoltRequest"] # type: ignore[name-defined] + name: str, + req: Union[BoltRequest, "AsyncBoltRequest"], # type: ignore[name-defined] ) -> str: return ( f"A global middleware ({name}) skipped calling either `next()` or `next_()` " @@ -194,8 +193,8 @@ def warning_unhandled_request( return _build_unhandled_request_suggestion( default_message, f""" -from slack_bolt.workflows.step{'.async_step' if is_async else ''} import {'Async' if is_async else ''}WorkflowStep -ws = {'Async' if is_async else ''}WorkflowStep( +from slack_bolt.workflows.step{".async_step" if is_async else ""} import {"Async" if is_async else ""}WorkflowStep +ws = {"Async" if is_async else ""}WorkflowStep( callback_id="{callback_id}", edit=edit, save=save, @@ -214,8 +213,8 @@ def warning_unhandled_request( default_message, f""" @app.action("{action_id_or_callback_id}") -{'async ' if is_async else ''}def handle_some_action(ack, body, logger): - {'await ' if is_async else ''}ack() +{"async " if is_async else ""}def handle_some_action(ack, body, logger): + {"await " if is_async else ""}ack() logger.info(body) """, ) @@ -225,13 +224,13 @@ def warning_unhandled_request( if req.body.get("action_id") is not None: constraints = '"' + req.body["action_id"] + '"' elif req.body.get("type") == "dialog_suggestion": - constraints = f"""{{"type": "dialog_suggestion", "callback_id": "{req.body.get('callback_id')}"}}""" + constraints = f"""{{"type": "dialog_suggestion", "callback_id": "{req.body.get("callback_id")}"}}""" return _build_unhandled_request_suggestion( default_message, f""" @app.options({constraints}) -{'async ' if is_async else ''}def handle_some_options(ack): - {'await ' if is_async else ''}ack(options=[ ... ]) +{"async " if is_async else ""}def handle_some_options(ack): + {"await " if is_async else ""}ack(options=[ ... ]) """, ) if is_shortcut(req.body): @@ -241,8 +240,8 @@ def warning_unhandled_request( default_message, f""" @app.shortcut("{id}") -{'async ' if is_async else ''}def handle_shortcuts(ack, body, logger): - {'await ' if is_async else ''}ack() +{"async " if is_async else ""}def handle_shortcuts(ack, body, logger): + {"await " if is_async else ""}ack() logger.info(body) """, ) @@ -251,9 +250,9 @@ def warning_unhandled_request( return _build_unhandled_request_suggestion( default_message, f""" -@app.view("{req.body.get('view', {}).get('callback_id', 'modal-view-id')}") -{'async ' if is_async else ''}def handle_view_submission_events(ack, body, logger): - {'await ' if is_async else ''}ack() +@app.view("{req.body.get("view", {}).get("callback_id", "modal-view-id")}") +{"async " if is_async else ""}def handle_view_submission_events(ack, body, logger): + {"await " if is_async else ""}ack() logger.info(body) """, ) @@ -262,9 +261,9 @@ def warning_unhandled_request( return _build_unhandled_request_suggestion( default_message, f""" -@app.view_closed("{req.body.get('view', {}).get('callback_id', 'modal-view-id')}") -{'async ' if is_async else ''}def handle_view_closed_events(ack, body, logger): - {'await ' if is_async else ''}ack() +@app.view_closed("{req.body.get("view", {}).get("callback_id", "modal-view-id")}") +{"async " if is_async else ""}def handle_view_closed_events(ack, body, logger): + {"await " if is_async else ""}ack() logger.info(body) """, ) @@ -279,23 +278,23 @@ def warning_unhandled_request( default_message, f""" @app.function("{callback_id}") -{'async ' if is_async else ''}def handle_some_function(ack, body, complete, fail, logger): - {'await ' if is_async else ''}ack() +{"async " if is_async else ""}def handle_some_function(ack, body, complete, fail, logger): + {"await " if is_async else ""}ack() logger.info(body) try: # TODO: do something here outputs = {{}} - {'await ' if is_async else ''}complete(outputs=outputs) + {"await " if is_async else ""}complete(outputs=outputs) except Exception as e: error = f"Failed to handle a function request (error: {{e}})" - {'await ' if is_async else ''}fail(error=error) + {"await " if is_async else ""}fail(error=error) """, ) return _build_unhandled_request_suggestion( default_message, f""" @app.event("{event_type}") -{'async ' if is_async else ''}def handle_{event_type}_events(body, logger): +{"async " if is_async else ""}def handle_{event_type}_events(body, logger): logger.info(body) """, ) @@ -306,8 +305,8 @@ def warning_unhandled_request( default_message, f""" @app.command("{command}") -{'async ' if is_async else ''}def handle_some_command(ack, body, logger): - {'await ' if is_async else ''}ack() +{"async " if is_async else ""}def handle_some_command(ack, body, logger): + {"await " if is_async else ""}ack() logger.info(body) """, ) @@ -320,8 +319,7 @@ def warning_did_not_call_ack(listener_name: str) -> str: def warning_bot_only_conflicts() -> str: return ( - "installation_store_bot_only exists in both App and OAuthFlow.settings. " - "The one passed in App constructor is used." + "installation_store_bot_only exists in both App and OAuthFlow.settings. The one passed in App constructor is used." ) @@ -334,7 +332,7 @@ def warning_skip_uncommon_arg_name(arg_name: str) -> str: def warning_ack_timeout_has_no_effect(identifier: Union[str, Pattern], ack_timeout: int) -> str: handler_example = f'@app.function("{identifier}")' if isinstance(identifier, str) else f"@app.function({identifier})" - return f"On {handler_example}, as `auto_acknowledge` is `True`, " f"`ack_timeout={ack_timeout}` you gave will be unused" + return f"On {handler_example}, as `auto_acknowledge` is `True`, `ack_timeout={ack_timeout}` you gave will be unused" # ------------------------------- diff --git a/slack_bolt/middleware/assistant/assistant.py b/slack_bolt/middleware/assistant/assistant.py index ad842f94d..98347d012 100644 --- a/slack_bolt/middleware/assistant/assistant.py +++ b/slack_bolt/middleware/assistant/assistant.py @@ -213,9 +213,7 @@ def _merge_matchers( primary_matcher: Callable[..., bool], custom_matchers: Optional[Union[Callable[..., bool], ListenerMatcher]], ): - return [CustomListenerMatcher(app_name=self.app_name, func=primary_matcher)] + ( - custom_matchers or [] - ) # type: ignore[operator] + return [CustomListenerMatcher(app_name=self.app_name, func=primary_matcher)] + (custom_matchers or []) # type: ignore[operator] @staticmethod def default_thread_context_changed(save_thread_context: SaveThreadContext, payload: dict): diff --git a/slack_bolt/middleware/attaching_conversation_kwargs/async_attaching_conversation_kwargs.py b/slack_bolt/middleware/attaching_conversation_kwargs/async_attaching_conversation_kwargs.py index ab69f5768..d9069e922 100644 --- a/slack_bolt/middleware/attaching_conversation_kwargs/async_attaching_conversation_kwargs.py +++ b/slack_bolt/middleware/attaching_conversation_kwargs/async_attaching_conversation_kwargs.py @@ -19,7 +19,6 @@ class AsyncAttachingConversationKwargs(AsyncMiddleware): - thread_context_store: Optional[AsyncAssistantThreadContextStore] def __init__(self, thread_context_store: Optional[AsyncAssistantThreadContextStore] = None): diff --git a/slack_bolt/middleware/attaching_conversation_kwargs/attaching_conversation_kwargs.py b/slack_bolt/middleware/attaching_conversation_kwargs/attaching_conversation_kwargs.py index 2d6ce7b01..9ff1c0bdd 100644 --- a/slack_bolt/middleware/attaching_conversation_kwargs/attaching_conversation_kwargs.py +++ b/slack_bolt/middleware/attaching_conversation_kwargs/attaching_conversation_kwargs.py @@ -19,7 +19,6 @@ class AttachingConversationKwargs(Middleware): - thread_context_store: Optional[AssistantThreadContextStore] def __init__(self, thread_context_store: Optional[AssistantThreadContextStore] = None): diff --git a/slack_bolt/middleware/request_verification/request_verification.py b/slack_bolt/middleware/request_verification/request_verification.py index af505bc84..82d1b72e1 100644 --- a/slack_bolt/middleware/request_verification/request_verification.py +++ b/slack_bolt/middleware/request_verification/request_verification.py @@ -65,5 +65,5 @@ def _build_error_response() -> BoltResponse: def _debug_log_error(self, signature, timestamp, body) -> None: self.logger.info( - "Invalid request signature detected " f"(signature: {signature}, timestamp: {timestamp}, body: {body})" + f"Invalid request signature detected (signature: {signature}, timestamp: {timestamp}, body: {body})" ) diff --git a/slack_bolt/oauth/internals.py b/slack_bolt/oauth/internals.py index 05959817a..31da94207 100644 --- a/slack_bolt/oauth/internals.py +++ b/slack_bolt/oauth/internals.py @@ -55,7 +55,7 @@ def _build_callback_failure_response( status: int = 500, error: Optional[Exception] = None, ) -> BoltResponse: - debug_message = "Handling an OAuth callback failure " f"(reason: {reason}, error: {error}, request: {request.query})" + debug_message = f"Handling an OAuth callback failure (reason: {reason}, error: {error}, request: {request.query})" self._logger.debug(debug_message) # Adding a bit more details to the error code to help installers understand what's happening. diff --git a/tests/mock_web_api_server/__init__.py b/tests/mock_web_api_server/__init__.py index e164d4f4a..adf4c19ea 100644 --- a/tests/mock_web_api_server/__init__.py +++ b/tests/mock_web_api_server/__init__.py @@ -27,9 +27,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 @@ -68,9 +68,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/scenario_tests/test_app_actor_user_token.py b/tests/scenario_tests/test_app_actor_user_token.py index 024c29e59..3ee5ebf25 100644 --- a/tests/scenario_tests/test_app_actor_user_token.py +++ b/tests/scenario_tests/test_app_actor_user_token.py @@ -111,35 +111,38 @@ def build_headers(self, timestamp: str, body: str): } def build_request(self, team_id: str = "T014GJXU940"): - timestamp, body = str(int(time())), json.dumps( - { - "team_id": team_id, - "enterprise_id": "E013Y3SHLAY", - "context_team_id": team_id, - "context_enterprise_id": "E013Y3SHLAY", - "api_app_id": "A04TEM7H4S0", - "event": { - "type": "message", - "files": [], - "upload": False, - "user": "W013QGS7BPF", - "display_as_bot": False, - "team": team_id, - "channel": "C04T3ACM40K", - "subtype": "file_share", - }, - "type": "event_callback", - "authorizations": [ - { - "enterprise_id": None, - "team_id": "T0G9PQBBK", - "user_id": "W23456789", - "is_bot": True, - "is_enterprise_install": False, - } - ], - "is_ext_shared_channel": True, - } + timestamp, body = ( + str(int(time())), + json.dumps( + { + "team_id": team_id, + "enterprise_id": "E013Y3SHLAY", + "context_team_id": team_id, + "context_enterprise_id": "E013Y3SHLAY", + "api_app_id": "A04TEM7H4S0", + "event": { + "type": "message", + "files": [], + "upload": False, + "user": "W013QGS7BPF", + "display_as_bot": False, + "team": team_id, + "channel": "C04T3ACM40K", + "subtype": "file_share", + }, + "type": "event_callback", + "authorizations": [ + { + "enterprise_id": None, + "team_id": "T0G9PQBBK", + "user_id": "W23456789", + "is_bot": True, + "is_enterprise_install": False, + } + ], + "is_ext_shared_channel": True, + } + ), ) return BoltRequest(body=body, headers=self.build_headers(timestamp, body)) diff --git a/tests/scenario_tests/test_app_installation_store.py b/tests/scenario_tests/test_app_installation_store.py index 7434ee3e4..277938547 100644 --- a/tests/scenario_tests/test_app_installation_store.py +++ b/tests/scenario_tests/test_app_installation_store.py @@ -101,27 +101,30 @@ def build_headers(self, timestamp: str, body: str): } def build_app_mention_request(self): - timestamp, body = str(int(time())), json.dumps( - { - "token": "verification_token", - "team_id": "T111", - "enterprise_id": "E111", - "api_app_id": "A111", - "event": { - "client_msg_id": "9cbd4c5b-7ddf-4ede-b479-ad21fca66d63", - "type": "app_mention", - "text": "<@W111> Hi there!", - "user": "W222", - "ts": "1595926230.009600", - "team": "T111", - "channel": "C111", - "event_ts": "1595926230.009600", - }, - "type": "event_callback", - "event_id": "Ev111", - "event_time": 1595926230, - "authed_users": ["W111"], - } + timestamp, body = ( + str(int(time())), + json.dumps( + { + "token": "verification_token", + "team_id": "T111", + "enterprise_id": "E111", + "api_app_id": "A111", + "event": { + "client_msg_id": "9cbd4c5b-7ddf-4ede-b479-ad21fca66d63", + "type": "app_mention", + "text": "<@W111> Hi there!", + "user": "W222", + "ts": "1595926230.009600", + "team": "T111", + "channel": "C111", + "event_ts": "1595926230.009600", + }, + "type": "event_callback", + "event_id": "Ev111", + "event_time": 1595926230, + "authed_users": ["W111"], + } + ), ) return BoltRequest(body=body, headers=self.build_headers(timestamp, body)) diff --git a/tests/scenario_tests/test_function.py b/tests/scenario_tests/test_function.py index 1e5e1c423..539e0fccc 100644 --- a/tests/scenario_tests/test_function.py +++ b/tests/scenario_tests/test_function.py @@ -189,8 +189,7 @@ def fake_sleep(duration): assert response.status == 404 assert_auth_test_count(self, 1) assert elapsed_seconds == timeout + 1, ( - f"Expected handler to time out after {timeout + 1} time.sleep calls, " - f"but it was called {elapsed_seconds} times" + f"Expected handler to time out after {timeout + 1} time.sleep calls, but it was called {elapsed_seconds} times" ) def test_warning_when_timeout_improperly_set(self, caplog): diff --git a/tests/scenario_tests_async/test_app_actor_user_token.py b/tests/scenario_tests_async/test_app_actor_user_token.py index 0028096be..eb4e2e7ad 100644 --- a/tests/scenario_tests_async/test_app_actor_user_token.py +++ b/tests/scenario_tests_async/test_app_actor_user_token.py @@ -60,35 +60,38 @@ def build_headers(self, timestamp: str, body: str): } def build_request(self, team_id: str = "T014GJXU940") -> AsyncBoltRequest: - timestamp, body = str(int(time())), json.dumps( - { - "team_id": team_id, - "enterprise_id": "E013Y3SHLAY", - "context_team_id": team_id, - "context_enterprise_id": "E013Y3SHLAY", - "api_app_id": "A04TEM7H4S0", - "event": { - "type": "message", - "files": [], - "upload": False, - "user": "W013QGS7BPF", - "display_as_bot": False, - "team": team_id, - "channel": "C04T3ACM40K", - "subtype": "file_share", - }, - "type": "event_callback", - "authorizations": [ - { - "enterprise_id": None, - "team_id": "T0G9PQBBK", - "user_id": "W23456789", - "is_bot": True, - "is_enterprise_install": False, - } - ], - "is_ext_shared_channel": True, - } + timestamp, body = ( + str(int(time())), + json.dumps( + { + "team_id": team_id, + "enterprise_id": "E013Y3SHLAY", + "context_team_id": team_id, + "context_enterprise_id": "E013Y3SHLAY", + "api_app_id": "A04TEM7H4S0", + "event": { + "type": "message", + "files": [], + "upload": False, + "user": "W013QGS7BPF", + "display_as_bot": False, + "team": team_id, + "channel": "C04T3ACM40K", + "subtype": "file_share", + }, + "type": "event_callback", + "authorizations": [ + { + "enterprise_id": None, + "team_id": "T0G9PQBBK", + "user_id": "W23456789", + "is_bot": True, + "is_enterprise_install": False, + } + ], + "is_ext_shared_channel": True, + } + ), ) return AsyncBoltRequest(body=body, headers=self.build_headers(timestamp, body)) diff --git a/tests/scenario_tests_async/test_function.py b/tests/scenario_tests_async/test_function.py index ce9080e36..0cbcf67c7 100644 --- a/tests/scenario_tests_async/test_function.py +++ b/tests/scenario_tests_async/test_function.py @@ -193,7 +193,7 @@ async def fake_sleep(duration): assert response.status == 404 await assert_auth_test_count_async(self, 1) assert elapsed_seconds == timeout + 1, ( - f"Expected handler to time out after {timeout + 1} sleep calls, " f"but it was called {elapsed_seconds} times" + f"Expected handler to time out after {timeout + 1} sleep calls, but it was called {elapsed_seconds} times" ) @pytest.mark.asyncio diff --git a/tests/slack_bolt/logger/test_unmatched_suggestions.py b/tests/slack_bolt/logger/test_unmatched_suggestions.py index b470fa061..426f8fd72 100644 --- a/tests/slack_bolt/logger/test_unmatched_suggestions.py +++ b/tests/slack_bolt/logger/test_unmatched_suggestions.py @@ -707,7 +707,9 @@ def test_step(self): ], "private_metadata": "This is for you!", "callback_id": "view-id", - "state": {"values": {"hspI": {"maBWU": {"type": "plain_text_input", "value": "test"}}}}, + "state": { + "values": {"hspI": {"maBWU": {"type": "plain_text_input", "value": "test"}}} + }, "hash": "1596530361.3wRYuk3R", "title": { "type": "plain_text", diff --git a/tests/slack_bolt/request/test_payload_utils.py b/tests/slack_bolt/request/test_payload_utils.py index 576cb390d..d58c2c436 100644 --- a/tests/slack_bolt/request/test_payload_utils.py +++ b/tests/slack_bolt/request/test_payload_utils.py @@ -261,13 +261,13 @@ def test_is_user_message_event_in_assistant_thread(self): "block_actions": block_actions_body, } for key, body in positives.items(): - assert is_user_message_event_in_assistant_thread( - body - ), f"{key} should pass {is_user_message_event_in_assistant_thread.__name__}" + assert is_user_message_event_in_assistant_thread(body), ( + f"{key} should pass {is_user_message_event_in_assistant_thread.__name__}" + ) for key, body in negatives.items(): - assert not is_user_message_event_in_assistant_thread( - body - ), f"{key} should NOT pass {is_user_message_event_in_assistant_thread.__name__}" + assert not is_user_message_event_in_assistant_thread(body), ( + f"{key} should NOT pass {is_user_message_event_in_assistant_thread.__name__}" + ) def test_is_bot_message_event_in_assistant_thread(self): positives = { @@ -287,13 +287,13 @@ def test_is_bot_message_event_in_assistant_thread(self): "block_actions": block_actions_body, } for key, body in positives.items(): - assert is_bot_message_event_in_assistant_thread( - body - ), f"{key} should pass {is_bot_message_event_in_assistant_thread.__name__}" + assert is_bot_message_event_in_assistant_thread(body), ( + f"{key} should pass {is_bot_message_event_in_assistant_thread.__name__}" + ) for key, body in negatives.items(): - assert not is_bot_message_event_in_assistant_thread( - body - ), f"{key} should NOT pass {is_bot_message_event_in_assistant_thread.__name__}" + assert not is_bot_message_event_in_assistant_thread(body), ( + f"{key} should NOT pass {is_bot_message_event_in_assistant_thread.__name__}" + ) def test_is_bot_message_user_message_asymmetry(self): assert is_user_message_event_in_assistant_thread(file_share_im_message_body) @@ -318,13 +318,13 @@ def test_is_other_message_sub_event_in_assistant_thread(self): "block_actions": block_actions_body, } for key, body in positives.items(): - assert is_other_message_sub_event_in_assistant_thread( - body - ), f"{key} should pass {is_other_message_sub_event_in_assistant_thread.__name__}" + assert is_other_message_sub_event_in_assistant_thread(body), ( + f"{key} should pass {is_other_message_sub_event_in_assistant_thread.__name__}" + ) for key, body in negatives.items(): - assert not is_other_message_sub_event_in_assistant_thread( - body - ), f"{key} should NOT pass {is_other_message_sub_event_in_assistant_thread.__name__}" + assert not is_other_message_sub_event_in_assistant_thread(body), ( + f"{key} should NOT pass {is_other_message_sub_event_in_assistant_thread.__name__}" + ) def test_is_assistant_event(self): positives = { @@ -364,9 +364,9 @@ def test_is_assistant_thread_started_event(self): "block_actions": block_actions_body, } for key, body in negatives.items(): - assert not is_assistant_thread_started_event( - body - ), f"{key} should NOT pass {is_assistant_thread_started_event.__name__}" + assert not is_assistant_thread_started_event(body), ( + f"{key} should NOT pass {is_assistant_thread_started_event.__name__}" + ) def test_is_assistant_thread_context_changed_event(self): assert is_assistant_thread_context_changed_event(thread_context_changed_event_body) @@ -381,9 +381,9 @@ def test_is_assistant_thread_context_changed_event(self): "block_actions": block_actions_body, } for key, body in negatives.items(): - assert not is_assistant_thread_context_changed_event( - body - ), f"{key} should NOT pass {is_assistant_thread_context_changed_event.__name__}" + assert not is_assistant_thread_context_changed_event(body), ( + f"{key} should NOT pass {is_assistant_thread_context_changed_event.__name__}" + ) def test_is_app_home_opened_event(self): assert is_app_home_opened_event(app_home_opened_messages_body) @@ -403,6 +403,6 @@ def test_is_app_home_opened_event(self): } for key, body in negatives.items(): assert not is_app_home_opened_event(body), f"{key} should NOT pass {is_app_home_opened_event.__name__}" - assert not is_app_home_opened_event( - body, tab="messages" - ), f"{key} should NOT pass {is_app_home_opened_event.__name__} with tab='messages'" + assert not is_app_home_opened_event(body, tab="messages"), ( + f"{key} should NOT pass {is_app_home_opened_event.__name__} with tab='messages'" + ) diff --git a/tests/slack_bolt_async/context/test_async_complete.py b/tests/slack_bolt_async/context/test_async_complete.py index 4277d4218..36fa6c5a5 100644 --- a/tests/slack_bolt_async/context/test_async_complete.py +++ b/tests/slack_bolt_async/context/test_async_complete.py @@ -11,7 +11,6 @@ class TestAsyncComplete: - @pytest.fixture(scope="function", autouse=True) def setup_teardown(self): old_os_env = remove_os_env_temporarily() diff --git a/tests/slack_bolt_async/context/test_async_respond.py b/tests/slack_bolt_async/context/test_async_respond.py index b47ef1056..92d03a7f7 100644 --- a/tests/slack_bolt_async/context/test_async_respond.py +++ b/tests/slack_bolt_async/context/test_async_respond.py @@ -9,7 +9,6 @@ class TestAsyncRespond: - @pytest.fixture(scope="function", autouse=True) def setup_teardown(self): old_os_env = remove_os_env_temporarily() diff --git a/tests/slack_bolt_async/context/test_async_say.py b/tests/slack_bolt_async/context/test_async_say.py index d8d63ae8a..94ae0b159 100644 --- a/tests/slack_bolt_async/context/test_async_say.py +++ b/tests/slack_bolt_async/context/test_async_say.py @@ -8,7 +8,6 @@ class TestAsyncSay: - @pytest.fixture(scope="function", autouse=True) def setup_teardown(self): old_os_env = remove_os_env_temporarily() diff --git a/tests/slack_bolt_async/context/test_async_set_status.py b/tests/slack_bolt_async/context/test_async_set_status.py index bcf1fcf19..95e009004 100644 --- a/tests/slack_bolt_async/context/test_async_set_status.py +++ b/tests/slack_bolt_async/context/test_async_set_status.py @@ -8,7 +8,6 @@ class TestAsyncSetStatus: - @pytest.fixture(scope="function", autouse=True) def setup_teardown(self): old_os_env = remove_os_env_temporarily() diff --git a/tests/slack_bolt_async/context/test_async_set_suggested_prompts.py b/tests/slack_bolt_async/context/test_async_set_suggested_prompts.py index 7a92ff2a3..a881d7abd 100644 --- a/tests/slack_bolt_async/context/test_async_set_suggested_prompts.py +++ b/tests/slack_bolt_async/context/test_async_set_suggested_prompts.py @@ -11,7 +11,6 @@ class TestAsyncSetSuggestedPrompts: - @pytest.fixture(scope="function", autouse=True) def setup_teardown(self): old_os_env = remove_os_env_temporarily() diff --git a/tests/slack_bolt_async/logger/test_unmatched_suggestions.py b/tests/slack_bolt_async/logger/test_unmatched_suggestions.py index d8c659892..93343c4a2 100644 --- a/tests/slack_bolt_async/logger/test_unmatched_suggestions.py +++ b/tests/slack_bolt_async/logger/test_unmatched_suggestions.py @@ -22,7 +22,8 @@ def test_block_actions(self): "block_id": "b", "action_id": "action-id-value", } - assert f"""Unhandled request ({filtered_body}) + assert ( + f"""Unhandled request ({filtered_body}) --- [Suggestion] You can handle this type of event with the following listener function: @@ -30,7 +31,9 @@ def test_block_actions(self): async def handle_some_action(ack, body, logger): await ack() logger.info(body) -""" == message +""" + == message + ) def test_attachment_actions(self): req: AsyncBoltRequest = AsyncBoltRequest(body=attachment_actions, mode="socket_mode") @@ -46,7 +49,8 @@ def test_attachment_actions(self): } ], } - assert f"""Unhandled request ({filtered_body}) + assert ( + f"""Unhandled request ({filtered_body}) --- [Suggestion] You can handle this type of event with the following listener function: @@ -54,7 +58,9 @@ def test_attachment_actions(self): async def handle_some_action(ack, body, logger): await ack() logger.info(body) -""" == message +""" + == message + ) def test_app_mention_event(self): req: AsyncBoltRequest = AsyncBoltRequest(body=app_mention_event, mode="socket_mode") @@ -63,14 +69,17 @@ def test_app_mention_event(self): "event": {"type": "app_mention"}, } message = warning_unhandled_request(req) - assert f"""Unhandled request ({filtered_body}) + assert ( + f"""Unhandled request ({filtered_body}) --- [Suggestion] You can handle this type of event with the following listener function: @app.event("app_mention") async def handle_app_mention_events(body, logger): logger.info(body) -""" == message +""" + == message + ) def test_function_event(self): req: AsyncBoltRequest = AsyncBoltRequest(body=function_event, mode="socket_mode") @@ -79,7 +88,8 @@ def test_function_event(self): "event": {"type": "function_executed"}, } message = warning_unhandled_request(req) - assert f"""Unhandled request ({filtered_body}) + assert ( + f"""Unhandled request ({filtered_body}) --- [Suggestion] You can handle this type of event with the following listener function: @@ -94,7 +104,9 @@ async def handle_some_function(ack, body, complete, fail, logger): except Exception as e: error = f"Failed to handle a function request (error: {{e}})" await fail(error=error) -""" == message +""" + == message + ) def test_commands(self): req: AsyncBoltRequest = AsyncBoltRequest(body=slash_command, mode="socket_mode") @@ -103,7 +115,8 @@ def test_commands(self): "type": None, "command": "/start-conv", } - assert f"""Unhandled request ({filtered_body}) + assert ( + f"""Unhandled request ({filtered_body}) --- [Suggestion] You can handle this type of event with the following listener function: @@ -111,7 +124,9 @@ def test_commands(self): async def handle_some_command(ack, body, logger): await ack() logger.info(body) -""" == message +""" + == message + ) def test_shortcut(self): req: AsyncBoltRequest = AsyncBoltRequest(body=global_shortcut, mode="socket_mode") @@ -120,7 +135,8 @@ def test_shortcut(self): "type": "shortcut", "callback_id": "test-shortcut", } - assert f"""Unhandled request ({filtered_body}) + assert ( + f"""Unhandled request ({filtered_body}) --- [Suggestion] You can handle this type of event with the following listener function: @@ -128,7 +144,9 @@ def test_shortcut(self): async def handle_shortcuts(ack, body, logger): await ack() logger.info(body) -""" == message +""" + == message + ) req: AsyncBoltRequest = AsyncBoltRequest(body=message_shortcut, mode="socket_mode") message = warning_unhandled_request(req) @@ -136,7 +154,8 @@ async def handle_shortcuts(ack, body, logger): "type": "message_action", "callback_id": "test-shortcut", } - assert f"""Unhandled request ({filtered_body}) + assert ( + f"""Unhandled request ({filtered_body}) --- [Suggestion] You can handle this type of event with the following listener function: @@ -144,7 +163,9 @@ async def handle_shortcuts(ack, body, logger): async def handle_shortcuts(ack, body, logger): await ack() logger.info(body) -""" == message +""" + == message + ) def test_view(self): req: AsyncBoltRequest = AsyncBoltRequest(body=view_submission, mode="socket_mode") @@ -153,7 +174,8 @@ def test_view(self): "type": "view_submission", "view": {"type": "modal", "callback_id": "view-id"}, } - assert f"""Unhandled request ({filtered_body}) + assert ( + f"""Unhandled request ({filtered_body}) --- [Suggestion] You can handle this type of event with the following listener function: @@ -161,7 +183,9 @@ def test_view(self): async def handle_view_submission_events(ack, body, logger): await ack() logger.info(body) -""" == message +""" + == message + ) req: AsyncBoltRequest = AsyncBoltRequest(body=view_closed, mode="socket_mode") message = warning_unhandled_request(req) @@ -169,7 +193,8 @@ async def handle_view_submission_events(ack, body, logger): "type": "view_closed", "view": {"type": "modal", "callback_id": "view-id"}, } - assert f"""Unhandled request ({filtered_body}) + assert ( + f"""Unhandled request ({filtered_body}) --- [Suggestion] You can handle this type of event with the following listener function: @@ -177,7 +202,9 @@ async def handle_view_submission_events(ack, body, logger): async def handle_view_closed_events(ack, body, logger): await ack() logger.info(body) -""" == message +""" + == message + ) def test_block_suggestion(self): req: AsyncBoltRequest = AsyncBoltRequest(body=block_suggestion, mode="socket_mode") @@ -189,14 +216,17 @@ def test_block_suggestion(self): "action_id": "the-id", "value": "search word", } - assert f"""Unhandled request ({filtered_body}) + assert ( + f"""Unhandled request ({filtered_body}) --- [Suggestion] You can handle this type of event with the following listener function: @app.options("the-id") async def handle_some_options(ack): await ack(options=[ ... ]) -""" == message +""" + == message + ) def test_dialog_suggestion(self): req: AsyncBoltRequest = AsyncBoltRequest(body=dialog_suggestion, mode="socket_mode") @@ -206,14 +236,17 @@ def test_dialog_suggestion(self): "callback_id": "the-id", "value": "search keyword", } - assert f"""Unhandled request ({filtered_body}) + assert ( + f"""Unhandled request ({filtered_body}) --- [Suggestion] You can handle this type of event with the following listener function: @app.options({{"type": "dialog_suggestion", "callback_id": "the-id"}}) async def handle_some_options(ack): await ack(options=[ ... ]) -""" == message +""" + == message + ) def test_step(self): req: AsyncBoltRequest = AsyncBoltRequest(body=step_edit_payload, mode="socket_mode") @@ -222,7 +255,8 @@ def test_step(self): "type": "workflow_step_edit", "callback_id": "copy_review", } - assert f"""Unhandled request ({filtered_body}) + assert ( + f"""Unhandled request ({filtered_body}) --- [Suggestion] You can handle this type of event with the following listener function: @@ -235,14 +269,17 @@ def test_step(self): ) # Pass Step to set up listeners app.step(ws) -""" == message +""" + == message + ) req: AsyncBoltRequest = AsyncBoltRequest(body=step_save_payload, mode="socket_mode") message = warning_unhandled_request(req) filtered_body = { "type": "view_submission", "view": {"type": "workflow_step", "callback_id": "copy_review"}, } - assert f"""Unhandled request ({filtered_body}) + assert ( + f"""Unhandled request ({filtered_body}) --- [Suggestion] You can handle this type of event with the following listener function: @@ -255,14 +292,17 @@ def test_step(self): ) # Pass Step to set up listeners app.step(ws) -""" == message +""" + == message + ) req: AsyncBoltRequest = AsyncBoltRequest(body=step_execute_payload, mode="socket_mode") message = warning_unhandled_request(req) filtered_body = { "type": "event_callback", "event": {"type": "workflow_step_execute"}, } - assert f"""Unhandled request ({filtered_body}) + assert ( + f"""Unhandled request ({filtered_body}) --- [Suggestion] You can handle this type of event with the following listener function: @@ -275,7 +315,9 @@ def test_step(self): ) # Pass Step to set up listeners app.step(ws) -""" == message +""" + == message + ) block_actions = { diff --git a/tests/slack_bolt_async/middleware/authorization/test_single_team_authorization.py b/tests/slack_bolt_async/middleware/authorization/test_single_team_authorization.py index 0ddb6281d..ab30130d0 100644 --- a/tests/slack_bolt_async/middleware/authorization/test_single_team_authorization.py +++ b/tests/slack_bolt_async/middleware/authorization/test_single_team_authorization.py @@ -19,7 +19,6 @@ async def next(): class TestSingleTeamAuthorization: - @pytest.fixture(scope="function", autouse=True) def setup_teardown(self): old_os_env = remove_os_env_temporarily() diff --git a/tests/slack_bolt_async/oauth/test_async_oauth_flow.py b/tests/slack_bolt_async/oauth/test_async_oauth_flow.py index 5714e1a6a..538861c05 100644 --- a/tests/slack_bolt_async/oauth/test_async_oauth_flow.py +++ b/tests/slack_bolt_async/oauth/test_async_oauth_flow.py @@ -30,7 +30,6 @@ class TestAsyncOAuthFlow: - @pytest.fixture(scope="function", autouse=True) def setup_teardown(self): old_os_env = remove_os_env_temporarily() diff --git a/tests/slack_bolt_async/oauth/test_async_oauth_flow_sqlite3.py b/tests/slack_bolt_async/oauth/test_async_oauth_flow_sqlite3.py index 00300929f..f8da60928 100644 --- a/tests/slack_bolt_async/oauth/test_async_oauth_flow_sqlite3.py +++ b/tests/slack_bolt_async/oauth/test_async_oauth_flow_sqlite3.py @@ -16,7 +16,6 @@ class TestAsyncOAuthFlowSQLite3: - @pytest.fixture(scope="function", autouse=True) def setup_teardown(self): setup_mock_web_api_server_async(self) From 29dbaed3ea0a24987ebcfaa9678fd80f3699489a Mon Sep 17 00:00:00 2001 From: William Bergamin Date: Thu, 27 Aug 2026 14:03:07 -0400 Subject: [PATCH 2/4] 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"] plus the ignore set carried over from .flake8 (F841, F821, E402); drop [tool.black]. - requirements/dev_tools.txt: replace flake8 and black with ruff. - delete .flake8 (settings now live in pyproject.toml). - scripts/format.sh: ruff check --fix + ruff format. - scripts/lint.sh: ruff check. - rename the file-level `# flake8: noqa` directives to `# ruff: noqa`. - freeze three middleware/handler dispatch calls with `# fmt: skip` so ruff format cannot detach their `# type: ignore` comments (which would break mypy under warn_unused_ignores). - record the reformat commit in .git-blame-ignore-revs. Co-Authored-By: Claude --- .flake8 | 3 --- .git-blame-ignore-revs | 3 +++ AGENTS.md | 8 ++++---- examples/assistants/async_interaction_app.py | 2 +- pyproject.toml | 6 +++++- requirements/dev_tools.txt | 8 +++----- scripts/format.sh | 3 ++- scripts/lint.sh | 2 +- slack_bolt/adapter/asgi/base_handler.py | 2 +- slack_bolt/app/__init__.py | 2 +- slack_bolt/app/app.py | 2 +- slack_bolt/app/async_app.py | 4 ++-- 12 files changed, 24 insertions(+), 21 deletions(-) delete mode 100644 .flake8 diff --git a/.flake8 b/.flake8 deleted file mode 100644 index 9960c210e..000000000 --- a/.flake8 +++ /dev/null @@ -1,3 +0,0 @@ -[flake8] -max-line-length = 125 -ignore = F841,F821,W503,E402 diff --git a/.git-blame-ignore-revs b/.git-blame-ignore-revs index 9e2a40167..08e355c7f 100644 --- a/.git-blame-ignore-revs +++ b/.git-blame-ignore-revs @@ -1,2 +1,5 @@ # change black settings 0e4cd56b69e8f83166cd262f762802b7f18c3d21 + +# apply ruff format across the codebase +07e8ac9d98c535ade20040883a04734b4c9d04b8 diff --git a/AGENTS.md b/AGENTS.md index eae86f330..cc6ba8198 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -16,7 +16,7 @@ Slack Bolt for Python -- a framework for building Slack apps in Python. ## Environment Setup -You can verify the venv is active by checking `echo $VIRTUAL_ENV`. If tools like `black`, `flake8`, `mypy` or `pytest` are not found, ask the user to activate the venv. +You can verify the venv is active by checking `echo $VIRTUAL_ENV`. If tools like `ruff`, `mypy` or `pytest` are not found, ask the user to activate the venv. A python virtual environment (`venv`) should be activated before running any commands. @@ -65,10 +65,10 @@ Always use the project scripts instead of calling `pytest` directly: ### Formatting, Linting, Type Checking ```bash -# Format -- Black, configured in pyproject.toml +# Format -- Ruff formatter (+ lint autofix), configured in pyproject.toml ./scripts/format.sh --no-install -# Lint -- Flake8, configured in .flake8 +# Lint -- Ruff linter, configured in pyproject.toml ./scripts/lint.sh --no-install # Type check -- mypy, configured in pyproject.toml @@ -210,7 +210,7 @@ The core package has a **single required runtime dependency**: `slack_sdk` (defi - `test_async.txt` -- test runner deps (`pytest`, `pytest-asyncio`, includes `async_dev.txt`) - `test.txt` -- test deps without async (`pytest`, `pytest-cov`) - `test_adapter.txt` -- adapter-specific test deps (`moto`, `boddle`, `sanic-testing`) -- `dev_tools.txt` -- dev tools (`mypy`, `flake8`, `black`) +- `dev_tools.txt` -- dev tools (`mypy`, `ruff`) When adding a new dependency: add it to the appropriate `requirements/*.txt` file with version constraints, never to `pyproject.toml` `dependencies` (unless it's a core runtime dep, which is very rare). diff --git a/examples/assistants/async_interaction_app.py b/examples/assistants/async_interaction_app.py index b9e8de3bc..d2cb0e449 100644 --- a/examples/assistants/async_interaction_app.py +++ b/examples/assistants/async_interaction_app.py @@ -1,4 +1,4 @@ -# flake8: noqa F811 +# ruff: noqa: F811 import asyncio import logging import os diff --git a/pyproject.toml b/pyproject.toml index ac197c4f6..c7094dd4b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -38,9 +38,13 @@ readme = { file = ["README.md"], content-type = "text/markdown" } [tool.distutils.bdist_wheel] universal = true -[tool.black] +[tool.ruff] line-length = 125 +[tool.ruff.lint] +select = ["E", "W", "F"] +ignore = ["F841", "F821", "E402"] + [tool.pytest.ini_options] testpaths = ["tests"] log_file = "logs/pytest.log" diff --git a/requirements/dev_tools.txt b/requirements/dev_tools.txt index 59e4cdd21..97813433e 100644 --- a/requirements/dev_tools.txt +++ b/requirements/dev_tools.txt @@ -3,8 +3,6 @@ # mypy mypy==2.3.0 -# flake8 -flake8==7.3.0 - -# black -black==26.3.1 +# ruff +# Note: replaces flake8 (lint) and black (format) +ruff==0.16.4 diff --git a/scripts/format.sh b/scripts/format.sh index 771cbb413..c25146d2f 100755 --- a/scripts/format.sh +++ b/scripts/format.sh @@ -10,4 +10,5 @@ if [[ "$1" != "--no-install" ]]; then pip install -U -r requirements/dev_tools.txt fi -black slack_bolt/ tests/ +ruff check --fix slack_bolt/ examples/ +ruff format slack_bolt/ tests/ diff --git a/scripts/lint.sh b/scripts/lint.sh index 3a3037419..f7f2b605b 100755 --- a/scripts/lint.sh +++ b/scripts/lint.sh @@ -9,4 +9,4 @@ if [[ "$1" != "--no-install" ]]; then pip install -U -r requirements/dev_tools.txt fi -flake8 slack_bolt/ && flake8 examples/ +ruff check slack_bolt/ examples/ diff --git a/slack_bolt/adapter/asgi/base_handler.py b/slack_bolt/adapter/asgi/base_handler.py index adfa060c1..3acce78da 100644 --- a/slack_bolt/adapter/asgi/base_handler.py +++ b/slack_bolt/adapter/asgi/base_handler.py @@ -59,7 +59,7 @@ async def __call__(self, scope: scope_type, receive: Callable, send: Callable) - if scope["type"] == "http": response: AsgiHttpResponse = await self._get_http_response( method=scope["method"], path=scope["path"], request=AsgiHttpRequest(scope, receive) # type: ignore[arg-type] - ) + ) # fmt: skip await send(response.get_response_start()) await send(response.get_response_body()) return diff --git a/slack_bolt/app/__init__.py b/slack_bolt/app/__init__.py index 455f2b949..d5d4f7f8a 100644 --- a/slack_bolt/app/__init__.py +++ b/slack_bolt/app/__init__.py @@ -1,4 +1,4 @@ -# flake8: noqa +# ruff: noqa """Application interface in Bolt. For most use cases, we recommend using `slack_bolt.app.app`. diff --git a/slack_bolt/app/app.py b/slack_bolt/app/app.py index e20649902..0fa3008bb 100644 --- a/slack_bolt/app/app.py +++ b/slack_bolt/app/app.py @@ -589,7 +589,7 @@ def middleware_next(): # run all the middleware attached to this listener first middleware_resp, next_was_not_called = listener.run_middleware( req=req, resp=resp # type: ignore[arg-type] - ) + ) # fmt: skip if next_was_not_called: if middleware_resp is not None: if self._framework_logger.level <= logging.DEBUG: diff --git a/slack_bolt/app/async_app.py b/slack_bolt/app/async_app.py index cc94f9e15..262fd9a3a 100644 --- a/slack_bolt/app/async_app.py +++ b/slack_bolt/app/async_app.py @@ -588,7 +588,7 @@ async def async_middleware_next(): self._framework_logger.debug(f"Applying {middleware.name}") resp = await middleware.async_process( req=req, resp=resp, next=async_middleware_next # type: ignore[arg-type] - ) + ) # fmt: skip if not middleware_state["next_called"]: if resp is None: # next() method was not called without providing the response to return to Slack @@ -619,7 +619,7 @@ async def async_middleware_next(): # run all the middleware attached to this listener first middleware_resp, next_was_not_called = await listener.run_async_middleware( req=req, resp=resp # type: ignore[arg-type] - ) + ) # fmt: skip if next_was_not_called: if middleware_resp is not None: if self._framework_logger.level <= logging.DEBUG: From 74f6eca288c1eddf2388ac2f05c0911273ead82e Mon Sep 17 00:00:00 2001 From: William Bergamin Date: Thu, 27 Aug 2026 14:09:32 -0400 Subject: [PATCH 3/4] Update .gitignore --- .gitignore | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.gitignore b/.gitignore index 2549060e7..37a5fdd9a 100644 --- a/.gitignore +++ b/.gitignore @@ -35,6 +35,9 @@ pip # JetBrains PyCharm settings .idea/ +# VS Code settings +.vscode/ + tmp.txt .DS_Store logs/ From 6fae899d5ea07366d27d6f07f0e5cdcc7bc3e488 Mon Sep 17 00:00:00 2001 From: William Bergamin Date: Thu, 27 Aug 2026 14:46:04 -0400 Subject: [PATCH 4/4] Update dev_tools.txt --- requirements/dev_tools.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/requirements/dev_tools.txt b/requirements/dev_tools.txt index 97813433e..023bd9f62 100644 --- a/requirements/dev_tools.txt +++ b/requirements/dev_tools.txt @@ -4,5 +4,4 @@ mypy==2.3.0 # ruff -# Note: replaces flake8 (lint) and black (format) ruff==0.16.4