mirror of
https://github.com/Cog-Creators/Red-DiscordBot.git
synced 2025-11-06 11:18:54 -05:00
Handle deprecations in asyncio (#3509)
* passing loop to certain things was deprecated. additionally, `asyncio.get_event_loop()` is being deprecated * awesome, checks are functioning as intended * fun with fixtures * we can just stop misuing that anyhow * Update redbot/pytest/downloader.py Co-Authored-By: jack1142 <6032823+jack1142@users.noreply.github.com> Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>
This commit is contained in:
parent
61ed864e02
commit
00cf395483
@ -1,7 +1,5 @@
|
|||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
# Discord Version check
|
|
||||||
|
|
||||||
import asyncio
|
import asyncio
|
||||||
import functools
|
import functools
|
||||||
import getpass
|
import getpass
|
||||||
@ -20,7 +18,7 @@ from typing import NoReturn
|
|||||||
|
|
||||||
import discord
|
import discord
|
||||||
|
|
||||||
# Set the event loop policies here so any subsequent `get_event_loop()`
|
# Set the event loop policies here so any subsequent `new_event_loop()`
|
||||||
# calls, in particular those as a result of the following imports,
|
# calls, in particular those as a result of the following imports,
|
||||||
# return the correct loop object.
|
# return the correct loop object.
|
||||||
from redbot import _update_event_loop_policy, __version__
|
from redbot import _update_event_loop_policy, __version__
|
||||||
@ -298,7 +296,8 @@ def handle_edit(cli_flags: Namespace):
|
|||||||
"""
|
"""
|
||||||
This one exists to not log all the things like it's a full run of the bot.
|
This one exists to not log all the things like it's a full run of the bot.
|
||||||
"""
|
"""
|
||||||
loop = asyncio.get_event_loop()
|
loop = asyncio.new_event_loop()
|
||||||
|
asyncio.set_event_loop(loop)
|
||||||
data_manager.load_basic_configuration(cli_flags.instance_name)
|
data_manager.load_basic_configuration(cli_flags.instance_name)
|
||||||
red = Red(cli_flags=cli_flags, description="Red V3", dm_help=None, fetch_offline_members=True)
|
red = Red(cli_flags=cli_flags, description="Red V3", dm_help=None, fetch_offline_members=True)
|
||||||
try:
|
try:
|
||||||
@ -310,6 +309,7 @@ def handle_edit(cli_flags: Namespace):
|
|||||||
print("Aborted!")
|
print("Aborted!")
|
||||||
finally:
|
finally:
|
||||||
loop.run_until_complete(asyncio.sleep(1))
|
loop.run_until_complete(asyncio.sleep(1))
|
||||||
|
asyncio.set_event_loop(None)
|
||||||
loop.stop()
|
loop.stop()
|
||||||
loop.close()
|
loop.close()
|
||||||
sys.exit(0)
|
sys.exit(0)
|
||||||
@ -460,7 +460,8 @@ def main():
|
|||||||
handle_edit(cli_flags)
|
handle_edit(cli_flags)
|
||||||
return
|
return
|
||||||
try:
|
try:
|
||||||
loop = asyncio.get_event_loop()
|
loop = asyncio.new_event_loop()
|
||||||
|
asyncio.set_event_loop(loop)
|
||||||
|
|
||||||
if cli_flags.no_instance:
|
if cli_flags.no_instance:
|
||||||
print(
|
print(
|
||||||
@ -524,6 +525,7 @@ def main():
|
|||||||
# results in a resource warning instead
|
# results in a resource warning instead
|
||||||
log.info("Please wait, cleaning up a bit more")
|
log.info("Please wait, cleaning up a bit more")
|
||||||
loop.run_until_complete(asyncio.sleep(2))
|
loop.run_until_complete(asyncio.sleep(2))
|
||||||
|
asyncio.set_event_loop(None)
|
||||||
loop.stop()
|
loop.stop()
|
||||||
loop.close()
|
loop.close()
|
||||||
exit_code = red._shutdown_mode if red is not None else 1
|
exit_code = red._shutdown_mode if red is not None else 1
|
||||||
|
|||||||
@ -462,7 +462,7 @@ class Downloader(commands.Cog):
|
|||||||
if not deps:
|
if not deps:
|
||||||
await ctx.send_help()
|
await ctx.send_help()
|
||||||
return
|
return
|
||||||
repo = Repo("", "", "", "", Path.cwd(), loop=ctx.bot.loop)
|
repo = Repo("", "", "", "", Path.cwd())
|
||||||
async with ctx.typing():
|
async with ctx.typing():
|
||||||
success = await repo.install_raw_requirements(deps, self.LIB_PATH)
|
success = await repo.install_raw_requirements(deps, self.LIB_PATH)
|
||||||
|
|
||||||
|
|||||||
@ -135,7 +135,6 @@ class Repo(RepoJSONMixin):
|
|||||||
commit: str,
|
commit: str,
|
||||||
folder_path: Path,
|
folder_path: Path,
|
||||||
available_modules: Tuple[Installable, ...] = (),
|
available_modules: Tuple[Installable, ...] = (),
|
||||||
loop: Optional[asyncio.AbstractEventLoop] = None,
|
|
||||||
):
|
):
|
||||||
self.url = url
|
self.url = url
|
||||||
self.branch = branch
|
self.branch = branch
|
||||||
@ -154,8 +153,6 @@ class Repo(RepoJSONMixin):
|
|||||||
|
|
||||||
self._repo_lock = asyncio.Lock()
|
self._repo_lock = asyncio.Lock()
|
||||||
|
|
||||||
self._loop = loop if loop is not None else asyncio.get_event_loop()
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def clean_url(self) -> str:
|
def clean_url(self) -> str:
|
||||||
"""Sanitized repo URL (with removed HTTP Basic Auth)"""
|
"""Sanitized repo URL (with removed HTTP Basic Auth)"""
|
||||||
@ -529,7 +526,7 @@ class Repo(RepoJSONMixin):
|
|||||||
env["LANGUAGE"] = "C"
|
env["LANGUAGE"] = "C"
|
||||||
kwargs["env"] = env
|
kwargs["env"] = env
|
||||||
async with self._repo_lock:
|
async with self._repo_lock:
|
||||||
p: CompletedProcess = await self._loop.run_in_executor(
|
p: CompletedProcess = await asyncio.get_running_loop().run_in_executor(
|
||||||
self._executor,
|
self._executor,
|
||||||
functools.partial(sp_run, *args, stdout=PIPE, stderr=PIPE, **kwargs),
|
functools.partial(sp_run, *args, stdout=PIPE, stderr=PIPE, **kwargs),
|
||||||
)
|
)
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
import asyncio
|
import asyncio
|
||||||
|
import warnings
|
||||||
from asyncio import AbstractEventLoop, as_completed, Semaphore
|
from asyncio import AbstractEventLoop, as_completed, Semaphore
|
||||||
from asyncio.futures import isfuture
|
from asyncio.futures import isfuture
|
||||||
from itertools import chain
|
from itertools import chain
|
||||||
@ -177,14 +178,20 @@ def bounded_gather_iter(
|
|||||||
TypeError
|
TypeError
|
||||||
When invalid parameters are passed
|
When invalid parameters are passed
|
||||||
"""
|
"""
|
||||||
if loop is None:
|
if loop is not None:
|
||||||
loop = asyncio.get_event_loop()
|
warnings.warn(
|
||||||
|
"Explicitly passing the loop will not work in Red 3.4+ and is currently ignored."
|
||||||
|
"Call this from the related event loop.",
|
||||||
|
DeprecationWarning,
|
||||||
|
)
|
||||||
|
|
||||||
|
loop = asyncio.get_running_loop()
|
||||||
|
|
||||||
if semaphore is None:
|
if semaphore is None:
|
||||||
if not isinstance(limit, int) or limit <= 0:
|
if not isinstance(limit, int) or limit <= 0:
|
||||||
raise TypeError("limit must be an int > 0")
|
raise TypeError("limit must be an int > 0")
|
||||||
|
|
||||||
semaphore = Semaphore(limit, loop=loop)
|
semaphore = Semaphore(limit)
|
||||||
|
|
||||||
pending = []
|
pending = []
|
||||||
|
|
||||||
@ -195,7 +202,7 @@ def bounded_gather_iter(
|
|||||||
cof = _sem_wrapper(semaphore, cof)
|
cof = _sem_wrapper(semaphore, cof)
|
||||||
pending.append(cof)
|
pending.append(cof)
|
||||||
|
|
||||||
return as_completed(pending, loop=loop)
|
return as_completed(pending)
|
||||||
|
|
||||||
|
|
||||||
def bounded_gather(
|
def bounded_gather(
|
||||||
@ -228,15 +235,21 @@ def bounded_gather(
|
|||||||
TypeError
|
TypeError
|
||||||
When invalid parameters are passed
|
When invalid parameters are passed
|
||||||
"""
|
"""
|
||||||
if loop is None:
|
if loop is not None:
|
||||||
loop = asyncio.get_event_loop()
|
warnings.warn(
|
||||||
|
"Explicitly passing the loop will not work in Red 3.4+ and is currently ignored."
|
||||||
|
"Call this from the related event loop.",
|
||||||
|
DeprecationWarning,
|
||||||
|
)
|
||||||
|
|
||||||
|
loop = asyncio.get_running_loop()
|
||||||
|
|
||||||
if semaphore is None:
|
if semaphore is None:
|
||||||
if not isinstance(limit, int) or limit <= 0:
|
if not isinstance(limit, int) or limit <= 0:
|
||||||
raise TypeError("limit must be an int > 0")
|
raise TypeError("limit must be an int > 0")
|
||||||
|
|
||||||
semaphore = Semaphore(limit, loop=loop)
|
semaphore = Semaphore(limit)
|
||||||
|
|
||||||
tasks = (_sem_wrapper(semaphore, task) for task in coros_or_futures)
|
tasks = (_sem_wrapper(semaphore, task) for task in coros_or_futures)
|
||||||
|
|
||||||
return asyncio.gather(*tasks, loop=loop, return_exceptions=return_exceptions)
|
return asyncio.gather(*tasks, return_exceptions=return_exceptions)
|
||||||
|
|||||||
@ -5,6 +5,7 @@
|
|||||||
import asyncio
|
import asyncio
|
||||||
import contextlib
|
import contextlib
|
||||||
import functools
|
import functools
|
||||||
|
import warnings
|
||||||
from typing import Union, Iterable, Optional
|
from typing import Union, Iterable, Optional
|
||||||
import discord
|
import discord
|
||||||
|
|
||||||
@ -200,7 +201,9 @@ def start_adding_reactions(
|
|||||||
await message.add_reaction(emoji)
|
await message.add_reaction(emoji)
|
||||||
|
|
||||||
if loop is None:
|
if loop is None:
|
||||||
loop = asyncio.get_event_loop()
|
loop = asyncio.get_running_loop()
|
||||||
|
else:
|
||||||
|
warnings.warn("Explicitly passing the loop will not work in Red 3.4+", DeprecationWarning)
|
||||||
|
|
||||||
return loop.create_task(task())
|
return loop.create_task(task())
|
||||||
|
|
||||||
|
|||||||
@ -76,7 +76,6 @@ def bot_repo(event_loop):
|
|||||||
commit="",
|
commit="",
|
||||||
url="https://empty.com/something.git",
|
url="https://empty.com/something.git",
|
||||||
folder_path=cwd,
|
folder_path=cwd,
|
||||||
loop=event_loop,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@ -163,14 +162,7 @@ def _init_test_repo(destination: Path):
|
|||||||
async def _session_git_repo(tmp_path_factory, event_loop):
|
async def _session_git_repo(tmp_path_factory, event_loop):
|
||||||
# we will import repo only once once per session and duplicate the repo folder
|
# we will import repo only once once per session and duplicate the repo folder
|
||||||
repo_path = tmp_path_factory.mktemp("session_git_repo")
|
repo_path = tmp_path_factory.mktemp("session_git_repo")
|
||||||
repo = Repo(
|
repo = Repo(name="redbot-testrepo", url="", branch="master", commit="", folder_path=repo_path)
|
||||||
name="redbot-testrepo",
|
|
||||||
url="",
|
|
||||||
branch="master",
|
|
||||||
commit="",
|
|
||||||
folder_path=repo_path,
|
|
||||||
loop=event_loop,
|
|
||||||
)
|
|
||||||
git_dirparams = _init_test_repo(repo_path)
|
git_dirparams = _init_test_repo(repo_path)
|
||||||
fast_import = sp.Popen((*git_dirparams, "fast-import", "--quiet"), stdin=sp.PIPE)
|
fast_import = sp.Popen((*git_dirparams, "fast-import", "--quiet"), stdin=sp.PIPE)
|
||||||
with TEST_REPO_EXPORT_PTH.open(mode="rb") as f:
|
with TEST_REPO_EXPORT_PTH.open(mode="rb") as f:
|
||||||
@ -193,7 +185,6 @@ async def git_repo(_session_git_repo, tmp_path, event_loop):
|
|||||||
branch=_session_git_repo.branch,
|
branch=_session_git_repo.branch,
|
||||||
commit=_session_git_repo.commit,
|
commit=_session_git_repo.commit,
|
||||||
folder_path=repo_path,
|
folder_path=repo_path,
|
||||||
loop=event_loop,
|
|
||||||
)
|
)
|
||||||
return repo
|
return repo
|
||||||
|
|
||||||
@ -208,7 +199,6 @@ async def cloned_git_repo(_session_git_repo, tmp_path, event_loop):
|
|||||||
branch=_session_git_repo.branch,
|
branch=_session_git_repo.branch,
|
||||||
commit=_session_git_repo.commit,
|
commit=_session_git_repo.commit,
|
||||||
folder_path=repo_path,
|
folder_path=repo_path,
|
||||||
loop=event_loop,
|
|
||||||
)
|
)
|
||||||
sp.run(("git", "clone", str(_session_git_repo.folder_path), str(repo_path)), check=True)
|
sp.run(("git", "clone", str(_session_git_repo.folder_path), str(repo_path)), check=True)
|
||||||
return repo
|
return repo
|
||||||
@ -224,7 +214,6 @@ async def git_repo_with_remote(git_repo, tmp_path, event_loop):
|
|||||||
branch=git_repo.branch,
|
branch=git_repo.branch,
|
||||||
commit=git_repo.commit,
|
commit=git_repo.commit,
|
||||||
folder_path=repo_path,
|
folder_path=repo_path,
|
||||||
loop=event_loop,
|
|
||||||
)
|
)
|
||||||
sp.run(("git", "clone", str(git_repo.folder_path), str(repo_path)), check=True)
|
sp.run(("git", "clone", str(git_repo.folder_path), str(repo_path)), check=True)
|
||||||
return repo
|
return repo
|
||||||
|
|||||||
@ -371,8 +371,7 @@ def delete(
|
|||||||
remove_datapath: Optional[bool],
|
remove_datapath: Optional[bool],
|
||||||
):
|
):
|
||||||
"""Removes an instance."""
|
"""Removes an instance."""
|
||||||
loop = asyncio.get_event_loop()
|
asyncio.run(
|
||||||
loop.run_until_complete(
|
|
||||||
remove_instance(
|
remove_instance(
|
||||||
instance, interactive, delete_data, _create_backup, drop_db, remove_datapath
|
instance, interactive, delete_data, _create_backup, drop_db, remove_datapath
|
||||||
)
|
)
|
||||||
@ -391,14 +390,12 @@ def convert(instance, backend):
|
|||||||
default_dirs = deepcopy(data_manager.basic_config_default)
|
default_dirs = deepcopy(data_manager.basic_config_default)
|
||||||
default_dirs["DATA_PATH"] = str(Path(instance_data[instance]["DATA_PATH"]))
|
default_dirs["DATA_PATH"] = str(Path(instance_data[instance]["DATA_PATH"]))
|
||||||
|
|
||||||
loop = asyncio.get_event_loop()
|
|
||||||
|
|
||||||
if current_backend == BackendType.MONGOV1:
|
if current_backend == BackendType.MONGOV1:
|
||||||
raise RuntimeError("Please see the 3.2 release notes for upgrading a bot using mongo.")
|
raise RuntimeError("Please see the 3.2 release notes for upgrading a bot using mongo.")
|
||||||
elif current_backend == BackendType.POSTGRES: # TODO: GH-3115
|
elif current_backend == BackendType.POSTGRES: # TODO: GH-3115
|
||||||
raise RuntimeError("Converting away from postgres isn't currently supported")
|
raise RuntimeError("Converting away from postgres isn't currently supported")
|
||||||
else:
|
else:
|
||||||
new_storage_details = loop.run_until_complete(do_migration(current_backend, target))
|
new_storage_details = asyncio.run(do_migration(current_backend, target))
|
||||||
|
|
||||||
if new_storage_details is not None:
|
if new_storage_details is not None:
|
||||||
default_dirs["STORAGE_TYPE"] = target.value
|
default_dirs["STORAGE_TYPE"] = target.value
|
||||||
@ -422,8 +419,7 @@ def convert(instance, backend):
|
|||||||
)
|
)
|
||||||
def backup(instance: str, destination_folder: Union[str, Path]) -> None:
|
def backup(instance: str, destination_folder: Union[str, Path]) -> None:
|
||||||
"""Backup instance's data."""
|
"""Backup instance's data."""
|
||||||
loop = asyncio.get_event_loop()
|
asyncio.run(create_backup(instance, Path(destination_folder)))
|
||||||
loop.run_until_complete(create_backup(instance, Path(destination_folder)))
|
|
||||||
|
|
||||||
|
|
||||||
def run_cli():
|
def run_cli():
|
||||||
|
|||||||
@ -12,8 +12,10 @@ _update_event_loop_policy()
|
|||||||
@pytest.fixture(scope="session")
|
@pytest.fixture(scope="session")
|
||||||
def event_loop(request):
|
def event_loop(request):
|
||||||
"""Create an instance of the default event loop for entire session."""
|
"""Create an instance of the default event loop for entire session."""
|
||||||
loop = asyncio.get_event_loop_policy().new_event_loop()
|
loop = asyncio.new_event_loop()
|
||||||
|
asyncio.set_event_loop(loop)
|
||||||
yield loop
|
yield loop
|
||||||
|
asyncio.set_event_loop(None)
|
||||||
loop.close()
|
loop.close()
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user