Use a metaclass for config's singletons (#3137)

* Usea metaclass for config's singletons

* make this a little safer
This commit is contained in:
Michael H 2020-02-28 15:37:35 -05:00 committed by GitHub
parent eedec4ff02
commit f6361992e3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -30,6 +30,33 @@ _config_cache = weakref.WeakValueDictionary()
_retrieved = weakref.WeakSet()
class ConfigMeta(type):
"""
We want to prevent re-initializing existing config instances while having a singleton
"""
def __call__(
cls,
cog_name: str,
unique_identifier: str,
driver: BaseDriver,
force_registration: bool = False,
defaults: dict = None,
):
if cog_name is None:
raise ValueError("You must provide either the cog instance or a cog name.")
key = (cog_name, unique_identifier)
if key in _config_cache:
return _config_cache[key]
instance = super(ConfigMeta, cls).__call__(
cog_name, unique_identifier, driver, force_registration, defaults
)
_config_cache[key] = instance
return instance
def get_latest_confs() -> Tuple["Config"]:
global _retrieved
ret = set(_config_cache.values()) - set(_retrieved)
@ -562,7 +589,7 @@ class Group(Value):
await self.driver.set(identifier_data, value=value)
class Config:
class Config(metaclass=ConfigMeta):
"""Configuration manager for cogs and Red.
You should always use `get_conf` to instantiate a Config object. Use
@ -605,19 +632,6 @@ class Config:
USER = "USER"
MEMBER = "MEMBER"
def __new__(cls, cog_name, unique_identifier, *args, **kwargs):
key = (cog_name, unique_identifier)
if key[0] is None:
raise ValueError("You must provide either the cog instance or a cog name.")
if key in _config_cache:
conf = _config_cache[key]
else:
conf = object.__new__(cls)
_config_cache[key] = conf
return conf
def __init__(
self,
cog_name: str,
@ -893,10 +907,10 @@ class Config:
"""
Initializes a custom group for usage. This method must be called first!
"""
if group_identifier in self.custom_groups:
raise ValueError(f"Group identifier already registered: {group_identifier}")
self.custom_groups[group_identifier] = identifier_count
if identifier_count != self.custom_groups.setdefault(group_identifier, identifier_count):
raise ValueError(
f"Cannot change identifier count of already registered group: {group_identifier}"
)
def _get_base_group(self, category: str, *primary_keys: str) -> Group:
"""