Repository: Pycord-Development/pycord

Issue:
TypeError when editing a fetched message from a partial webhook
### Summary

When editing a message that was fetched by a partial webhook, it fails with a TypeError.

### Reproduction Steps

1. Create a partial webhook
2. Send a message and store the resulting WebhookMessage object
3. Re-fetch the message using `fetch_message()`
4. Attempt to edit the message

### Minimal Reproducible Code

```python
import asyncio
import aiohttp
import discord

async def main():
    async with aiohttp.ClientSession() as session:
        webhook = discord.Webhook.partial(1234, "token", session=session)
        message = await webhook.send("Hello world!", wait=True)
        message = await webhook.fetch_message(message.id)
        await message.edit(content="A whole new world!")

asyncio.run(main())
```


### Expected Results

The message should have been edited.

### Actual Results

The message is not edited, and the following error is raised:

```py
Traceback (most recent call last):
  File "main.py", line 16, in <module>
    asyncio.run(main())
  File "..\Python311\Lib\asyncio\runners.py", line 190, in run
    return runner.run(main)
           ^^^^^^^^^^^^^^^^
  File "..\Python311\Lib\asyncio\runners.py", line 118, in run
    return self._loop.run_until_complete(task)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "..\Python311\Lib\asyncio\base_events.py", line 653, in run_until_complete
    return future.result()
           ^^^^^^^^^^^^^^^
  File "main.py", line 14, in main
    await message.edit(content="A whole new world!")
  File "..\.venv\Lib\site-packages\discord\webhook\async_.py", line 892, in edit
    thread = Object(self._thread_id)
             ^^^^^^^^^^^^^^^^^^^^^^^
  File "..\.venv\Lib\site-packages\discord\object.py", line 77, in __init__
    id = int(id)
         ^^^^^^^
TypeError: int() argument must be a string, a bytes-like object or a real number, not 'NoneType'
```

### Intents

N/A

### System Information

```
..\.venv\Lib\site-packages\discord\__main__.py:33: DeprecationWarning: pkg_resources is deprecated as an API. See https://setuptools.pypa.io/en/latest/pkg_resources.html
  import pkg_resources
- Python v3.11.7-final
- py-cord v2.4.1-final
- aiohttp v3.8.6
- system info: Windows 10 10.0.22631
```
(note: actual operating system is Windows 11)

### 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

Looking through the source code, it appears that this bug was introduced by https://github.com/Pycord-Development/pycord/commit/d56dc864bbf7f0910890ae5cb8a660720beff75f, where `WebhookMessage._thread_id` can be assigned None in `fetch_message()` while `WebhookMessage.edit()` assumes that the attribute can never be None.

https://github.com/Pycord-Development/pycord/blob/9d4d0f705c604c17661d916b5b43d37bc8e4013f/discord/webhook/async_.py#L1825-L1827

https://github.com/Pycord-Development/pycord/blob/9d4d0f705c604c17661d916b5b43d37bc8e4013f/discord/webhook/async_.py#L891-L892


Discussion:

Resolving patch:
diff --git a/discord/webhook/async_.py b/discord/webhook/async_.py
--- a/discord/webhook/async_.py
+++ b/discord/webhook/async_.py
@@ -1855,7 +1855,7 @@ async def fetch_message(
             thread_id=thread_id,
         )
         msg = self._create_message(data)
-        if isinstance(msg.channel, PartialMessageable):
+        if thread_id and isinstance(msg.channel, PartialMessageable):
             msg._thread_id = thread_id
 
         return msg
diff --git a/discord/webhook/sync.py b/discord/webhook/sync.py
--- a/discord/webhook/sync.py
+++ b/discord/webhook/sync.py
@@ -1147,7 +1147,7 @@ def fetch_message(
             thread_id=thread_id,
         )
         msg = self._create_message(data)
-        if isinstance(msg.channel, PartialMessageable):
+        if thread_id and isinstance(msg.channel, PartialMessageable):
             msg._thread_id = thread_id
 
         return msg


Test patch: