-
-
Notifications
You must be signed in to change notification settings - Fork 30k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
"TypeError: unhashable type" could often be more clear #85286
Comments
Currently, if you (for example) put a dict as a value in a set or key in a dict, you get: TypeError: unhashable type: 'dict' I'm pretty sure this wording goes back a long time, but I've noticed that Python beginners tend to find this really confusing. It fits into a pattern of error messages where you have to explain why the error message is worded the way it is after you explain why the error message occurs at all. There are many instances of: It would be clearer if the message was something like: TypeError: 'dict' can not be used as a set value because it is an unhashable type. (Or "dict key" instead of "set value".) The exception is raised in PyObject_Hash, so that doesn't have some of the context about how/why hash was called. That's called in a lot of places. Possibly, PyObject_Hash and PyObject_HashNotImplemented could take the format string passed to PyErr_Format as an optional second argument, defaulting to the current behavior? Then certain callers (in particular, the set and dict constructor, set and dict methods that add set values or add/modify dict keys) could provide clearer error messages. |
IMO that doesn't help. The trackback already shows the code where the exception occurred. The user already knows the calling type, and the existing message tells them what type was passed in. Their real problem is that they still have to confront the notion of what "unhashable type" means and then need figure-out a way to fix it. So the proposed extra information is just a distractor that doesn't get the user any closer to understanding or solving their problem. To get a user closer to the solution they would either need an explanation of what hashable means and/or be given a suggestion of how to fix it: TypeError: unhashable type: 'dict'. Consider using an int, That said, it is precarious to guess what the user intended, so it is difficult to suggest some form of "did you mean ..." |
Do you think it would help if the exception was of type UnhashableType (subclass of TypeError)? This would give the user a hint that this error is a thing which is worth looking for in the docs and understanding. |
That would not add more information. The message already says "unhashable type". Saying it twice doesn't help. |
The example I link to in the initial description appears to be one case where the user does not in fact know. I do think context that this restriction applies to dict key in particular is very relevant. The line could use the same type for both the key and the value in a dict assignment, for example.
That seems like a pretty reasonable wording, though I think mentioning "dictionary key" or "set item" specifically still helps. It could also link to the documentation directly: Though other error messages don't generally follow that pattern.
As the comment you were responding to noted, putting it in the type implies there might be additional information in documentation (or at least provides a place in documentation to put that information). TypeError is too general to say something about that specifically: |
No minor tweak to the exception message will make this go away. For understanding to occur, the only way to forward is to learn a bit about hashability. That is a step that every beginner must take. Fortunately, the term "hashable" is listed in the glossary. Also the error message itself is easily Googled: https://docs.python.org/3/glossary.html#term-hashable I suggest that you take this to the python-ideas list. While there is a valid concern that a new user may not understand the error message (this is unfortunately true for many our error messages), the proposals don't actually improve the situation. The first proposal adds hard-to-implement context information that still doesn't tell a user what the issue is. The second proposal repeats information that is already being shown. Neither proposal explains what is meant by unhashable type, why it matters, what would be an allowable hashable type, or how to fix the problem (which is what the user really wants to know). After a discussion on python-ideas, if a better proposal is found, feel free to reopen this issue. |
This is a derisive and beginner-hostile response that ignores half of what's been said by other participants in this thread.
Yeah, the first thing that comes up is ~4k Stack Overflow entries where people are really confused by the error message. |
I think it's reasonable to discuss the problem on python-ideas rather than on a bugs issue, when it's not obvious what the right solution is. |
I did start a thread there. Don't object to that, if that's a better forum for this sort of thing. |
python-ideas thread: https://mail.python.org/archives/list/python-ideas@python.org/thread/B6OMGYIM47OVGOCZLEY3MEUJDFURJRDV/ The most minimal ideas from that seem to be:
|
The problem is that you can't use a list as the key in a dict, since dict keys need to be immutable. This means that when you try to hash an unhashable object it will result an error. For ex. when you use a list as a key in the dictionary , this cannot be done because lists can't be hashed. The standard way to solve this issue is to cast a list to a tuple . TypeError: unhashable type: 'list' usually means that you are trying to use a list as an hash argument. The standard way to solve this issue is to cast a list to tuple. Though tuples may seem similar to lists, they are often used in different situations and for different purposes. Tuples can be used as keys if they contain only strings, numbers, or tuples; if a tuple contains any mutable object either directly or indirectly, it cannot be used as a key. You can’t use lists as key. |
Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.
Show more details
GitHub fields:
bugs.python.org fields:
The text was updated successfully, but these errors were encountered: