If a class supports hash(), repr() is always immutable?

I know that, if a class implements __hash__, it’s not mandatory that the instances are immutable. A mutable object can calculate the hash from its immutable properties. The classical example is an iterator.

If so, __repr__() can return another result if the internal state changes, or it’s not considered a good practice to do so?

I’m asking this because I’m implementing with the Python C API a builtin frozendict. I already implemented it in pure Py, but obviously is more slow than dict for some operations.

Since it’s immutable, I thought I can cache its repr when it’s hashable, that it means that all its values are hashable. But what if one of its values changes?

Alternatively, there’s not a generic way to check if a mutable object changed its version? For example, dict has a ma_version_tag integer property that increments itself when the dictionary changes.

Why do you want to cache __repr__? repr’s job is to help humans understand and debug, so I’d think reliability is extremely important and speed hardly matters at all…

1 Like

Well, that’s why I’ve done the question above: because I want that repr will be reliable. And if it’s also fast, well, it’s better :smiley:

See what tuple does when one of elements are mutable:

> t = ([], None)
> hash(t)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'list'

And the repr:

> repr(t)
'([], None)'
> t[0].append(999)
> repr(t)
'([999], None)'

Well, indeed list is not hashable. And I asked:

  1. if it is reasonable to expect that a mutable and hashable object have an immutable repr anyway
  2. if there’s a generic way to get the version of a mutable object. For dict is ma_version_tag

That’s between you and your code. The language takes no position on this.


That’s between you and your code. The language takes no position on this.

So I suppose the answer is “No” :smiley: