<p>Suppose I model a game of cards, where suits don't matter. I might find the integer representation of cards (14 for "Ace", 13 for "King", ..., 2 for "2") to be convenient.</p>
<p>The deck has 4 copies of each card, which I need to distinguish. </p>
<p>I was thinking to model a card as follows:</p>
<p>class Card(int):<br>
__hash__ = int.__hash__<br>
def __eq__(self, other):<br>
return self is other</p>
<p>This works precisely as I want (at least in CPython 3.2):</p>
<p>x = Card(14)<br>
y = Card(14)<br>
assert x != y # x and y are two different Aces<br>
z = x<br>
assert x == z # x and z are bound to the same Ace</p>
<p>But this behavior is implementation dependent, so the above code may one day break (very painfully for whoever happens to maintain it at the time).</p>
<p>Is it possible to add a guarantee to the language that would make the above code safe to use? Currently the language promises:</p>
<p>"For immutable types, operations that compute new values may actually return a reference to any existing object with the same type and value, while for mutable objects this is not allowed."</p>
<p>Nowhere in the documentation is it clearly defined which objects are considered "immutable" for the purpose of this promise. As a result, a Python implementation, now or in the future, may decide that it's ok to return a reference to an existing object when a Card instance is created - since arguably, class Card is immutable (since it derives from an immutable base class, and doesn't add any new attributes). </p>

<p>Perhaps a change like this would be fine (it obviously won't break any existing code):</p>
<p>"For certain types, operations that compute new values may actually return a reference to an existing object with the same type and value. The only types for which this may happen are:</p>
<p>- built-in immutable types<br>
- user-defined classes that explicitly override __new__ to return a reference to an existing object</p>
<p>Note that a user-defined class that inherits from a built-in immutable types, without overriding __new__, will not exhibit this behavior."</p>