mirror of
https://github.com/Cog-Creators/Red-DiscordBot.git
synced 2025-11-21 10:17:59 -05:00
[Core] Add deprecation warnings about removal of shared libraries. (#3106)
* feat: add deprecation warning when importing shared libs * enhance(downloader): add shared libs deprecation warns * enhance: add deprecation warning when (re)loading cogs * docs(downloader): add deprecation note about shared libs * chore(changelog): add towncrier entries * style: split long tuple unpacks in multiple lines * fix: argument to `humanize_list` has to be a sequence
This commit is contained in:
29
redbot/core/_sharedlibdeprecation.py
Normal file
29
redbot/core/_sharedlibdeprecation.py
Normal file
@@ -0,0 +1,29 @@
|
||||
from importlib.abc import MetaPathFinder
|
||||
import warnings
|
||||
|
||||
|
||||
class SharedLibDeprecationWarning(DeprecationWarning):
|
||||
pass
|
||||
|
||||
|
||||
warnings.simplefilter("always", SharedLibDeprecationWarning)
|
||||
|
||||
|
||||
class SharedLibImportWarner(MetaPathFinder):
|
||||
"""
|
||||
Deprecation warner for shared libraries. This class sits on `sys.meta_path`
|
||||
and prints warning if imported module is a shared library
|
||||
"""
|
||||
|
||||
def find_spec(self, fullname, path, target=None) -> None:
|
||||
"""This is only supposed to print warnings, it won't ever return module spec."""
|
||||
parts = fullname.split(".")
|
||||
if parts[0] != "cog_shared" or len(parts) != 2:
|
||||
return None
|
||||
msg = (
|
||||
"One of cogs uses shared libraries which are"
|
||||
" deprecated and scheduled for removal in Red 3.3.\n"
|
||||
"You should inform author of the cog about this message."
|
||||
)
|
||||
warnings.warn(msg, SharedLibDeprecationWarning, stacklevel=2)
|
||||
return None
|
||||
@@ -14,7 +14,7 @@ from collections import namedtuple
|
||||
from pathlib import Path
|
||||
from random import SystemRandom
|
||||
from string import ascii_letters, digits
|
||||
from typing import TYPE_CHECKING, Union, Tuple, List, Optional, Iterable, Sequence, Dict
|
||||
from typing import TYPE_CHECKING, Union, Tuple, List, Optional, Iterable, Sequence, Dict, Set
|
||||
|
||||
import aiohttp
|
||||
import discord
|
||||
@@ -70,7 +70,7 @@ class CoreLogic:
|
||||
|
||||
async def _load(
|
||||
self, cog_names: Iterable[str]
|
||||
) -> Tuple[List[str], List[str], List[str], List[str], List[Tuple[str, str]]]:
|
||||
) -> Tuple[List[str], List[str], List[str], List[str], List[Tuple[str, str]], Set[str]]:
|
||||
"""
|
||||
Loads cogs by name.
|
||||
Parameters
|
||||
@@ -87,6 +87,7 @@ class CoreLogic:
|
||||
notfound_packages = []
|
||||
alreadyloaded_packages = []
|
||||
failed_with_reason_packages = []
|
||||
repos_with_shared_libs = set()
|
||||
|
||||
bot = self.bot
|
||||
|
||||
@@ -125,6 +126,20 @@ class CoreLogic:
|
||||
else:
|
||||
await bot.add_loaded_package(name)
|
||||
loaded_packages.append(name)
|
||||
# remove in Red 3.3
|
||||
downloader = bot.get_cog("Downloader")
|
||||
if downloader is None:
|
||||
continue
|
||||
try:
|
||||
maybe_repo = await downloader._shared_lib_load_check(name)
|
||||
except Exception:
|
||||
log.exception(
|
||||
"Shared library check failed,"
|
||||
" if you're not using modified Downloader, report this issue."
|
||||
)
|
||||
maybe_repo = None
|
||||
if maybe_repo is not None:
|
||||
repos_with_shared_libs.add(maybe_repo.name)
|
||||
|
||||
return (
|
||||
loaded_packages,
|
||||
@@ -132,6 +147,7 @@ class CoreLogic:
|
||||
notfound_packages,
|
||||
alreadyloaded_packages,
|
||||
failed_with_reason_packages,
|
||||
repos_with_shared_libs,
|
||||
)
|
||||
|
||||
@staticmethod
|
||||
@@ -186,14 +202,26 @@ class CoreLogic:
|
||||
|
||||
async def _reload(
|
||||
self, cog_names: Sequence[str]
|
||||
) -> Tuple[List[str], List[str], List[str], List[str], List[Tuple[str, str]]]:
|
||||
) -> Tuple[List[str], List[str], List[str], List[str], List[Tuple[str, str]], Set[str]]:
|
||||
await self._unload(cog_names)
|
||||
|
||||
loaded, load_failed, not_found, already_loaded, load_failed_with_reason = await self._load(
|
||||
cog_names
|
||||
)
|
||||
(
|
||||
loaded,
|
||||
load_failed,
|
||||
not_found,
|
||||
already_loaded,
|
||||
load_failed_with_reason,
|
||||
repos_with_shared_libs,
|
||||
) = await self._load(cog_names)
|
||||
|
||||
return loaded, load_failed, not_found, already_loaded, load_failed_with_reason
|
||||
return (
|
||||
loaded,
|
||||
load_failed,
|
||||
not_found,
|
||||
already_loaded,
|
||||
load_failed_with_reason,
|
||||
repos_with_shared_libs,
|
||||
)
|
||||
|
||||
async def _name(self, name: Optional[str] = None) -> str:
|
||||
"""
|
||||
@@ -580,7 +608,14 @@ class Core(commands.Cog, CoreLogic):
|
||||
return await ctx.send_help()
|
||||
cogs = tuple(map(lambda cog: cog.rstrip(","), cogs))
|
||||
async with ctx.typing():
|
||||
loaded, failed, not_found, already_loaded, failed_with_reason = await self._load(cogs)
|
||||
(
|
||||
loaded,
|
||||
failed,
|
||||
not_found,
|
||||
already_loaded,
|
||||
failed_with_reason,
|
||||
repos_with_shared_libs,
|
||||
) = await self._load(cogs)
|
||||
|
||||
output = []
|
||||
|
||||
@@ -636,6 +671,21 @@ class Core(commands.Cog, CoreLogic):
|
||||
).format(reasons=reasons)
|
||||
output.append(formed)
|
||||
|
||||
if repos_with_shared_libs:
|
||||
if len(repos_with_shared_libs) == 1:
|
||||
formed = _(
|
||||
"**WARNING**: The following repo is using shared libs"
|
||||
" which are marked for removal in Red 3.3: {repo}.\n"
|
||||
"You should inform maintainer of the repo about this message."
|
||||
).format(repo=inline(repos_with_shared_libs.pop()))
|
||||
else:
|
||||
formed = _(
|
||||
"**WARNING**: The following repos are using shared libs"
|
||||
" which are marked for removal in Red 3.3: {repos}.\n"
|
||||
"You should inform maintainers of these repos about this message."
|
||||
).format(repos=humanize_list([inline(repo) for repo in repos_with_shared_libs]))
|
||||
output.append(formed)
|
||||
|
||||
if output:
|
||||
total_message = "\n\n".join(output)
|
||||
for page in pagify(total_message):
|
||||
@@ -687,9 +737,14 @@ class Core(commands.Cog, CoreLogic):
|
||||
return await ctx.send_help()
|
||||
cogs = tuple(map(lambda cog: cog.rstrip(","), cogs))
|
||||
async with ctx.typing():
|
||||
loaded, failed, not_found, already_loaded, failed_with_reason = await self._reload(
|
||||
cogs
|
||||
)
|
||||
(
|
||||
loaded,
|
||||
failed,
|
||||
not_found,
|
||||
already_loaded,
|
||||
failed_with_reason,
|
||||
repos_with_shared_libs,
|
||||
) = await self._reload(cogs)
|
||||
|
||||
output = []
|
||||
|
||||
@@ -734,6 +789,21 @@ class Core(commands.Cog, CoreLogic):
|
||||
).format(reasons=reasons)
|
||||
output.append(formed)
|
||||
|
||||
if repos_with_shared_libs:
|
||||
if len(repos_with_shared_libs) == 1:
|
||||
formed = _(
|
||||
"**WARNING**: The following repo is using shared libs"
|
||||
" which are marked for removal in Red 3.3: {repo}.\n"
|
||||
"You should inform maintainers of these repos about this message."
|
||||
).format(repo=inline(repos_with_shared_libs.pop()))
|
||||
else:
|
||||
formed = _(
|
||||
"**WARNING**: The following repos are using shared libs"
|
||||
" which are marked for removal in Red 3.3: {repos}.\n"
|
||||
"You should inform maintainers of these repos about this message."
|
||||
).format(repos=humanize_list([inline(repo) for repo in repos_with_shared_libs]))
|
||||
output.append(formed)
|
||||
|
||||
if output:
|
||||
total_message = "\n\n".join(output)
|
||||
for page in pagify(total_message):
|
||||
|
||||
Reference in New Issue
Block a user