5

Suppose I create two instances of class object. Are these two instances guaranteed to be not equal to each other? In other words, is object() == object() guaranteed to be False, or is it implementation-dependent?

I understand that object() is object() is guaranteed to be False, but here I am asking about object() == object().

Flux
  • 9,805
  • 5
  • 46
  • 92
  • 3
    does it impact any business logic/architecture design? – Lei Yang Mar 09 '22 at 03:41
  • Most of the time I'd expect it to be `True`, because default initialization should produce an object with a consistent value. – Mark Ransom Mar 09 '22 at 03:43
  • 4
    You might want to read https://docs.python.org/3/reference/datamodel.html#object.__eq__, I guess. – j1-lee Mar 09 '22 at 03:44
  • @MarkRansom Does `object() == object()` return `True` in the implementation you are using? Which implementation/version of Python are you using? – Flux Mar 09 '22 at 03:46
  • You realize, of course, that `object` isn't a reserved word, and could be reassigned to change the behaviour... right? – Karl Knechtel Mar 09 '22 at 03:48
  • @j1-lee wow, that information is extraordinarily hard to find. I thought it would be a quick Google away, but I wasn't able to dig it up on my own. – Mark Ransom Mar 09 '22 at 03:56
  • @Flux I checked after I left my comment, and indeed it returns `False`. It wasn't clear to me at first that you were talking about the built-in type `object`, I thought you were speaking more generically. You now have an answer that explains it, and I must admit the default implementation breaks my expectations. – Mark Ransom Mar 09 '22 at 04:01
  • 1
    Where is `object() is object()` guaranteed to be `False`? – Kelly Bundy Mar 11 '22 at 20:56
  • 1
    @KellyBundy The documentation for `object()` says: "Return a **new** featureless object." – Flux Mar 12 '22 at 00:30
  • @Flux Right, but `is` tests for an object’s identity, which is determined using the `id()` function, and `id(object()) == id(object())` [can be `True`](https://tio.run/##K6gsycjPM7YoKPr/v6AoM69EIzNFIz8pKzW5RENTU8HWVgGZr/n/PwA), so why not also `object() is object()`? I think that's more difficult to explain than simply looking up what `object.__eq__` does :-P – Kelly Bundy Mar 12 '22 at 00:37
  • @KellyBundy I have posted a follow up question: [Why are two instances of "object" considered non-identical although their "id()" are the same?](https://stackoverflow.com/questions/71446096/why-are-two-instances-of-object-considered-non-identical-although-their-id) – Flux Mar 12 '22 at 00:53
  • @Flux Oh I hope you didn't ask for me, as I knew the answer. I really just meant that it's more difficult to fully explain, and what juanpa said there still leaves a question: where is it guaranteed that the two objects in `object() is object()` have overlapping lifetimes? It seems obvious that they do/must, but I don't know a piece of documentation saying so, and I'm not even sure there is one :-) – Kelly Bundy Mar 12 '22 at 01:08

2 Answers2

10

Yes it is guaranteed that object() == object() is False because it is documented that "by default, object implements __eq__() by using is".

blhsing
  • 91,368
  • 6
  • 71
  • 106
  • Now we just need proof that `is` is guaranteed to be `False` there. – Kelly Bundy Mar 11 '22 at 20:59
  • @KellyBundy I would say no: "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." Then, "after `c = []; d = []`, `c` and `d` are guaranteed to refer to two different, unique, newly created empty lists." So many adjectives, yet no mention of the `id` operator. Clearly, the semantics _allow_ for the `is` comparison to return `True`, but you'd have to justify why. Those `object`s can be monkey-patched to anything, if `is` returns `True` there, it's meaningless. – Nearoo Mar 15 '22 at 18:31
  • @Nearoo Hmm, I don't think anybody here was talking about monkey-patching anything or so. Think of a script doing nothing but `print(object() == object())` or nothing but `print(object() is object())`. – Kelly Bundy Mar 15 '22 at 18:37
  • @KellyBundy But if you return True there you have to think about other situations. What if the objects are monkey patched after the comparsion? If you return true for `object() == object()`, you should return `True` for the monkey patch case as well, or you have to setup rules that will lie between cumbersome and undecidable to enforce both for the programmer and the compiler. – Nearoo Mar 17 '22 at 11:38
  • @Nearoo Hmm, somewhere there you lost me, I don't understand what you're saying. But "monkey patched after the comparsion" sounds like you're talking about them being two separate objects that keep on living, so you've already *decided* against the `is` comparison possibly returning true. – Kelly Bundy Mar 17 '22 at 16:24
3

Each Python 3.x release is intended to be backward-compatible with previous 3.x releases. As it's the base class, changing the comparison behavior of object would break this backward compatibility promise. So I think you can rely on it, but if we knew what you're trying to do that requires this invariant, we could probably give better advice.

You can always use assert to make sure it continues to be true.

kindall
  • 178,883
  • 35
  • 278
  • 309
  • "if we knew what you're trying to do that requires this invariant, we could probably give better advice" - Thank you for the response. I am not trying to do anything in particular. I am simply asking out of curiosity. – Flux Mar 09 '22 at 03:56