# [Python-Dev] redefining is

Tim Peters tim.one at comcast.net
Wed Mar 24 23:27:54 EST 2004

```[Andrew Koenig]
> ...
> If I understand things correctly, if I evaluate
>
> 	x = (3, 4)
> 	y = (3, 4)
>
> the implementation is permitted to bind x and y to the same object,
> or not, as it pleases.

Right.

> If you like, all instances of (3, 4) are equivalent and the
> implementation is permitted to chose any representative of that
> equivalence class.

Yup.

> I think the interesting use case is whenever one wants to test for
> membership in that equivalence class.

Which equivalence class?  If it's the equivalence class of objects the
implementation is permitted to bind to y, then that's the set of 2-tuples
containing 3 at index 0 and 4 at index 1.  I don't believe the language
definition is actually clear about whether, e.g., (3L, 4L) is in that class,
although I'm sure it's Guido's intent that (3L, 4L) is not in that class.

> Now, you will probably say that == does the trick: if x is a member
> of the equivalence class of (3, 4), then x == y is True if and only
> if y is also a member of that equivalence class.

== ain't it.  For example, it could be that (x, x) == (3, 4), where x is an
instance of a perverse user-defined class that arranges to compare equal to
3 or 4 on alternating __eq__ calls.  Less strained, (3+0j, 4+0j) == (3, 4),
but the implementation can't return the former here either.

> However, consider this:
>
> 	a = []
> 	x = (3, a)
> 	y = (3, a)
>
> I claim that x and y are *still* members of an equivalence class in
> exactly the same sense that they were members before --

Well, they may well be members of *an* equivalence class, depending on how
the equivalence relation is defined.  If you're claiming that they're
members of "the" equivalence class Python's implementation is free to draw
from ("exactly the same sense" seems to imply that's your claim), then I
think Guido would disagree:  I believe Guido will say that

x is y

cannot be true after the code snippet above.  And we really have to ask him
that, because I don't think the "Objects, values and types" section in the
language reference manual is clear enough to nail it.

> aside from checking the identity of x and y, there is no way of
> distinguishing them.

There are potentially other ways apart from checking "x is y" or "id(x) ==
id(y)" directly.  Like they may have different refcounts (which CPython
exposes), gc.get_referrers() may return different lists, even
gc.get_referents() may return different objects (depending on whether the
same instance of 3 appears in both).

> However, the test x == y no longer determines whether x and y are
> members of the same equivalence class.

But == never did, and I remain fuzzy on whether you're trying to capture a
Python-defined equivalence class, or a more-or-less arbitrary equivalence

> Indeed, there is no built-in test that will determine whether x and
> y are in the same equivalence class.

I believe that.  What I don't know is why I'd want to write Python code that
can determine it.

> Finally:
>
> 	x = [3, 4]
> 	y = [3, 4]
>
> Now x and y are *not* in the same equivalence class, because changing
> one of them doesn't change the other.  Nevertheless, x == y yields
> True.
>
>
> So what I think is the interesting use case is this:  You evaluate two
> expressions, for which the implementation is permitted to return the
> same object twice or two distinct members of the same equivalence
> class, or perhaps two distinct objects.  How can one determine
> straightforwardly whether those objects are members of the same
> equivalence class?

I don't have a use case for answering that very question -- that's what I

> If the objects' value is (3, 4), you can use ==.

Nope (see above).

> If the objects' value is (3, a), there's no really easy way to do it.

Not even if it's (3, 4).

> If the objects' value is [3, 4], you can use 'is'.

Yes.

> I think it would be useful to have an operation that is as easy to
> use as 'is' that would make the determination.

Why <wink>?

```