Repository: Cog-Creators/Red-DiscordBot

Issue:
Config *_from_id(s) methods not typechecking.
### What Red version are you using?

3.4.14

### What were you trying to do?

Trying to access a guild's data from config using the `Config.guild_from_id()` method but accidentally passed in a guild object instead of its id.

### What did you expect to happen?

An error or exception to raise that indicated that my passed value wasn't of type int.

### What actually happened?

The `Config.guild_from_id()` method took the guild object and casted it to a string which turned into the guild's name and upon bot restart, errors were raised about it not being of base 10 for int casting when using the `Config.all_guilds()` method in a cog's initialization

### How can we reproduce this error?

1. Use the `Config.guild_from_id()` method but instead of an integer id, pass a proper guild object.
2. Restart the bot and call the `Config.all_guilds()` method in a cog.


### Anything else?

I'll be happy to push a pr fix for this if needed


Discussion:
Though generally we expect inputs to be the correct type without explicit checking, since in this case it has the potential to easily break a config file, I'd say there probably should be some explicit type checking. Feel free to PR a fix if you feel comfortable doing so.

Resolving patch:
diff --git a/redbot/core/config.py b/redbot/core/config.py
--- a/redbot/core/config.py
+++ b/redbot/core/config.py
@@ -956,7 +956,13 @@ def guild_from_id(self, guild_id: int) -> Group:
         `Group <redbot.core.config.Group>`
             The guild's Group object.
 
+        Raises
+        ------
+        TypeError
+            If the given guild_id parameter is not of type int
         """
+        if type(guild_id) is not int:
+            raise TypeError(f"guild_id should be of type int, not {guild_id.__class__.__name__}")
         return self._get_base_group(self.GUILD, str(guild_id))
 
     def guild(self, guild: discord.Guild) -> Group:
@@ -990,7 +996,15 @@ def channel_from_id(self, channel_id: int) -> Group:
         `Group <redbot.core.config.Group>`
             The channel's Group object.
 
+        Raises
+        ------
+        TypeError
+            If the given channel_id parameter is not of type int
         """
+        if type(channel_id) is not int:
+            raise TypeError(
+                f"channel_id should be of type int, not {channel_id.__class__.__name__}"
+            )
         return self._get_base_group(self.CHANNEL, str(channel_id))
 
     def channel(self, channel: discord.abc.GuildChannel) -> Group:
@@ -1024,7 +1038,13 @@ def role_from_id(self, role_id: int) -> Group:
         `Group <redbot.core.config.Group>`
             The role's Group object.
 
+        Raises
+        ------
+        TypeError
+            If the given role_id parameter is not of type int
         """
+        if type(role_id) is not int:
+            raise TypeError(f"role_id should be of type int, not {role_id.__class__.__name__}")
         return self._get_base_group(self.ROLE, str(role_id))
 
     def role(self, role: discord.Role) -> Group:
@@ -1056,7 +1076,13 @@ def user_from_id(self, user_id: int) -> Group:
         `Group <redbot.core.config.Group>`
             The user's Group object.
 
+        Raises
+        ------
+        TypeError
+            If the given user_id parameter is not of type int
         """
+        if type(user_id) is not int:
+            raise TypeError(f"user_id should be of type int, not {user_id.__class__.__name__}")
         return self._get_base_group(self.USER, str(user_id))
 
     def user(self, user: discord.abc.User) -> Group:
@@ -1090,7 +1116,17 @@ def member_from_ids(self, guild_id: int, member_id: int) -> Group:
         `Group <redbot.core.config.Group>`
             The member's Group object.
 
+        Raises
+        ------
+        TypeError
+            If the given guild_id or member_id parameter is not of type int
         """
+        if type(guild_id) is not int:
+            raise TypeError(f"guild_id should be of type int, not {guild_id.__class__.__name__}")
+
+        if type(member_id) is not int:
+            raise TypeError(f"member_id should be of type int, not {member_id.__class__.__name__}")
+
         return self._get_base_group(self.MEMBER, str(guild_id), str(member_id))
 
     def member(self, member: discord.Member) -> Group:


Test patch: