Repository: Pycord-Development/pycord

Issue:
Fetch_guild getting with_counts
### Summary

This basically adds the ability to correctly get prescence_count

### What is the feature request for?

The core library

### The Problem

The problem is that you can't do this on the guild object itself(and to add stuff that doesn't exist in guild stuff)

### The Ideal Solution

I would like this fork to be able to get prescence_count, the new member_count at the time, and of course other guild information

having a fetch_guild with the prescence_count and member_count as a part of the guild object, otherwise normal get would have prescence_count None, and member_count would be the most updated(it also doesn't require intents to get all the users online, you can't always get intents either. Discord would probaly like it even more if you added this)
and being able to get with_counts on many guilds with fetch_guilds.


### The Current Solution

The current one is to fetch the invite(which as we know we don't always have permissions to make, and not all guilds have vanity urls), but even so you should only have to be able to use fetch_guild or fetch_guilds.

for example now you need to have an invite object to get the prescence count, and an accurate member_count.

### Additional Context

_No response_


Discussion:
Could you elaborate on this?
Discord.py was missing the option to grab prescence data(a.k.a those who are not offline), except by invites, the with_counts has it fetch via fetch__guild which is much better than getting it on invite.

Resolving patch:
diff --git a/discord/client.py b/discord/client.py
--- a/discord/client.py
+++ b/discord/client.py
@@ -1196,7 +1196,7 @@ async def fetch_template(self, code: Union[Template, str]) -> Template:
         data = await self.http.get_template(code)
         return Template(data=data, state=self._connection) # type: ignore
 
-    async def fetch_guild(self, guild_id: int, /) -> Guild:
+    async def fetch_guild(self, guild_id: int, /, *, with_counts=True) -> Guild:
         """|coro|
 
         Retrieves a :class:`.Guild` from an ID.
@@ -1215,6 +1215,12 @@ async def fetch_guild(self, guild_id: int, /) -> Guild:
         guild_id: :class:`int`
             The guild's ID to fetch from.
 
+        with_counts: :class:`bool`
+            Whether to include count information in the guild. This fills the
+            :attr:`.Guild.approximate_member_count` and :attr:`.Guild.approximate_presence_count`
+            fields.
+
+            .. versionadded:: 2.0
         Raises
         ------
         :exc:`.Forbidden`
@@ -1227,7 +1233,7 @@ async def fetch_guild(self, guild_id: int, /) -> Guild:
         :class:`.Guild`
             The guild from the ID.
         """
-        data = await self.http.get_guild(guild_id)
+        data = await self.http.get_guild(guild_id, with_counts = with_counts)
         return Guild(data=data, state=self._connection)
 
     async def create_guild(
diff --git a/discord/guild.py b/discord/guild.py
--- a/discord/guild.py
+++ b/discord/guild.py
@@ -252,6 +252,20 @@ class Guild(Hashable):
     nsfw_level: :class:`NSFWLevel`
         The guild's NSFW level.
 
+        .. versionadded:: 2.0
+        
+    approximate_member_count: Optional[:class:`int`]
+        The approximate number of members in the guild. This is ``None`` unless the guild is obtained
+        using :meth:`Client.fetch_guild` with ``with_counts=True``.
+
+        .. versionadded:: 2.0
+        
+    approximate_presence_count: Optional[:class:`int`]
+        The approximate number of members currently active in the guild.
+        This includes idle, dnd, online, and invisible members. Offline members are excluded.
+        This is ``None`` unless the guild is obtained using :meth:`Client.fetch_guild`
+        with ``with_counts=True``.
+
         .. versionadded:: 2.0
     """
 
@@ -296,6 +310,8 @@ class Guild(Hashable):
         '_public_updates_channel_id',
         '_stage_instances',
         '_threads',
+        "approximate_member_count",
+        "approximate_presence_count",
     )
 
     _PREMIUM_GUILD_LIMITS: ClassVar[Dict[Optional[int], _GuildLimit]] = {
@@ -464,6 +480,8 @@ def _from_data(self, guild: GuildPayload) -> None:
         self._rules_channel_id: Optional[int] = utils._get_as_snowflake(guild, 'rules_channel_id')
         self._public_updates_channel_id: Optional[int] = utils._get_as_snowflake(guild, 'public_updates_channel_id')
         self.nsfw_level: NSFWLevel = try_enum(NSFWLevel, guild.get('nsfw_level', 0))
+        self.approximate_presence_count = guild.get('approximate_presence_count')
+        self.approximate_member_count = guild.get('approximate_member_count')
 
         self._stage_instances: Dict[int, StageInstance] = {}
         for s in guild.get('stage_instances', []):
diff --git a/discord/http.py b/discord/http.py
--- a/discord/http.py
+++ b/discord/http.py
@@ -1100,8 +1100,9 @@ def get_guilds(
     def leave_guild(self, guild_id: Snowflake) -> Response[None]:
         return self.request(Route('DELETE', '/users/@me/guilds/{guild_id}', guild_id=guild_id))
 
-    def get_guild(self, guild_id: Snowflake) -> Response[guild.Guild]:
-        return self.request(Route('GET', '/guilds/{guild_id}', guild_id=guild_id))
+    def get_guild(self, guild_id: Snowflake, *, with_counts = True) -> Response[guild.Guild]:
+        params = {'with_counts': int(with_counts)}
+        return self.request(Route('GET', '/guilds/{guild_id}', guild_id=guild_id), params=params)
 
     def delete_guild(self, guild_id: Snowflake) -> Response[None]:
         return self.request(Route('DELETE', '/guilds/{guild_id}', guild_id=guild_id))


Test patch: