mirror of
https://github.com/Cog-Creators/Red-DiscordBot.git
synced 2025-11-06 11:18:54 -05:00
[Config] Modify config's all methods to provide default values (#916)
* Add in functionality for Tobotimus * Cover all_guilds * Make it obvious * Fix auto rename of docstrings * Fix downloader docs warning
This commit is contained in:
parent
248d2baa2a
commit
da28630644
@ -108,12 +108,16 @@ class Group(Value):
|
|||||||
defaults: dict,
|
defaults: dict,
|
||||||
spawner,
|
spawner,
|
||||||
force_registration: bool=False):
|
force_registration: bool=False):
|
||||||
self.defaults = defaults
|
self._defaults = defaults
|
||||||
self.force_registration = force_registration
|
self.force_registration = force_registration
|
||||||
self.spawner = spawner
|
self.spawner = spawner
|
||||||
|
|
||||||
super().__init__(identifiers, {}, self.spawner)
|
super().__init__(identifiers, {}, self.spawner)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def defaults(self):
|
||||||
|
return self._defaults.copy()
|
||||||
|
|
||||||
# noinspection PyTypeChecker
|
# noinspection PyTypeChecker
|
||||||
def __getattr__(self, item: str) -> Union["Group", Value]:
|
def __getattr__(self, item: str) -> Union["Group", Value]:
|
||||||
"""
|
"""
|
||||||
@ -135,14 +139,14 @@ class Group(Value):
|
|||||||
if is_group:
|
if is_group:
|
||||||
return Group(
|
return Group(
|
||||||
identifiers=new_identifiers,
|
identifiers=new_identifiers,
|
||||||
defaults=self.defaults[item],
|
defaults=self._defaults[item],
|
||||||
spawner=self.spawner,
|
spawner=self.spawner,
|
||||||
force_registration=self.force_registration
|
force_registration=self.force_registration
|
||||||
)
|
)
|
||||||
elif is_value:
|
elif is_value:
|
||||||
return Value(
|
return Value(
|
||||||
identifiers=new_identifiers,
|
identifiers=new_identifiers,
|
||||||
default_value=self.defaults[item],
|
default_value=self._defaults[item],
|
||||||
spawner=self.spawner
|
spawner=self.spawner
|
||||||
)
|
)
|
||||||
elif self.force_registration:
|
elif self.force_registration:
|
||||||
@ -174,7 +178,7 @@ class Group(Value):
|
|||||||
:param str item:
|
:param str item:
|
||||||
See :py:meth:`__getattr__`.
|
See :py:meth:`__getattr__`.
|
||||||
"""
|
"""
|
||||||
default = self.defaults.get(item)
|
default = self._defaults.get(item)
|
||||||
return isinstance(default, dict)
|
return isinstance(default, dict)
|
||||||
|
|
||||||
def is_value(self, item: str) -> bool:
|
def is_value(self, item: str) -> bool:
|
||||||
@ -185,7 +189,7 @@ class Group(Value):
|
|||||||
See :py:meth:`__getattr__`.
|
See :py:meth:`__getattr__`.
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
default = self.defaults[item]
|
default = self._defaults[item]
|
||||||
except KeyError:
|
except KeyError:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
@ -231,19 +235,42 @@ class Group(Value):
|
|||||||
This method allows you to get "all" of a particular group of data. It will return the dictionary of all data
|
This method allows you to get "all" of a particular group of data. It will return the dictionary of all data
|
||||||
for a particular Guild/Channel/Role/User/Member etc.
|
for a particular Guild/Channel/Role/User/Member etc.
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
|
||||||
|
Any values that have not been set from the registered defaults will have their default values
|
||||||
|
added to the dictionary that this method returns.
|
||||||
|
|
||||||
:rtype: dict
|
:rtype: dict
|
||||||
"""
|
"""
|
||||||
return await self()
|
defaults = self.defaults
|
||||||
|
defaults.update(await self())
|
||||||
|
return defaults
|
||||||
|
|
||||||
async def all_from_kind(self) -> dict:
|
async def all_from_kind(self) -> dict:
|
||||||
"""
|
"""
|
||||||
This method allows you to get all data from all entries in a given Kind. It will return a dictionary of Kind
|
This method allows you to get all data from all entries in a given Kind. It will return a dictionary of Kind
|
||||||
ID's -> data.
|
ID's -> data.
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
|
||||||
|
Any values that have not been set from the registered defaults will have their default values
|
||||||
|
added to the dictionary that this method returns.
|
||||||
|
|
||||||
|
.. important::
|
||||||
|
|
||||||
|
This method is overridden in :py:meth:`.MemberGroup.all_from_kind` and functions slightly differently.
|
||||||
|
|
||||||
:rtype: dict
|
:rtype: dict
|
||||||
"""
|
"""
|
||||||
# noinspection PyTypeChecker
|
# noinspection PyTypeChecker
|
||||||
return await self._super_group()
|
all_from_kind = await self._super_group()
|
||||||
|
|
||||||
|
for k, v in all_from_kind.items():
|
||||||
|
defaults = self.defaults
|
||||||
|
defaults.update(v)
|
||||||
|
all_from_kind[k] = defaults
|
||||||
|
|
||||||
|
return all_from_kind
|
||||||
|
|
||||||
async def set(self, value):
|
async def set(self, value):
|
||||||
if not isinstance(value, dict):
|
if not isinstance(value, dict):
|
||||||
@ -307,14 +334,29 @@ class MemberGroup(Group):
|
|||||||
"""
|
"""
|
||||||
Returns a dict of :code:`GUILD_ID -> MEMBER_ID -> data`.
|
Returns a dict of :code:`GUILD_ID -> MEMBER_ID -> data`.
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
|
||||||
|
Any values that have not been set from the registered defaults will have their default values
|
||||||
|
added to the dictionary that this method returns.
|
||||||
|
|
||||||
:rtype: dict
|
:rtype: dict
|
||||||
"""
|
"""
|
||||||
# noinspection PyTypeChecker
|
# noinspection PyTypeChecker
|
||||||
return await self._super_group()
|
return await super().all_from_kind()
|
||||||
|
|
||||||
async def all(self) -> dict:
|
async def all_from_kind(self) -> dict:
|
||||||
# noinspection PyTypeChecker
|
"""
|
||||||
return await self._guild_group()
|
Returns a dict of all members from the same guild as the given one.
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
|
||||||
|
Any values that have not been set from the registered defaults will have their default values
|
||||||
|
added to the dictionary that this method returns.
|
||||||
|
|
||||||
|
:rtype: dict
|
||||||
|
"""
|
||||||
|
guild_member = await super().all_from_kind()
|
||||||
|
return guild_member.get(self.identifiers[-2], {})
|
||||||
|
|
||||||
|
|
||||||
class Config:
|
class Config:
|
||||||
@ -366,7 +408,11 @@ class Config:
|
|||||||
|
|
||||||
self.spawner = driver_spawn
|
self.spawner = driver_spawn
|
||||||
self.force_registration = force_registration
|
self.force_registration = force_registration
|
||||||
self.defaults = defaults or {}
|
self._defaults = defaults or {}
|
||||||
|
|
||||||
|
@property
|
||||||
|
def defaults(self):
|
||||||
|
return self._defaults.copy()
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_conf(cls, cog_instance, identifier: int,
|
def get_conf(cls, cog_instance, identifier: int,
|
||||||
@ -425,7 +471,7 @@ class Config:
|
|||||||
def _get_defaults_dict(key: str, value) -> dict:
|
def _get_defaults_dict(key: str, value) -> dict:
|
||||||
"""
|
"""
|
||||||
Since we're allowing nested config stuff now, not storing the
|
Since we're allowing nested config stuff now, not storing the
|
||||||
defaults as a flat dict sounds like a good idea. May turn
|
_defaults as a flat dict sounds like a good idea. May turn
|
||||||
out to be an awful one but we'll see.
|
out to be an awful one but we'll see.
|
||||||
:param key:
|
:param key:
|
||||||
:param value:
|
:param value:
|
||||||
@ -447,7 +493,7 @@ class Config:
|
|||||||
@staticmethod
|
@staticmethod
|
||||||
def _update_defaults(to_add: dict, _partial: dict):
|
def _update_defaults(to_add: dict, _partial: dict):
|
||||||
"""
|
"""
|
||||||
This tries to update the defaults dictionary with the nested
|
This tries to update the _defaults dictionary with the nested
|
||||||
partial dict generated by _get_defaults_dict. This WILL
|
partial dict generated by _get_defaults_dict. This WILL
|
||||||
throw an error if you try to have both a value and a group
|
throw an error if you try to have both a value and a group
|
||||||
registered under the same name.
|
registered under the same name.
|
||||||
@ -471,14 +517,14 @@ class Config:
|
|||||||
_partial[k] = v
|
_partial[k] = v
|
||||||
|
|
||||||
def _register_default(self, key: str, **kwargs):
|
def _register_default(self, key: str, **kwargs):
|
||||||
if key not in self.defaults:
|
if key not in self._defaults:
|
||||||
self.defaults[key] = {}
|
self._defaults[key] = {}
|
||||||
|
|
||||||
data = deepcopy(kwargs)
|
data = deepcopy(kwargs)
|
||||||
|
|
||||||
for k, v in data.items():
|
for k, v in data.items():
|
||||||
to_add = self._get_defaults_dict(k, v)
|
to_add = self._get_defaults_dict(k, v)
|
||||||
self._update_defaults(to_add, self.defaults[key])
|
self._update_defaults(to_add, self._defaults[key])
|
||||||
|
|
||||||
def register_global(self, **kwargs):
|
def register_global(self, **kwargs):
|
||||||
"""
|
"""
|
||||||
@ -497,7 +543,7 @@ class Config:
|
|||||||
|
|
||||||
You can also now register nested values::
|
You can also now register nested values::
|
||||||
|
|
||||||
defaults = {
|
_defaults = {
|
||||||
"foo": {
|
"foo": {
|
||||||
"bar": True,
|
"bar": True,
|
||||||
"baz": False
|
"baz": False
|
||||||
@ -506,10 +552,10 @@ class Config:
|
|||||||
|
|
||||||
# Will register `foo.bar` == True and `foo.baz` == False
|
# Will register `foo.bar` == True and `foo.baz` == False
|
||||||
conf.register_global(
|
conf.register_global(
|
||||||
**defaults
|
**_defaults
|
||||||
)
|
)
|
||||||
|
|
||||||
You can do the same thing without a :python:`defaults` dict by using double underscore as a variable
|
You can do the same thing without a :python:`_defaults` dict by using double underscore as a variable
|
||||||
name separator::
|
name separator::
|
||||||
|
|
||||||
# This is equivalent to the previous example
|
# This is equivalent to the previous example
|
||||||
@ -556,7 +602,7 @@ class Config:
|
|||||||
# noinspection PyTypeChecker
|
# noinspection PyTypeChecker
|
||||||
return group_class(
|
return group_class(
|
||||||
identifiers=(self.unique_identifier, key) + identifiers,
|
identifiers=(self.unique_identifier, key) + identifiers,
|
||||||
defaults=self.defaults.get(key, {}),
|
defaults=self._defaults.get(key, {}),
|
||||||
spawner=self.spawner,
|
spawner=self.spawner,
|
||||||
force_registration=self.force_registration
|
force_registration=self.force_registration
|
||||||
)
|
)
|
||||||
|
|||||||
@ -43,16 +43,28 @@ API Reference
|
|||||||
|
|
||||||
.. automodule:: core.config
|
.. automodule:: core.config
|
||||||
|
|
||||||
|
Config
|
||||||
|
^^^^^^
|
||||||
|
|
||||||
.. autoclass:: Config
|
.. autoclass:: Config
|
||||||
:members:
|
:members:
|
||||||
|
|
||||||
|
Group
|
||||||
|
^^^^^
|
||||||
|
|
||||||
.. autoclass:: Group
|
.. autoclass:: Group
|
||||||
:members:
|
:members:
|
||||||
:special-members:
|
:special-members:
|
||||||
|
|
||||||
|
MemberGroup
|
||||||
|
^^^^^^^^^^^
|
||||||
|
|
||||||
.. autoclass:: MemberGroup
|
.. autoclass:: MemberGroup
|
||||||
:members:
|
:members:
|
||||||
|
|
||||||
|
Value
|
||||||
|
^^^^^
|
||||||
|
|
||||||
.. autoclass:: Value
|
.. autoclass:: Value
|
||||||
:members:
|
:members:
|
||||||
:special-members: __call__
|
:special-members: __call__
|
||||||
|
|||||||
@ -69,7 +69,7 @@ Repo Manager
|
|||||||
:members:
|
:members:
|
||||||
|
|
||||||
Exceptions
|
Exceptions
|
||||||
^^^^^^
|
^^^^^^^^^^
|
||||||
|
|
||||||
.. automodule:: cogs.downloader.errors
|
.. automodule:: cogs.downloader.errors
|
||||||
:members:
|
:members:
|
||||||
|
|||||||
@ -37,7 +37,7 @@ def config(json_driver):
|
|||||||
unique_identifier=str(uuid.uuid4()),
|
unique_identifier=str(uuid.uuid4()),
|
||||||
driver_spawn=json_driver)
|
driver_spawn=json_driver)
|
||||||
yield conf
|
yield conf
|
||||||
conf.defaults = {}
|
conf._defaults = {}
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture()
|
@pytest.fixture()
|
||||||
@ -53,7 +53,7 @@ def config_fr(json_driver):
|
|||||||
force_registration=True
|
force_registration=True
|
||||||
)
|
)
|
||||||
yield conf
|
yield conf
|
||||||
conf.defaults = {}
|
conf._defaults = {}
|
||||||
|
|
||||||
|
|
||||||
#region Dpy Mocks
|
#region Dpy Mocks
|
||||||
|
|||||||
@ -242,7 +242,7 @@ async def test_membergroup_allguilds(config, empty_member):
|
|||||||
async def test_membergroup_allmembers(config, empty_member):
|
async def test_membergroup_allmembers(config, empty_member):
|
||||||
await config.member(empty_member).foo.set(False)
|
await config.member(empty_member).foo.set(False)
|
||||||
|
|
||||||
all_members = await config.member(empty_member).all()
|
all_members = await config.member(empty_member).all_from_kind()
|
||||||
assert str(empty_member.id) in all_members
|
assert str(empty_member.id) in all_members
|
||||||
|
|
||||||
|
|
||||||
@ -301,6 +301,10 @@ async def test_member_clear_all(config, member_factory):
|
|||||||
# Get All testing
|
# Get All testing
|
||||||
@pytest.mark.asyncio
|
@pytest.mark.asyncio
|
||||||
async def test_user_get_all_from_kind(config, user_factory):
|
async def test_user_get_all_from_kind(config, user_factory):
|
||||||
|
config.register_user(
|
||||||
|
foo=False,
|
||||||
|
bar=True
|
||||||
|
)
|
||||||
for _ in range(5):
|
for _ in range(5):
|
||||||
user = user_factory.get()
|
user = user_factory.get()
|
||||||
await config.user(user).foo.set(True)
|
await config.user(user).foo.set(True)
|
||||||
@ -310,10 +314,23 @@ async def test_user_get_all_from_kind(config, user_factory):
|
|||||||
|
|
||||||
assert len(all_data) == 5
|
assert len(all_data) == 5
|
||||||
|
|
||||||
|
for _, v in all_data.items():
|
||||||
|
assert v['foo'] is True
|
||||||
|
assert v['bar'] is True
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.asyncio
|
@pytest.mark.asyncio
|
||||||
async def test_user_getalldata(config, user_factory):
|
async def test_user_getalldata(config, user_factory):
|
||||||
user = user_factory.get()
|
user = user_factory.get()
|
||||||
|
config.register_user(
|
||||||
|
foo=True,
|
||||||
|
bar=False
|
||||||
|
)
|
||||||
await config.user(user).foo.set(False)
|
await config.user(user).foo.set(False)
|
||||||
|
|
||||||
assert "foo" in await config.user(user).all()
|
all_data = await config.user(user).all()
|
||||||
|
|
||||||
|
assert "foo" in all_data
|
||||||
|
assert "bar" in all_data
|
||||||
|
|
||||||
|
assert config.user(user).defaults['foo'] is True
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user