This would run into similar problems as the PEP's auto-freeze approach when using "s1 in s2". If s1 is a mutable set, this creates an immutable copy for the test and then throws it away. The PEP's problem is that it's too easy to accidentally freeze a set; the problem with your proposal is "merely" one of performance. Yet I think both are undesirable, although I still prefer your solution.
If performance is a problem (and I can well see it might be!) then Set.__contains__(self, x) needs to use a specialized version of the ad-hoc adaptation code I proposed for insertion:
def insert(self, item): try: item = item.asSetItem() except AttributeError: pass self.data[item] = True
One possible route to such optimization is to introduce another class, called _TemporarilyImmutableSet, able to wrap a MutableSet x, have the same hash value that x would have if x were immutable, and compare == to whatever x compares == to.
Set would then expose a private method _asTemporarilyImmutable. ImmutableSet._asTemporarilyImmutable would just return self; MutableSet._asTemporarilyImmutable would return _TemporarlyImmutableSet(self).
class Set(object): ... def __contains__(self, item): try: item = item._asTemporarilyImmutable() except AttributeError: pass return item in self.data
Sounds reasonable. Who's gonna do an implementation? There's Greg Wilson's version, and there's an alternative by Aric Coady email@example.com that could be used as a comparison.
--Guido van Rossum (home page: http://www.python.org/~guido/)