Comparing a proto message with an object of unknown returns NotImplemented

The Python comparison protocol requires that if an object doesn't know how to
compare itself to an object of a different type, it returns NotImplemented
rather than False. The interpreter will then try performing the comparison using
the other operand. This translates, for protos, to:
If a proto message doesn't know how to compare itself to an object of
non-message type, it returns NotImplemented. This way, the interpreter will then
try performing the comparison using the comparison methods of the other object,
which may know how to compare itself to a message. If not, then Python will
return the combined result (e.g., if both objects don't know how to perform
__eq__, then the equality operator `==` return false).
This change allows one to compare a proto with custom matchers such as mock.ANY
that the message doesn't know how to compare to, regardless of whether
mock.ANY is on the right-hand side or left-hand side of the equality (prior to
this change, it only worked with mock.ANY on the left-hand side).

See https://github.com/protocolbuffers/protobuf/issues/9173

PiperOrigin-RevId: 559056804
pull/13675/head^2
Protobuf Team Bot 1 year ago committed by Copybara-Service
parent d252014365
commit 243add4411
  1. 4
      python/message.c

@ -772,6 +772,10 @@ static PyObject* PyUpb_Message_RichCompare(PyObject* _self, PyObject* other,
Py_INCREF(Py_NotImplemented);
return Py_NotImplemented;
}
if (!PyObject_TypeCheck(other, Py_TYPE(self))) {
Py_INCREF(Py_NotImplemented);
return Py_NotImplemented;
}
bool ret = PyUpb_Message_IsEqual(self, other);
if (opid == Py_NE) ret = !ret;
return PyBool_FromLong(ret);

Loading…
Cancel
Save