diff --git a/docs/framework_config.rst b/docs/framework_config.rst index 1d33a7d63..3837d9915 100644 --- a/docs/framework_config.rst +++ b/docs/framework_config.rst @@ -187,6 +187,7 @@ This usage guide will cover the following features: - :py:meth:`Group.get_raw` - :py:meth:`Group.set_raw` +- :py:meth:`Group.clear_raw` For this example let's suppose that we're creating a cog that allows users to buy and own multiple pets using the built-in Economy credits:: @@ -290,6 +291,37 @@ We're responsible pet owners here, so we've also got to have a way to feed our p await ctx.send("Your pet is now at {}/100 hunger!".format(new_hunger) +Of course, if we're less than responsible pet owners, there are consequences:: + + #continued + @commands.command() + async def adopt(self, ctx, pet_name: str, *, member: discord.Member): + try: + pet = await self.conf.user(member).pets.get_raw(pet_name) + except KeyError: + await ctx.send("That person doesn't own that pet!") + return + + hunger = pet.get("hunger") + if hunger < 80: + await ctx.send("That pet is too well taken care of to be adopted.") + return + + await self.conf.user(member).pets.clear_raw(pet_name) + + # this is equivalent to doing the following + + pets = await self.conf.user(member).pets() + del pets[pet_name] + await self.conf.user(member).pets.set(pets) + + await self.conf.user(ctx.author).pets.set_raw(pet_name, value=pet) + await ctx.send( + "Your request to adopt this pet has been granted due to " + "how poorly it was taken care of." + ) + + ************* V2 Data Usage ************* diff --git a/redbot/core/config.py b/redbot/core/config.py index c0b411666..bd3226115 100644 --- a/redbot/core/config.py +++ b/redbot/core/config.py @@ -238,6 +238,29 @@ class Group(Value): else: return Value(identifiers=new_identifiers, default_value=None, driver=self.driver) + async def clear_raw(self, *nested_path: str): + """ + Allows a developer to clear data as if it was stored in a standard + Python dictionary. + + For example:: + + await conf.clear_raw("foo", "bar") + + # is equivalent to + + data = {"foo": {"bar": None}} + del data["foo"]["bar"] + + Parameters + ---------- + nested_path : str + Multiple arguments that mirror the arguments passed in for nested + dict access. + """ + path = [str(p) for p in nested_path] + await self.driver.clear(*self.identifiers, *path) + def is_group(self, item: str) -> bool: """A helper method for `__getattr__`. Most developers will have no need to use this. diff --git a/tests/core/test_config.py b/tests/core/test_config.py index c333201e0..abfafd8f2 100644 --- a/tests/core/test_config.py +++ b/tests/core/test_config.py @@ -224,6 +224,15 @@ async def test_set_dynamic_attr(config): assert await config.foobar() is True +@pytest.mark.asyncio +async def test_clear_dynamic_attr(config): + await config.foo.set(True) + await config.clear_raw("foo") + + with pytest.raises(KeyError): + await config.get_raw("foo") + + @pytest.mark.asyncio async def test_get_dynamic_attr(config): assert await config.get_raw("foobaz", default=True) is True