Repository: Pycord-Development/pycord

Issue:
TypeError: 'tuple' object is not callable when a channel is provided as a slash command option. (2.0.0b7)
### Summary

Error in core.py when specifying a type of channel as a slash command option.

### Reproduction Steps

1. Create a slash command with an option parameter of type discord.TextChannel or discord.VoiceChannel.
2. Attempt to run the slash command and the error will occur.

### Minimal Reproducible Code

```python
@slash_command(guild_ids=globals.COMMAND_GUILD_ID_REGISTER_LIST)
async def testing(self, ctx, chan: Option(discord.TextChannel, "Specify channel:")):
    pass
```


### Expected Results

The code would run and I would have access to the channel object as the "chan" parameter, as per the example.

### Actual Results

Crash with traceback:

Traceback (most recent call last):
  File "c:\Users\Tiffany\dev\pycord-bot-testing\venv\lib\site-packages\discord\commands\core.py", line 122, in wrapped
    ret = await coro(arg)
  File "c:\Users\Tiffany\dev\pycord-bot-testing\venv\lib\site-packages\discord\commands\core.py", line 810, in _invoke
    arg = obj_type(state=ctx.interaction._state, data=_data, **kw)
TypeError: 'tuple' object is not callable

### Intents

All

### System Information

- Python v3.9.2-final
- py-cord v2.0.0-beta
    - py-cord pkg_resources: v2.0.0b7
- aiohttp v3.8.1
- system info: Windows 8.1 6.3.9600

### Checklist

- [X] I have searched the open issues for duplicates.
- [X] I have shown the entire traceback, if possible.
- [X] I have removed my token from display, if visible.

### Additional Context

Commands were previously working fine in any version under py-cord 2.0.0b6.


Discussion:
I have the same issue. 

`async def gwstart_cmd(self, ctx: discord.ApplicationContext, channel: Option(discord.TextChannel, 'channel type is broken')`

Resolving patch:
diff --git a/discord/channel.py b/discord/channel.py
--- a/discord/channel.py
+++ b/discord/channel.py
@@ -130,9 +130,9 @@ class TextChannel(discord.abc.Messageable, discord.abc.GuildChannel, Hashable):
         The category channel ID this channel belongs to, if applicable.
     topic: Optional[:class:`str`]
         The channel's topic. ``None`` if it doesn't exist.
-    position: :class:`int`
+    position: Optional[:class:`int`]
         The position in the channel list. This is a number that starts at 0. e.g. the
-        top channel is position 0.
+        top channel is position 0. Can be ``None`` if the channel was recieved in an interaction.
     last_message_id: Optional[:class:`int`]
         The last message ID of the message sent to this channel. It may
         *not* point to an existing or valid message.
@@ -192,7 +192,7 @@ def _update(self, guild: Guild, data: TextChannelPayload) -> None:
         self.name: str = data["name"]
         self.category_id: Optional[int] = utils._get_as_snowflake(data, "parent_id")
         self.topic: Optional[str] = data.get("topic")
-        self.position: int = data["position"]
+        self.position: int = data.get("position")
         self.nsfw: bool = data.get("nsfw", False)
         # Does this need coercion into `int`? No idea yet.
         self.slowmode_delay: int = data.get("rate_limit_per_user", 0)
@@ -816,7 +816,7 @@ def _update(self, guild: Guild, data: Union[VoiceChannelPayload, StageChannelPay
         self.video_quality_mode: VideoQualityMode = try_enum(VideoQualityMode, data.get("video_quality_mode", 1))
         self.category_id: Optional[int] = utils._get_as_snowflake(data, "parent_id")
         self.last_message_id: Optional[int] = utils._get_as_snowflake(data, 'last_message_id')
-        self.position: int = data["position"]
+        self.position: int = data.get("position")
         self.bitrate: int = data.get("bitrate")
         self.user_limit: int = data.get("user_limit")
         self._fill_overwrites(data)
@@ -902,9 +902,9 @@ class VoiceChannel(discord.abc.Messageable, VocalGuildChannel):
         The channel ID.
     category_id: Optional[:class:`int`]
         The category channel ID this channel belongs to, if applicable.
-    position: :class:`int`
+    position: Optional[:class:`int`]
         The position in the channel list. This is a number that starts at 0. e.g. the
-        top channel is position 0.
+        top channel is position 0. Can be ``None`` if the channel was recieved in an interaction.
     bitrate: :class:`int`
         The channel's preferred audio bitrate in bits per second.
     user_limit: :class:`int`
@@ -1374,9 +1374,9 @@ class StageChannel(VocalGuildChannel):
         The channel's topic. ``None`` if it isn't set.
     category_id: Optional[:class:`int`]
         The category channel ID this channel belongs to, if applicable.
-    position: :class:`int`
+    position: Optional[:class:`int`]
         The position in the channel list. This is a number that starts at 0. e.g. the
-        top channel is position 0.
+        top channel is position 0. Can be ``None`` if the channel was recieved in an interaction.
     bitrate: :class:`int`
         The channel's preferred audio bitrate in bits per second.
     user_limit: :class:`int`
@@ -1651,9 +1651,9 @@ class CategoryChannel(discord.abc.GuildChannel, Hashable):
         The guild the category belongs to.
     id: :class:`int`
         The category channel ID.
-    position: :class:`int`
+    position: Optional[:class:`int`]
         The position in the category list. This is a number that starts at 0. e.g. the
-        top category is position 0.
+        top category is position 0. Can be ``None`` if the channel was recieved in an interaction.
     nsfw: :class:`bool`
         If the channel is marked as "not safe for work".
 
@@ -1686,7 +1686,7 @@ def _update(self, guild: Guild, data: CategoryChannelPayload) -> None:
         self.name: str = data["name"]
         self.category_id: Optional[int] = utils._get_as_snowflake(data, "parent_id")
         self.nsfw: bool = data.get("nsfw", False)
-        self.position: int = data["position"]
+        self.position: int = data.get("position")
         self._fill_overwrites(data)
 
     @property
diff --git a/discord/commands/core.py b/discord/commands/core.py
--- a/discord/commands/core.py
+++ b/discord/commands/core.py
@@ -803,7 +803,7 @@ async def _invoke(self, ctx: ApplicationContext) -> None:
                         obj_type = Role
                         kw["guild"] = ctx.guild
                     elif op.input_type is SlashCommandOptionType.channel:
-                        obj_type = _guild_channel_factory(_data["type"])
+                        obj_type = _guild_channel_factory(_data["type"])[0]
                         kw["guild"] = ctx.guild
                     elif op.input_type is SlashCommandOptionType.attachment:
                         obj_type = Attachment


Test patch: