Rapptz / discord.py

An API wrapper for Discord written in Python.
http://discordpy.rtfd.org/en/latest
MIT License
14.84k stars 3.76k forks source link

[v2] Possible TypeError Exception Upon Message Class Instantiation #8222

Closed ThorntonMatthewD closed 2 years ago

ThorntonMatthewD commented 2 years ago

Summary

Upon instantiating an instance of the Message class, if the value of application is None within the MessagePayload the constructor receives, it will cause a TypeError to be thrown whenever an instance of MessageApplication is later created.

Reproduction Steps

I am attempting to port a testing library over to being compatible with the upcoming v2.0 release. I don't have all of the "plumbing" in place yet, however I did come across the following scenario:

I instantiate an instance of discord.Message without providing an instance of MessageApplication to the constructor. There exists within my MessagePayload a key named application with a value of None. This is placed into a local application variable here: https://github.com/Rapptz/discord.py/blob/1aaa32d4bced65d346f0634984c95a707bf0c00b/discord/message.py#L1516

Below, whenever an instance of MessageApplication is created, this None value is passed in as the data param: https://github.com/Rapptz/discord.py/blob/1aaa32d4bced65d346f0634984c95a707bf0c00b/discord/message.py#L1520

In the constructor for MessageApplication, any data['...'] call will throw the following error: TypeError: 'NoneType' object is not subscriptable

https://github.com/Rapptz/discord.py/blob/1aaa32d4bced65d346f0634984c95a707bf0c00b/discord/message.py#L634

Minimal Reproducible Code

No response

Expected Results

I'm not entirely sure what the best tactic would be here to mitigate this, but I guess I'd expect a check for if application == None before proceeding with creating the MessageApplication object.

Actual Results

I received the following exception: TypeError: 'NoneType' object is not subscriptable

The full pytest exception traceback:

Traceback (most recent call last):
  File "/home/matt/.local/share/virtualenvs/bot-detector-discord-bot--Gx7yMoQ/src/discord-py/discord/ext/commands/core.py", line 200, in wrapped
    ret = await coro(*args, **kwargs)
  File "/home/matt/Programming/python/bot-detector-discord-bot/src/cogs/fun_commands.py", line 54, in poke
    await ctx.reply(embed=embed)
  File "/home/matt/.local/share/virtualenvs/bot-detector-discord-bot--Gx7yMoQ/src/discord-py/discord/ext/commands/context.py", line 648, in reply
    return await self.send(content, reference=self.message, **kwargs)
  File "/home/matt/.local/share/virtualenvs/bot-detector-discord-bot--Gx7yMoQ/src/discord-py/discord/ext/commands/context.py", line 841, in send
    return await super().send(
  File "/home/matt/.local/share/virtualenvs/bot-detector-discord-bot--Gx7yMoQ/src/discord-py/discord/abc.py", line 1540, in send
    ret = state.create_message(channel=channel, data=data)
  File "/home/matt/.local/share/virtualenvs/bot-detector-discord-bot--Gx7yMoQ/src/discord-py/discord/state.py", line 1580, in create_message
    return Message(state=self, channel=channel, data=data)
  File "/home/matt/.local/share/virtualenvs/bot-detector-discord-bot--Gx7yMoQ/src/discord-py/discord/message.py", line 1523, in __init__
    self.application = MessageApplication(state=self._state, data=application)
  File "/home/matt/.local/share/virtualenvs/bot-detector-discord-bot--Gx7yMoQ/src/discord-py/discord/message.py", line 635, in __init__
    self.id: int = int(data['id'])
TypeError: 'NoneType' object is not subscriptable

This is the MessagePayload that causes the error to occur:

{'id': 995858766438203397, 'author': {'id': 995858763653185536, 'username': 'FakeApp', 'discriminator': '0001', 'avatar': None, 'bot': True}, 'mentions': [], 'mention_roles': [], 'mention_channels': [], 'edited_timestamp': None, 'embeds': [{'fields': [{'inline': False, 'name': 'Teehee', 'value': ':3'}, {'inline': False, 'name': 'Discord Ping:', 'value': 'inf ms'}, {'inline': False, 'name': 'BD API Status:', 'value': 'Online'}], 'color': 255, 'type': 'rich'}], 'attachments': [], 'content': '', 'pinned': False, 'application': None, 'activity': None, 'mention_everyone': False, 'tts': False, 'type': <MessageType.default: 0>, 'nonce': None}

Intents

messages=True, guilds=True, members=True, reactions=True, message_content=True

System Information

> python -m discord -v
- Python v3.10.5-final
- discord.py v2.0.0-alpha
    - discord.py pkg_resources: v2.0.0a4403+g1aaa32d4
- aiohttp v3.8.1
- system info: Linux 5.18.10-arch1-1 #1 SMP PREEMPT_DYNAMIC Thu, 07 Jul 2022 17:18:13 +0000

Checklist

Additional Context

I am experiencing this issue while running pytest and also while utilizing the dpytest library to help facilitate writing a test for a command, so it's a bit of an odd situation.

AbstractUmbra commented 2 years ago

This isn't a bug with discord.py. Our classes are not designed to be user constructable, which includes discord.Message.

Your error is that you're providing None where an actual json payload is expected, with certain mandatory keys. You'll need to mock a minimal acceptable version of this payload.

As this is not a bug with the library, you're more than welcome to join the official help server and talk about this more there.

Rapptz commented 2 years ago

Is this a payload received by Discord or is it a synthetic payload you made? The library doesn't support creating instances of the classes by hand.

ThorntonMatthewD commented 2 years ago

Thank you both for your responses! This is a synthetic payload being generated by a library used for helping with creating mocks for use with dpy bots in pytest. Since a required parameter being missing is not a scenario that would occur outside of meddling like my own in this case then I retract this issue. Thank you for your help! :)

Rapptz commented 2 years ago

FWIW you can omit the key instead of giving it a value of None.

ThorntonMatthewD commented 2 years ago

FWIW you can omit the key instead of giving it a value of None.

Thank you so much! I've just given this a shot, and it's working like a charm now. One more issue down! 🥳