mirror of
https://github.com/python/cpython.git
synced 2025-08-30 21:48:47 +00:00
gh-49766: Make date-datetime comparison more symmetric and flexible (GH-114760)
Now the special comparison methods like `__eq__` and `__lt__` return NotImplemented if one of comparands is date and other is datetime instead of ignoring the time part and the time zone or forcefully return "not equal" or raise TypeError. It makes comparison of date and datetime subclasses more symmetric and allows to change the default behavior by overriding the special comparison methods in subclasses. It is now the same as if date and datetime was independent classes.
This commit is contained in:
parent
d9d6909697
commit
b104360788
5 changed files with 91 additions and 84 deletions
|
@ -1816,16 +1816,6 @@ diff_to_bool(int diff, int op)
|
|||
Py_RETURN_RICHCOMPARE(diff, 0, op);
|
||||
}
|
||||
|
||||
/* Raises a "can't compare" TypeError and returns NULL. */
|
||||
static PyObject *
|
||||
cmperror(PyObject *a, PyObject *b)
|
||||
{
|
||||
PyErr_Format(PyExc_TypeError,
|
||||
"can't compare %s to %s",
|
||||
Py_TYPE(a)->tp_name, Py_TYPE(b)->tp_name);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------------
|
||||
* Class implementations.
|
||||
*/
|
||||
|
@ -3448,7 +3438,15 @@ date_isocalendar(PyDateTime_Date *self, PyObject *Py_UNUSED(ignored))
|
|||
static PyObject *
|
||||
date_richcompare(PyObject *self, PyObject *other, int op)
|
||||
{
|
||||
if (PyDate_Check(other)) {
|
||||
/* Since DateTime is a subclass of Date, if the other object is
|
||||
* a DateTime, it would compute an equality testing or an ordering
|
||||
* based on the date part alone, and we don't want that.
|
||||
* So return NotImplemented here in that case.
|
||||
* If a subclass wants to change this, it's up to the subclass to do so.
|
||||
* The behavior is the same as if Date and DateTime were independent
|
||||
* classes.
|
||||
*/
|
||||
if (PyDate_Check(other) && !PyDateTime_Check(other)) {
|
||||
int diff = memcmp(((PyDateTime_Date *)self)->data,
|
||||
((PyDateTime_Date *)other)->data,
|
||||
_PyDateTime_DATE_DATASIZE);
|
||||
|
@ -5880,21 +5878,7 @@ datetime_richcompare(PyObject *self, PyObject *other, int op)
|
|||
PyObject *offset1, *offset2;
|
||||
int diff;
|
||||
|
||||
if (! PyDateTime_Check(other)) {
|
||||
if (PyDate_Check(other)) {
|
||||
/* Prevent invocation of date_richcompare. We want to
|
||||
return NotImplemented here to give the other object
|
||||
a chance. But since DateTime is a subclass of
|
||||
Date, if the other object is a Date, it would
|
||||
compute an ordering based on the date part alone,
|
||||
and we don't want that. So force unequal or
|
||||
uncomparable here in that case. */
|
||||
if (op == Py_EQ)
|
||||
Py_RETURN_FALSE;
|
||||
if (op == Py_NE)
|
||||
Py_RETURN_TRUE;
|
||||
return cmperror(self, other);
|
||||
}
|
||||
if (!PyDateTime_Check(other)) {
|
||||
Py_RETURN_NOTIMPLEMENTED;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue