Repository: hikari-py/hikari
Pull request #1434 (2022-12-31 08:21:14)

Properly close unclosed file descriptor when reading banner
### Checklist
<!-- Make sure to tick all the following boxes by putting an `x` in between (like this `[x]`) -->
- [x] I have run `nox` and all the pipelines have passed.
- [x] I have made unittests according to the code I have added/modified/deleted.



Patch:
diff --git a/changes/1434.bugfix.md b/changes/1434.bugfix.md
new file mode 100644
index 00000000..5dc7bcb6
--- /dev/null
+++ b/changes/1434.bugfix.md
@@ -0,0 +1,2 @@
+Properly close unclosed file descriptor when reading banner.
+- This only affects versions of Python >= 3.9.
diff --git a/changes/1435.bugfix.md b/changes/1435.bugfix.md
new file mode 100644
index 00000000..82c45ca6
--- /dev/null
+++ b/changes/1435.bugfix.md
@@ -0,0 +1,1 @@
+Start GC of bucket manager when creating a rest client.
diff --git a/hikari/impl/rest.py b/hikari/impl/rest.py
index d296e892..e6ca8364 100644
--- a/hikari/impl/rest.py
+++ b/hikari/impl/rest.py
@@ -449,8 +449,10 @@ def build(
             trust_env=proxy_settings.trust_env,
         )
         _LOGGER.log(ux.TRACE, "acquired new aiohttp client session")
+        buckets = buckets_impl.RESTBucketManager(max_rate_limit)
+        buckets.start()
         return _LiveAttributes(
-            buckets=buckets_impl.RESTBucketManager(max_rate_limit),
+            buckets=buckets,
             client_session=client_session,
             closed_event=asyncio.Event(),
             global_rate_limit=rate_limits.ManualRateLimiter(),
diff --git a/hikari/internal/ux.py b/hikari/internal/ux.py
index cf1914c2..0e73dd72 100644
--- a/hikari/internal/ux.py
+++ b/hikari/internal/ux.py
@@ -149,7 +149,8 @@ def init_logging(
 
 def _read_banner(package: str) -> str:
     if sys.version_info >= (3, 9):
-        return importlib.resources.files(package).joinpath("banner.txt").open("r").read()
+        with importlib.resources.files(package).joinpath("banner.txt").open("r") as fp:
+            return fp.read()
     else:
         return importlib.resources.read_text(package, "banner.txt")
 


Test patch:
diff --git a/tests/hikari/impl/test_rest.py b/tests/hikari/impl/test_rest.py
index 2af8b2f9..9d914ac0 100644
--- a/tests/hikari/impl/test_rest.py
+++ b/tests/hikari/impl/test_rest.py
@@ -320,6 +320,7 @@ def test_build(self):
         assert attributes.tcp_connector is create_tcp_connector.return_value
 
         bucket_manager.assert_called_once_with(123.321)
+        bucket_manager.return_value.start.assert_called_once_with()
         create_tcp_connector.assert_called_once_with(mock_settings)
         create_client_session.assert_called_once_with(
             connector=create_tcp_connector.return_value,
diff --git a/tests/hikari/internal/test_ux.py b/tests/hikari/internal/test_ux.py
index 5596a76e..c5226702 100644
--- a/tests/hikari/internal/test_ux.py
+++ b/tests/hikari/internal/test_ux.py
@@ -146,9 +146,25 @@ def test_when_doesnt_support_color(self):
 
 class TestRedBanner:
     def test_when_above_3_9(self):
+        class MockFile:
+            context_entered = 0
+            context_exited = 0
+
+            def __enter__(self):
+                self.context_entered += 1
+                return self
+
+            def __exit__(self, exc_type, exc_val, exc_tb):
+                self.context_exited += 1
+                return None
+
+            def read(self):
+                return read
+
         class MockTraversable:
             joint_path = None
             open_mode = None
+            mock_file = None
 
             def joinpath(self, path):
                 self.joint_path = path
@@ -156,12 +172,10 @@ def joinpath(self, path):
 
             def open(self, mode):
                 self.open_mode = mode
-                return self
-
-            def read(self):
-                return read
+                return self.mock_file
 
         traversable = MockTraversable()
+        traversable.mock_file = MockFile()
         read = object()
 
         with mock.patch.object(sys, "version_info", new=(3, 9)):
@@ -171,6 +185,8 @@ def read(self):
         read_text.assert_called_once_with("hikaru")
         assert traversable.joint_path == "banner.txt"
         assert traversable.open_mode == "r"
+        assert traversable.mock_file.context_entered == 1
+        assert traversable.mock_file.context_exited == 1
 
     def test_when_bellow_3_9(self):
         with mock.patch.object(sys, "version_info", new=(2, 7)):