Discord.py: Messages aren't hashable

Created on 29 Sep 2020  路  9Comments  路  Source: Rapptz/discord.py

Summary

The Message type is not hashable.

Reproduction Steps

Get a message object and try to hash it

Expected Results

The message should have a hash, which would be the value of the guild, user/member sending it, and the message ID itself.

Actual Results

TypeError: unhashable type: 'Message'

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.

System Information


  • Python v3.8.5-final
  • discord.py v1.5.0-final
  • aiohttp v3.6.2
  • system info: Darwin 19.6.0 Darwin Kernel Version 19.6.0: Thu Jun 18 20:49:00 PDT 2020; root:xnu-6153.141.1~1/RELEASE_X86_64
bug

Most helpful comment

Unlike other classes which were deliberately documented as having a hash (see: member, guild, role ...) message was not ever documented as such. If it's intended to be hashable, this was not documented. The reason it stopped being hashable was adding an equality comparison without adding a hash (by default in python, if you implement neither, you get object identity as equality and a hash which is based on the same)

All 9 comments

discord.Message being an unhashable type is not a bug. Please change this issue to a feature request if you so wish it to be.

discord.Message being an unhashable type is _not a bug_. Please change this issue to a feature request if you so wish it to be.

It used to be hashable in V1.4. Also how do I change the bug report into a feature request?

I know this is not a solution, just a workaround, but you can hash message.jump_url instead, since the jump_url contains guild, channel and message ID and therefore is unique for every message

Unlike other classes which were deliberately documented as having a hash (see: member, guild, role ...) message was not ever documented as such. If it's intended to be hashable, this was not documented. The reason it stopped being hashable was adding an equality comparison without adding a hash (by default in python, if you implement neither, you get object identity as equality and a hash which is based on the same)

I think making messages hashable and documenting them as such would be a good idea since every message is unique.

I'd agree with @MvonK about using the guild, channel and message ID for a message to implement the hash, except I think using a tuple of the three would be a nicer solution for writing the hash of the object.

If needed, we can even include the message content in the tuple, since that would allow us to differentiate an edited message from its original counterpart using the hash.

Of course, we could stick with the guild, channel, and message ID tuple for simplicity, but including the editable properties could also provide some interesting behavior to the hash.

Comments?

I think making messages hashable and documenting them as such would be a good idea since every message is unique.

I'd agree with @MvonK about using the guild, channel and message ID for a message to implement the hash, except I think using a tuple of the three would be a nicer solution for writing the hash of the object.

If needed, we can even include the message content in the tuple, since that would allow us to differentiate an edited message from its original counterpart using the hash.

Of course, we could stick with the guild, channel, and message ID tuple for simplicity, but including the editable properties could also provide some interesting behavior to the hash.

Comments?

I took a good look at the __eq__ method, and it doesn't account for message content, so the hashing algo shouldn't either. But this could lead to issues storing multiple versions of the same message, so that should be addressed as well. I'll open a PR with appropriate code.

Why not use class Message(Hashable)?

Why not use class Message(Hashable)?

There's a Hash mixin? This is news to me

I had this error due to the new 'intent' implementation.
Just hash the messages' id instead of the message itself and retrieve them using fetch_message if you need to.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

tairabiteru picture tairabiteru  路  3Comments

reuscam picture reuscam  路  3Comments

synbitz picture synbitz  路  3Comments

danshat picture danshat  路  3Comments

jzburda picture jzburda  路  3Comments