Best practice for caching hash

Chris Angelico rosuav at gmail.com
Tue Mar 15 19:57:48 EDT 2022


On Wed, 16 Mar 2022 at 10:42, Cameron Simpson <cs at cskk.id.au> wrote:
>
> On 12Mar2022 21:45, Marco Sulla <Marco.Sulla.Python at gmail.com> wrote:
> >I have a custom immutable object, and I added a cache for its hash
> >value. The problem is the object can be composed of mutable or
> >immutable objects, so the hash can raise TypeError.
>
> Is it sensible to compute the hash only from the immutable parts?
> Bearing in mind that usually you need an equality function as well and
> it may have the same stability issues.

My understanding - and I'm sure Marco will correct me if I'm wrong
here - is that this behaves like a tuple: if it contains nothing but
hashable objects, it is itself hashable, but if it contains anything
unhashable, the entire tuple isn't hashable.

(Though it's a little confusing; a frozendict has to have nothing but
immutable objects, yet it permits them to be unhashable? I know of
hashable mutable objects, but can't think of any unhashable immutable
objects. And I'm not sure whether a hashable-mutable would be
permitted in a frozendict, or whether it'd even know.)

As such, any valid hash value will be stable, and "asking for a hash
will raise TypeError" is also stable.

> >The problem is the first time I get an error with details, for example:
> >
> >TypeError: unhashable type: 'list'
> >
> >The subsequent times I simply raise a generic error:
> >
> >TypeError
>
> You could, you know, cache the original exception. That does keep links
> to the traceback and therefore all the associates stack frames, so that
> isn't cheap (it is peerfectly fast - just the reference, t just prevents
> those things from being reclaimed).

I don't like that idea myself, for that exact reason - it'll keep
arbitrary numbers of objects alive. But caching the stringified form
would be more reasonable here, and have similar effect.

ChrisA


More information about the Python-list mailing list