Browse Source

[commands] Make Bot.cogs and Bot.extensions read-only mappings.

This also has the side effect of effectively documenting them for
public use.
pull/1995/head
Rapptz 6 years ago
parent
commit
f26a27dc98
  1. 35
      discord/ext/commands/bot.py

35
discord/ext/commands/bot.py

@ -31,6 +31,7 @@ import importlib
import sys import sys
import traceback import traceback
import re import re
import types
import discord import discord
@ -98,8 +99,8 @@ class BotBase(GroupMixin):
super().__init__(**options) super().__init__(**options)
self.command_prefix = command_prefix self.command_prefix = command_prefix
self.extra_events = {} self.extra_events = {}
self.cogs = {} self._cogs = {}
self.extensions = {} self._extensions = {}
self._checks = [] self._checks = []
self._check_once = [] self._check_once = []
self._before_invoke = None self._before_invoke = None
@ -128,13 +129,13 @@ class BotBase(GroupMixin):
asyncio.ensure_future(coro, loop=self.loop) asyncio.ensure_future(coro, loop=self.loop)
async def close(self): async def close(self):
for extension in tuple(self.extensions): for extension in tuple(self._extensions):
try: try:
self.unload_extension(extension) self.unload_extension(extension)
except Exception: except Exception:
pass pass
for cog in tuple(self.cogs): for cog in tuple(self._cogs):
try: try:
self.remove_cog(cog) self.remove_cog(cog)
except Exception: except Exception:
@ -476,7 +477,7 @@ class BotBase(GroupMixin):
raise TypeError('cogs must derive from Cog') raise TypeError('cogs must derive from Cog')
cog = cog._inject(self) cog = cog._inject(self)
self.cogs[cog.__cog_name__] = cog self._cogs[cog.__cog_name__] = cog
def get_cog(self, name): def get_cog(self, name):
"""Gets the cog instance requested. """Gets the cog instance requested.
@ -490,7 +491,7 @@ class BotBase(GroupMixin):
This is equivalent to the name passed via keyword This is equivalent to the name passed via keyword
argument in class creation or the class name if unspecified. argument in class creation or the class name if unspecified.
""" """
return self.cogs.get(name) return self._cogs.get(name)
def remove_cog(self, name): def remove_cog(self, name):
"""Removes a cog from the bot. """Removes a cog from the bot.
@ -506,7 +507,7 @@ class BotBase(GroupMixin):
The name of the cog to remove. The name of the cog to remove.
""" """
cog = self.cogs.pop(name, None) cog = self._cogs.pop(name, None)
if cog is None: if cog is None:
return return
@ -515,6 +516,11 @@ class BotBase(GroupMixin):
help_command.cog = None help_command.cog = None
cog._eject(self) cog._eject(self)
@property
def cogs(self):
"""Mapping[:class:`str`, :class:`Cog`]: A read-only mapping of cog name to cog."""
return types.MappingProxyType(self._cogs)
# extensions # extensions
def load_extension(self, name): def load_extension(self, name):
@ -542,7 +548,7 @@ class BotBase(GroupMixin):
The extension could not be imported. The extension could not be imported.
""" """
if name in self.extensions: if name in self._extensions:
return return
lib = importlib.import_module(name) lib = importlib.import_module(name)
@ -552,7 +558,7 @@ class BotBase(GroupMixin):
raise discord.ClientException('extension does not have a setup function') raise discord.ClientException('extension does not have a setup function')
lib.setup(self) lib.setup(self)
self.extensions[name] = lib self._extensions[name] = lib
def unload_extension(self, name): def unload_extension(self, name):
"""Unloads an extension. """Unloads an extension.
@ -573,7 +579,7 @@ class BotBase(GroupMixin):
``foo.test`` if you want to import ``foo/test.py``. ``foo.test`` if you want to import ``foo/test.py``.
""" """
lib = self.extensions.get(name) lib = self._extensions.get(name)
if lib is None: if lib is None:
return return
@ -582,7 +588,7 @@ class BotBase(GroupMixin):
# find all references to the module # find all references to the module
# remove the cogs registered from the module # remove the cogs registered from the module
for cogname, cog in self.cogs.copy().items(): for cogname, cog in self._cogs.copy().items():
if _is_submodule(lib_name, cog.__module__): if _is_submodule(lib_name, cog.__module__):
self.remove_cog(cogname) self.remove_cog(cogname)
@ -615,12 +621,17 @@ class BotBase(GroupMixin):
finally: finally:
# finally remove the import.. # finally remove the import..
del lib del lib
del self.extensions[name] del self._extensions[name]
del sys.modules[name] del sys.modules[name]
for module in list(sys.modules.keys()): for module in list(sys.modules.keys()):
if _is_submodule(lib_name, module): if _is_submodule(lib_name, module):
del sys.modules[module] del sys.modules[module]
@property
def extensions(self):
"""Mapping[:class:`str`, :class:`py:types.ModuleType`]: A read-only mapping of extension name to extension."""
return types.MappingProxyType(self._extensions)
# help command stuff # help command stuff
@property @property

Loading…
Cancel
Save