This it an inconsistent bug found in 2 tests TestEventsSharedChannels.test_uninstallation_and_revokes
and TestEventsSocketMode.test_middleware
I believe it sometimes happen in the CI pipeline, but I encountered it locally
The goal of this issue is to add stability to the unit tests
Reproducible in:
slack-sdk==3.19.5
Python 3.9.6
ProductName: macOS
ProductVersion: 12.6.1
BuildVersion: 21G217
Darwin Kernel Version 21.6.0
Steps to reproduce:
Hard to encounter locally
- run the tests
- a lot
Expected result:
All tests pass
Actual result:
=================================================================== FAILURES ===================================================================
___________________________________________ TestEventsSharedChannels.test_uninstallation_and_revokes ___________________________________________
self = <tests.scenario_tests.test_events_shared_channels.TestEventsSharedChannels object at 0x116f32bb0>
def test_uninstallation_and_revokes(self):
app = App(
client=self.web_client,
signing_secret=self.signing_secret,
authorize=authorize,
)
app._client = WebClient(token="uninstalled-revoked", base_url=self.mock_api_server_base_url)
@app.event("app_uninstalled")
def handler1(say: Say):
say(channel="C111", text="What's up?")
@app.event("tokens_revoked")
def handler2(say: Say):
say(channel="C111", text="What's up?")
app_uninstalled_body = {
"token": "verification_token",
"team_id": "T_INSTALLED",
"enterprise_id": "E_INSTALLED",
"api_app_id": "A111",
"event": {"type": "app_uninstalled"},
"type": "event_callback",
"event_id": "Ev111",
"event_time": 1599616881,
"authorizations": [
{
"enterprise_id": "E_INSTALLED",
"team_id": "T_INSTALLED",
"user_id": "W111",
"is_bot": True,
"is_enterprise_install": False,
}
],
}
timestamp, body = str(int(time())), json.dumps(app_uninstalled_body)
request: BoltRequest = BoltRequest(body=body, headers=self.build_headers(timestamp, body))
response = app.dispatch(request)
assert response.status == 200
tokens_revoked_body = {
"token": "verification_token",
"team_id": "T_INSTALLED",
"enterprise_id": "E_INSTALLED",
"api_app_id": "A111",
"event": {
"type": "tokens_revoked",
"tokens": {"oauth": ["UXXXXXXXX"], "bot": ["UXXXXXXXX"]},
},
"type": "event_callback",
"event_id": "Ev111",
"event_time": 1599616881,
"authorizations": [
{
"enterprise_id": "E_INSTALLED",
"team_id": "T_INSTALLED",
"user_id": "W111",
"is_bot": True,
"is_enterprise_install": False,
}
],
}
timestamp, body = str(int(time())), json.dumps(tokens_revoked_body)
request: BoltRequest = BoltRequest(body=body, headers=self.build_headers(timestamp, body))
response = app.dispatch(request)
assert response.status == 200
# this should not be called when we have authorize
assert self.mock_received_requests.get("/auth.test") is None
sleep(1) # wait a bit after auto ack()
> assert self.mock_received_requests["/chat.postMessage"] == 2
E assert 3 == 2
tests/scenario_tests/test_events_shared_channels.py:494: AssertionError
------------------------------------------------------------- Captured stderr call -------------------------------------------------------------
127.0.0.1 - - [07/Dec/2022 14:49:01] "POST /chat.postMessage HTTP/1.1" 200 -
----------------------------------------
Exception occurred during processing of request from ('127.0.0.1', 58680)
Traceback (most recent call last):
File "/.pyenv/versions/3.9.6/lib/python3.9/socketserver.py", line 316, in _handle_request_noblock
self.process_request(request, client_address)
File "/.pyenv/versions/3.9.6/lib/python3.9/socketserver.py", line 347, in process_request
self.finish_request(request, client_address)
File "/.pyenv/versions/3.9.6/lib/python3.9/socketserver.py", line 360, in finish_request
self.RequestHandlerClass(request, client_address, self)
File "/.pyenv/versions/3.9.6/lib/python3.9/http/server.py", line 653, in __init__
super().__init__(*args, **kwargs)
File "/.pyenv/versions/3.9.6/lib/python3.9/socketserver.py", line 747, in __init__
self.handle()
File "/.pyenv/versions/3.9.6/lib/python3.9/http/server.py", line 427, in handle
self.handle_one_request()
File "/.pyenv/versions/3.9.6/lib/python3.9/http/server.py", line 416, in handle_one_request
self.wfile.flush() #actually send the response if not already done.
ValueError: I/O operation on closed file.
----------------------------------------
127.0.0.1 - - [07/Dec/2022 14:49:01] "POST /chat.postMessage HTTP/1.1" 200 -
----------------------------------------
Exception occurred during processing of request from ('127.0.0.1', 58682)
Traceback (most recent call last):
File "/.pyenv/versions/3.9.6/lib/python3.9/socketserver.py", line 316, in _handle_request_noblock
self.process_request(request, client_address)
File "/.pyenv/versions/3.9.6/lib/python3.9/socketserver.py", line 347, in process_request
self.finish_request(request, client_address)
File "/.pyenv/versions/3.9.6/lib/python3.9/socketserver.py", line 360, in finish_request
self.RequestHandlerClass(request, client_address, self)
File "/.pyenv/versions/3.9.6/lib/python3.9/http/server.py", line 653, in __init__
super().__init__(*args, **kwargs)
File "/.pyenv/versions/3.9.6/lib/python3.9/socketserver.py", line 747, in __init__
self.handle()
File "/.pyenv/versions/3.9.6/lib/python3.9/http/server.py", line 427, in handle
self.handle_one_request()
File "/.pyenv/versions/3.9.6/lib/python3.9/http/server.py", line 416, in handle_one_request
self.wfile.flush() #actually send the response if not already done.
ValueError: I/O operation on closed file.
----------------------------------------
[Errno 61] Connection refused - goodbye
127.0.0.1 - - [07/Dec/2022 14:49:02] "POST /chat.postMessage HTTP/1.1" 200 -
----------------------------------------
Exception occurred during processing of request from ('127.0.0.1', 58687)
Traceback (most recent call last):
File "/.pyenv/versions/3.9.6/lib/python3.9/socketserver.py", line 316, in _handle_request_noblock
self.process_request(request, client_address)
File "/.pyenv/versions/3.9.6/lib/python3.9/socketserver.py", line 347, in process_request
self.finish_request(request, client_address)
File "/.pyenv/versions/3.9.6/lib/python3.9/socketserver.py", line 360, in finish_request
self.RequestHandlerClass(request, client_address, self)
File "/.pyenv/versions/3.9.6/lib/python3.9/http/server.py", line 653, in __init__
super().__init__(*args, **kwargs)
File "/.pyenv/versions/3.9.6/lib/python3.9/socketserver.py", line 747, in __init__
self.handle()
File "/.pyenv/versions/3.9.6/lib/python3.9/http/server.py", line 427, in handle
self.handle_one_request()
File "/.pyenv/versions/3.9.6/lib/python3.9/http/server.py", line 416, in handle_one_request
self.wfile.flush() #actually send the response if not already done.
ValueError: I/O operation on closed file.
----------------------------------------
[Errno 61] Connection refused - goodbye
-------------------------------------------------------------- Captured log call ---------------------------------------------------------------
2022-12-07 14:49:01 DEBUG Applying slack_bolt.middleware.ssl_check.ssl_check.SslCheck
2022-12-07 14:49:01 DEBUG Applying slack_bolt.middleware.request_verification.request_verification.RequestVerification
2022-12-07 14:49:01 DEBUG Applying slack_bolt.middleware.authorization.multi_teams_authorization.MultiTeamsAuthorization
2022-12-07 14:49:01 DEBUG Applying slack_bolt.middleware.ignoring_self_events.ignoring_self_events.IgnoringSelfEvents
2022-12-07 14:49:01 DEBUG Applying slack_bolt.middleware.url_verification.url_verification.UrlVerification
2022-12-07 14:49:01 DEBUG Checking listener: handler1 ...
2022-12-07 14:49:01 DEBUG Running listener: handler1 ...
2022-12-07 14:49:01 DEBUG Sending a request - url: http://localhost:8888/chat.postMessage, query_params: {}, body_params: {}, files: {}, json_body: {'channel': 'C111', 'text': "What's up?", 'team_id': 'T_INSTALLED'}, headers: {'Content-Type': 'application/json;charset=utf-8', 'User-Agent': 'Python/3.9.6 slackclient/3.19.5 Darwin/21.6.0'}
2022-12-07 14:49:01 DEBUG Responding with status: 200 body: "" (0 millis)
2022-12-07 14:49:01 DEBUG Applying slack_bolt.middleware.ssl_check.ssl_check.SslCheck
2022-12-07 14:49:01 DEBUG Applying slack_bolt.middleware.request_verification.request_verification.RequestVerification
2022-12-07 14:49:01 DEBUG Applying slack_bolt.middleware.authorization.multi_teams_authorization.MultiTeamsAuthorization
2022-12-07 14:49:01 DEBUG Applying slack_bolt.middleware.ignoring_self_events.ignoring_self_events.IgnoringSelfEvents
2022-12-07 14:49:01 DEBUG Applying slack_bolt.middleware.url_verification.url_verification.UrlVerification
2022-12-07 14:49:01 DEBUG Checking listener: handler1 ...
2022-12-07 14:49:01 DEBUG Checking listener: handler2 ...
2022-12-07 14:49:01 DEBUG Running listener: handler2 ...
2022-12-07 14:49:01 DEBUG Sending a request - url: http://localhost:8888/chat.postMessage, query_params: {}, body_params: {}, files: {}, json_body: {'channel': 'C111', 'text': "What's up?", 'team_id': 'T_INSTALLED'}, headers: {'Content-Type': 'application/json;charset=utf-8', 'User-Agent': 'Python/3.9.6 slackclient/3.19.5 Darwin/21.6.0'}
2022-12-07 14:49:01 DEBUG Responding with status: 200 body: "" (0 millis)
2022-12-07 14:49:01 ERROR Failed to send a request to Slack API server: [Errno 54] Connection reset by peer
2022-12-07 14:49:01 INFO A retry handler found: ConnectionErrorRetryHandler for POST http://localhost:8888/chat.postMessage - [Errno 54] Connection reset by peer
2022-12-07 14:49:01 ERROR Failed to send a request to Slack API server: [Errno 54] Connection reset by peer
2022-12-07 14:49:01 INFO A retry handler found: ConnectionErrorRetryHandler for POST http://localhost:8888/chat.postMessage - [Errno 54] Connection reset by peer
2022-12-07 14:49:01 INFO Starting to receive messages from a new connection
2022-12-07 14:49:01 ERROR [Errno 61] Connection refused - goodbye
2022-12-07 14:49:01 ERROR on_error invoked (error: ConnectionRefusedError, message: [Errno 61] Connection refused)
2022-12-07 14:49:01 DEBUG on_close invoked: (code: None, message: None)
2022-12-07 14:49:01 INFO Stopped receiving messages from a connection
2022-12-07 14:49:02 INFO Going to retry the same request: POST http://localhost:8888/chat.postMessage
2022-12-07 14:49:02 DEBUG Received the following response - status: 200, headers: {'Server': 'SimpleHTTP/0.6 Python/3.9.6', 'Date': 'Wed, 07 Dec 2022 19:49:02 GMT', 'content-type': 'application/json;charset=utf-8', 'connection': 'close'}, body: {"ok": false, "error": "invalid_auth"}
2022-12-07 14:49:02 ERROR Failed to run listener function (error: The request to the Slack API failed. (url: http://localhost:8888/chat.postMessage)
The server responded with: {'ok': False, 'error': 'invalid_auth'})
Traceback (most recent call last):
File "/Documents/slack/tools/forks/bolt-python/slack_bolt/listener/thread_runner.py", line 120, in run_ack_function_asynchronously
listener.run_ack_function(request=request, response=response)
File "/Documents/slack/tools/forks/bolt-python/slack_bolt/listener/custom_listener.py", line 50, in run_ack_function
return self.ack_function(
File "/Documents/slack/tools/forks/bolt-python/tests/scenario_tests/test_events_shared_channels.py", line 432, in handler1
say(channel="C111", text="What's up?")
File "/Documents/slack/tools/forks/bolt-python/slack_bolt/context/say/say.py", line 49, in __call__
return self.client.chat_postMessage(
File "/Documents/slack/tools/forks/bolt-python/env_3.11.0/lib/python3.9/site-packages/slack_sdk/web/client.py", line 2072, in chat_postMessage
return self.api_call("chat.postMessage", json=kwargs)
File "/Documents/slack/tools/forks/bolt-python/env_3.11.0/lib/python3.9/site-packages/slack_sdk/web/base_client.py", line 156, in api_call
return self._sync_send(api_url=api_url, req_args=req_args)
File "/Documents/slack/tools/forks/bolt-python/env_3.11.0/lib/python3.9/site-packages/slack_sdk/web/base_client.py", line 187, in _sync_send
return self._urllib_api_call(
File "/Documents/slack/tools/forks/bolt-python/env_3.11.0/lib/python3.9/site-packages/slack_sdk/web/base_client.py", line 309, in _urllib_api_call
return SlackResponse(
File "/Documents/slack/tools/forks/bolt-python/env_3.11.0/lib/python3.9/site-packages/slack_sdk/web/slack_response.py", line 199, in validate
raise e.SlackApiError(message=msg, response=self)
slack_sdk.errors.SlackApiError: The request to the Slack API failed. (url: http://localhost:8888/chat.postMessage)
The server responded with: {'ok': False, 'error': 'invalid_auth'}
2022-12-07 14:49:02 INFO Starting to receive messages from a new connection
2022-12-07 14:49:02 ERROR [Errno 61] Connection refused - goodbye
2022-12-07 14:49:02 ERROR on_error invoked (error: ConnectionRefusedError, message: [Errno 61] Connection refused)
2022-12-07 14:49:02 DEBUG on_close invoked: (code: None, message: None)
2022-12-07 14:49:02 INFO Stopped receiving messages from a connection
_____________________________________________________ TestEventsSocketMode.test_middleware _____________________________________________________
self = <tests.scenario_tests.test_events_socket_mode.TestEventsSocketMode object at 0x116c51af0>
def test_middleware(self):
app = App(client=self.web_client)
@app.event("app_mention")
def handle_app_mention(body, say, payload, event):
assert body == self.valid_event_body
assert body["event"] == payload
assert payload == event
say("What's up?")
request: BoltRequest = BoltRequest(body=self.valid_event_body, mode="socket_mode")
response = app.dispatch(request)
assert response.status == 200
assert_auth_test_count(self, 1)
sleep(1) # wait a bit after auto ack()
> assert self.mock_received_requests["/chat.postMessage"] == 1
E assert 2 == 1
tests/scenario_tests/test_events_socket_mode.py:76: AssertionError
------------------------------------------------------------- Captured stderr call -------------------------------------------------------------
127.0.0.1 - - [07/Dec/2022 14:49:02] "POST /auth.test HTTP/1.1" 200 -
[Errno 61] Connection refused - goodbye
127.0.0.1 - - [07/Dec/2022 14:49:02] "POST /chat.postMessage HTTP/1.1" 200 -
----------------------------------------
Exception occurred during processing of request from ('127.0.0.1', 58695)
Traceback (most recent call last):
File "/.pyenv/versions/3.9.6/lib/python3.9/socketserver.py", line 316, in _handle_request_noblock
self.process_request(request, client_address)
File "/.pyenv/versions/3.9.6/lib/python3.9/socketserver.py", line 347, in process_request
self.finish_request(request, client_address)
File "/.pyenv/versions/3.9.6/lib/python3.9/socketserver.py", line 360, in finish_request
self.RequestHandlerClass(request, client_address, self)
File "/.pyenv/versions/3.9.6/lib/python3.9/http/server.py", line 653, in __init__
super().__init__(*args, **kwargs)
File "/.pyenv/versions/3.9.6/lib/python3.9/socketserver.py", line 747, in __init__
self.handle()
File "/.pyenv/versions/3.9.6/lib/python3.9/http/server.py", line 427, in handle
self.handle_one_request()
File "/.pyenv/versions/3.9.6/lib/python3.9/http/server.py", line 416, in handle_one_request
self.wfile.flush() #actually send the response if not already done.
ValueError: I/O operation on closed file.
----------------------------------------
127.0.0.1 - - [07/Dec/2022 14:49:02] "POST /chat.postMessage HTTP/1.1" 200 -
----------------------------------------
Exception occurred during processing of request from ('127.0.0.1', 58699)
Traceback (most recent call last):
File "/.pyenv/versions/3.9.6/lib/python3.9/socketserver.py", line 316, in _handle_request_noblock
self.process_request(request, client_address)
File "/.pyenv/versions/3.9.6/lib/python3.9/socketserver.py", line 347, in process_request
self.finish_request(request, client_address)
File "/.pyenv/versions/3.9.6/lib/python3.9/socketserver.py", line 360, in finish_request
self.RequestHandlerClass(request, client_address, self)
File "/.pyenv/versions/3.9.6/lib/python3.9/http/server.py", line 653, in __init__
super().__init__(*args, **kwargs)
File "/.pyenv/versions/3.9.6/lib/python3.9/socketserver.py", line 747, in __init__
self.handle()
File "/.pyenv/versions/3.9.6/lib/python3.9/http/server.py", line 427, in handle
self.handle_one_request()
File "/.pyenv/versions/3.9.6/lib/python3.9/http/server.py", line 416, in handle_one_request
self.wfile.flush() #actually send the response if not already done.
ValueError: I/O operation on closed file.
----------------------------------------
[Errno 61] Connection refused - goodbye
[Errno 61] Connection refused - goodbye
-------------------------------------------------------------- Captured log call ---------------------------------------------------------------
2022-12-07 14:49:02 DEBUG Sending a request - url: http://localhost:8888/auth.test, query_params: {}, body_params: {}, files: {}, json_body: None, headers: {'Content-Type': 'application/x-www-form-urlencoded', 'Authorization': '(redacted)', 'User-Agent': 'Python/3.9.6 slackclient/3.19.5 Darwin/21.6.0'}
2022-12-07 14:49:02 DEBUG Received the following response - status: 200, headers: {'Server': 'SimpleHTTP/0.6 Python/3.9.6', 'Date': 'Wed, 07 Dec 2022 19:49:02 GMT', 'content-type': 'application/json;charset=utf-8', 'connection': 'close'}, body:
{
"ok": true,
"url": "https://subarachnoid.slack.com/",
"team": "Subarachnoid Workspace",
"user": "bot",
"team_id": "T0G9PQBBK",
"user_id": "W23456789",
"bot_id": "BZYBOTHED"
}
2022-12-07 14:49:02 DEBUG Applying slack_bolt.middleware.ssl_check.ssl_check.SslCheck
2022-12-07 14:49:02 DEBUG Applying slack_bolt.middleware.request_verification.request_verification.RequestVerification
2022-12-07 14:49:02 DEBUG Applying slack_bolt.middleware.authorization.single_team_authorization.SingleTeamAuthorization
2022-12-07 14:49:02 DEBUG Applying slack_bolt.middleware.ignoring_self_events.ignoring_self_events.IgnoringSelfEvents
2022-12-07 14:49:02 DEBUG Applying slack_bolt.middleware.url_verification.url_verification.UrlVerification
2022-12-07 14:49:02 DEBUG Checking listener: handle_app_mention ...
2022-12-07 14:49:02 DEBUG Running listener: handle_app_mention ...
2022-12-07 14:49:02 DEBUG Sending a request - url: http://localhost:8888/chat.postMessage, query_params: {}, body_params: {}, files: {}, json_body: {'channel': 'C111', 'text': "What's up?", 'team_id': 'T111'}, headers: {'Content-Type': 'application/json;charset=utf-8', 'Authorization': '(redacted)', 'User-Agent': 'Python/3.9.6 slackclient/3.19.5 Darwin/21.6.0'}
2022-12-07 14:49:02 DEBUG Responding with status: 200 body: "" (0 millis)
2022-12-07 14:49:02 INFO Starting to receive messages from a new connection
2022-12-07 14:49:02 INFO request: /chat.postMessage {'channel': 'C111', 'text': "What's up?", 'team_id': 'T111'}
2022-12-07 14:49:02 ERROR [Errno 61] Connection refused - goodbye
2022-12-07 14:49:02 ERROR on_error invoked (error: ConnectionRefusedError, message: [Errno 61] Connection refused)
2022-12-07 14:49:02 DEBUG on_close invoked: (code: None, message: None)
2022-12-07 14:49:02 INFO Stopped receiving messages from a connection
2022-12-07 14:49:02 DEBUG Received the following response - status: 200, headers: {'Server': 'SimpleHTTP/0.6 Python/3.9.6', 'Date': 'Wed, 07 Dec 2022 19:49:02 GMT', 'content-type': 'application/json;charset=utf-8', 'connection': 'close'}, body: {"ok": true}
2022-12-07 14:49:02 INFO Going to retry the same request: POST http://localhost:8888/chat.postMessage
2022-12-07 14:49:02 DEBUG Received the following response - status: 200, headers: {'Server': 'SimpleHTTP/0.6 Python/3.9.6', 'Date': 'Wed, 07 Dec 2022 19:49:02 GMT', 'content-type': 'application/json;charset=utf-8', 'connection': 'close'}, body: {"ok": false, "error": "invalid_auth"}
2022-12-07 14:49:02 ERROR Failed to run listener function (error: The request to the Slack API failed. (url: http://localhost:8888/chat.postMessage)
The server responded with: {'ok': False, 'error': 'invalid_auth'})
Traceback (most recent call last):
File "/Documents/slack/tools/forks/bolt-python/slack_bolt/listener/thread_runner.py", line 120, in run_ack_function_asynchronously
listener.run_ack_function(request=request, response=response)
File "/Documents/slack/tools/forks/bolt-python/slack_bolt/listener/custom_listener.py", line 50, in run_ack_function
return self.ack_function(
File "/Documents/slack/tools/forks/bolt-python/tests/scenario_tests/test_events_shared_channels.py", line 436, in handler2
say(channel="C111", text="What's up?")
File "/Documents/slack/tools/forks/bolt-python/slack_bolt/context/say/say.py", line 49, in __call__
return self.client.chat_postMessage(
File "/Documents/slack/tools/forks/bolt-python/env_3.11.0/lib/python3.9/site-packages/slack_sdk/web/client.py", line 2072, in chat_postMessage
return self.api_call("chat.postMessage", json=kwargs)
File "/Documents/slack/tools/forks/bolt-python/env_3.11.0/lib/python3.9/site-packages/slack_sdk/web/base_client.py", line 156, in api_call
return self._sync_send(api_url=api_url, req_args=req_args)
File "/Documents/slack/tools/forks/bolt-python/env_3.11.0/lib/python3.9/site-packages/slack_sdk/web/base_client.py", line 187, in _sync_send
return self._urllib_api_call(
File "/Documents/slack/tools/forks/bolt-python/env_3.11.0/lib/python3.9/site-packages/slack_sdk/web/base_client.py", line 309, in _urllib_api_call
return SlackResponse(
File "/Documents/slack/tools/forks/bolt-python/env_3.11.0/lib/python3.9/site-packages/slack_sdk/web/slack_response.py", line 199, in validate
raise e.SlackApiError(message=msg, response=self)
slack_sdk.errors.SlackApiError: The request to the Slack API failed. (url: http://localhost:8888/chat.postMessage)
The server responded with: {'ok': False, 'error': 'invalid_auth'}
2022-12-07 14:49:03 INFO Starting to receive messages from a new connection
2022-12-07 14:49:03 ERROR [Errno 61] Connection refused - goodbye
2022-12-07 14:49:03 ERROR on_error invoked (error: ConnectionRefusedError, message: [Errno 61] Connection refused)
2022-12-07 14:49:03 DEBUG on_close invoked: (code: None, message: None)
2022-12-07 14:49:03 INFO Stopped receiving messages from a connection
2022-12-07 14:49:03 INFO Starting to receive messages from a new connection
2022-12-07 14:49:03 ERROR [Errno 61] Connection refused - goodbye
2022-12-07 14:49:03 ERROR on_error invoked (error: ConnectionRefusedError, message: [Errno 61] Connection refused)
2022-12-07 14:49:03 DEBUG on_close invoked: (code: None, message: None)
2022-12-07 14:49:03 INFO Stopped receiving messages from a connection
=========================================================== short test summary info ============================================================
FAILED tests/scenario_tests/test_events_shared_channels.py::TestEventsSharedChannels::test_uninstallation_and_revokes - assert 3 == 2
FAILED tests/scenario_tests/test_events_socket_mode.py::TestEventsSocketMode::test_middleware - assert 2 == 1
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! KeyboardInterrupt !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
Requirements
Please read the Contributing guidelines and Code of Conduct before creating this issue or pull request. By submitting, you are agreeing to those rules.
bug