python / cpython

The Python programming language
https://www.python.org
Other
63.19k stars 30.26k forks source link

slice type is unhashable #45055

Closed 040a6c67-9f49-475c-a0fb-294ef5661fed closed 16 years ago

040a6c67-9f49-475c-a0fb-294ef5661fed commented 17 years ago
BPO 1733184
Nosy @gvanrossum, @rhettinger, @abalkin

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: ```python assignee = 'https://github.com/rhettinger' closed_at = created_at = labels = ['interpreter-core', 'type-feature'] title = 'slice type is unhashable' updated_at = user = 'https://bugs.python.org/lpd' ``` bugs.python.org fields: ```python activity = actor = 'gvanrossum' assignee = 'rhettinger' closed = True closed_date = closer = 'rhettinger' components = ['Interpreter Core'] creation = creator = 'lpd' dependencies = [] files = [] hgrepos = [] issue_num = 1733184 keywords = [] message_count = 14.0 messages = ['32255', '32256', '32257', '63375', '63379', '63380', '63381', '63384', '63400', '63402', '64418', '64425', '114630', '114632'] nosy_count = 5.0 nosy_names = ['gvanrossum', 'rhettinger', 'lpd', 'exarkun', 'belopolsky'] pr_nums = [] priority = 'normal' resolution = 'rejected' stage = None status = 'closed' superseder = None type = 'enhancement' url = 'https://bugs.python.org/issue1733184' versions = ['Python 2.5'] ```

040a6c67-9f49-475c-a0fb-294ef5661fed commented 17 years ago

Patch bpo-408326 is a "bug fix" that makes slice objects comparable but explicitly NOT hashable. I don't understand why Guido thinks this is the right behavior for them: they are immutable, have well-defined state, do not include references to mutable objects, and can be compared property for equality. Why shouldn't they be usable as dictionary keys? I have an application that really would like them to be usable as such. I know I can define a class Slice of my own .. but that seems so silly.

rhettinger commented 17 years ago

FWIW, you have a easy work-around. Use repr(yourslice) as the dictionary key.

040a6c67-9f49-475c-a0fb-294ef5661fed commented 17 years ago

I could probably live with that. However, there are other kinds of objects being used as keys in the same dictionary, and I can't just repr() them all, because it is not true that a == b implies repr(a) == repr(b). (E.g., a = 3, b = 3.0.)

Practicalities aside, it just seems silly to me that a simple type like slice should have all the prerequisites for being hashable and yet isn't, especially when much more complex types like methods are both comparable and hashable.

abalkin commented 16 years ago

Patch bpo-408326 was designed to make assignment to d[:] an error where d is a dictionary. See discussion starting at http://mail.python.org/pipermail/python-list/2001-March/072078.html .

I think the only reason slice objects need to be comparable is only to suppress inheritance of the default hash from object.

This RFE is ripe to be rejected. Slice objects are really meant to be internal structures and not passed around in the user's code. You can always use tuples instead of slices and convert the to slices with slice(*t) when needed.

rhettinger commented 16 years ago

Guido, any thoughts? I'm +0 on making slices hashable -- no real harm from doing it -- not much benefit either.

abalkin commented 16 years ago

In case I did not make my position clear in my previous post, I am -1 on this RFE. x[:] should mean slicing, not getitem.

8726d1eb-a365-45b6-b81d-c75988975e5a commented 16 years ago

Slice objects are really meant to be internal structures and not passed around in the user's code.

I don't know what they're "meant" to be, but they're certainly not internal. If you implement __getitem, __setitem, or __delitem__, then chances are Python is going to be passing slices to your code. That doesn't sound internal to me.

Having hashable slices is nice. The repr() workaround has a major drawback in that it makes it difficult to use the extremely useful "indices" method of the slice type.

gvanrossum commented 16 years ago

Alexander nailed my motivation.

Have the proponents for this change really thought through that making slices hashable means that henceforth this code will work?

d = {}
d[:] = [1, 2, 3]      # surprise here
print d               # prints {slice(None, None, None): [1, 2, 3]}
8726d1eb-a365-45b6-b81d-c75988975e5a commented 16 years ago

I don't see the ability to use a slice as a dict key as particularly more surprising than the ability to use ints as dict keys. Someone who doesn't understand how dicts work can use either of these features to write broken programs.

I have thought about that example and it's precisely the kind of thing I would like to work. The behavior is consistent with that of using any other immutable value as a key. I don't have a use case right now (and by admitting so may be dooming this change - but L. Peter Deutsch has one, I think) but there's no way I would ever benefit from the current behavior, whereas I _might_ be able to do something useful with the proposed behavior.

abalkin commented 16 years ago

Note that L[:] and L[:] = [] are well-known idioms for making a copy of a list and emptying the list respectively. (For dictionaries we have D.copy() and D.clear().) Someone looking at x[:] or x[:] = [] should immediately recognize a list copy or clear operation. Having to think of whether x may be a dictionary would make such code very confusing.

040a6c67-9f49-475c-a0fb-294ef5661fed commented 16 years ago

Having now read messages 63380 and 63384, I agree with them: I would have withdrawn my proposal if it hadn't gotten rejected first. I do have a use case, but the workaround is pretty easy.

abalkin commented 16 years ago

I hate to flip-flop like this, but please consider my new arguments at bpo-2268. In short, slices being unhashable prevents storing them in the code object's const dictionary and thus prevents optimizing code involving const slices.

Unless I hear strong opposition from the bug tracker forum, I plan to present some ideas on python-dev on how to make slices hashable while not enabling d[:].

rhettinger commented 14 years ago

This needs to stay rejected. I'm unwilling to introduce special cases in the language just to support a peephole optimization.

gvanrossum commented 14 years ago

Did Alexander ever present his case to python-dev?