I'm defining a Python object as being "immutable at any depth" iff
For example ((1, 2), (3, 4))
is immutable at any depth, whereas ((1, 2), [3, 4])
isn't (even though the latter, by virtue of being a tuple, is "nominally" immutable).
Is there a reasonable way to test whether a Python object is "immutable at any depth"?
It is relatively easy to test for the first condition (e.g. using collections.Hashable
class, and neglecting the possibility of an improperly implemented __hash__
method), but the second condition is harder to test for, because of the heterogeneity of "container" objects, and the means of iterating over their "contents"...
Thanks!
There are no general tests for immutability. An object is immutable only if none of its methods can mutate the underlying data.
More likely, you're interested in hashability which usually depends on immutability. Containers that are hashable will recursively hash their contents (i.e. tuples and frozensets). So, your test amounts to running hash(obj)
and if it succeeds then it was deeply hashable.
IOW, your code already used the best test available:
>>> a = ((1, 2), (3, 4))
>>> b = ((1, 2), [3, 4])
>>> hash(a)
5879964472677921951
>>> hash(b)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'list'