Skip to content

Commit

Permalink
Use a stack to keep streams open until usage in `RESTClient.edit_guil…
Browse files Browse the repository at this point in the history
  • Loading branch information
davfsa authored and yakMM committed Oct 19, 2023
1 parent 1b57628 commit 7b0159e
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 17 deletions.
1 change: 1 addition & 0 deletions changes/1627.bugfix.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Fix a bug in `RESTClient.edit_guild` which load to closed stream errors
37 changes: 21 additions & 16 deletions hikari/impl/rest.py
Original file line number Diff line number Diff line change
Expand Up @@ -2537,36 +2537,41 @@ async def edit_guild(
body.put_snowflake("rules_channel_id", rules_channel)
body.put_snowflake("public_updates_channel_id", public_updates_channel)

stack = contextlib.AsyncExitStack()
tasks: typing.List[asyncio.Task[str]] = []

if icon is None:
body.put("icon", None)
elif icon is not undefined.UNDEFINED:
icon_resource = files.ensure_resource(icon)
async with icon_resource.stream(executor=self._executor) as stream:
async with stack:
if icon is None:
body.put("icon", None)
elif icon is not undefined.UNDEFINED:
icon_resource = files.ensure_resource(icon)
stream = await stack.enter_async_context(icon_resource.stream(executor=self._executor))

task = asyncio.create_task(stream.data_uri())
task.add_done_callback(lambda future: body.put("icon", future.result()))
tasks.append(task)

if splash is None:
body.put("splash", None)
elif splash is not undefined.UNDEFINED:
splash_resource = files.ensure_resource(splash)
async with splash_resource.stream(executor=self._executor) as stream:
if splash is None:
body.put("splash", None)
elif splash is not undefined.UNDEFINED:
splash_resource = files.ensure_resource(splash)
stream = await stack.enter_async_context(splash_resource.stream(executor=self._executor))

task = asyncio.create_task(stream.data_uri())
task.add_done_callback(lambda future: body.put("splash", future.result()))
tasks.append(task)

if banner is None:
body.put("banner", None)
elif banner is not undefined.UNDEFINED:
banner_resource = files.ensure_resource(banner)
async with banner_resource.stream(executor=self._executor) as stream:
if banner is None:
body.put("banner", None)
elif banner is not undefined.UNDEFINED:
banner_resource = files.ensure_resource(banner)
stream = await stack.enter_async_context(banner_resource.stream(executor=self._executor))

task = asyncio.create_task(stream.data_uri())
task.add_done_callback(lambda future: body.put("banner", future.result()))
tasks.append(task)

await asyncio.gather(*tasks)
await asyncio.gather(*tasks)

response = await self._request(route, json=body, reason=reason)
assert isinstance(response, dict)
Expand Down
7 changes: 6 additions & 1 deletion tests/hikari/impl/test_rest.py
Original file line number Diff line number Diff line change
Expand Up @@ -430,16 +430,21 @@ def rest_client(rest_client_class, mock_cache):
def file_resource():
class Stream:
def __init__(self, data):
self.open = False
self.data = data

async def data_uri(self):
if not self.open:
raise RuntimeError("Tried to read off a closed stream")

return self.data

async def __aenter__(self):
self.open = True
return self

async def __aexit__(self, exc_type, exc, exc_tb) -> None:
pass
self.open = False

class FileResource(files.Resource):
filename = None
Expand Down

0 comments on commit 7b0159e

Please sign in to comment.