Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit be4cbb1

Browse files
committed
Use rich comparisons to fulfill an old wish: complex numbers now raise
exceptions when compared using <, <=, > or >=. NOTE: This is a tentative change: this means that cmp() involving complex numbers will raise an exception when the numbers differ, and that in turn means that e.g. dictionaries and certain other compounds (e.g. UserLists) containing complex numbers can't be compared either. So we'll have to decide whether this is acceptable. The alpha test cycle is a good time to keep an eye on this!
1 parent 9d19cb8 commit be4cbb1

1 file changed

Lines changed: 84 additions & 49 deletions

File tree

Objects/complexobject.c

Lines changed: 84 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -210,22 +210,6 @@ complex_repr(PyComplexObject *v)
210210
return PyString_FromString(buf);
211211
}
212212

213-
static int
214-
complex_compare(PyComplexObject *v, PyComplexObject *w)
215-
{
216-
/* Note: "greater" and "smaller" have no meaning for complex numbers,
217-
but Python requires that they be defined nevertheless. */
218-
Py_complex i, j;
219-
i = v->cval;
220-
j = w->cval;
221-
if (i.real == j.real && i.imag == j.imag)
222-
return 0;
223-
else if (i.real != j.real)
224-
return (i.real < j.real) ? -1 : 1;
225-
else
226-
return (i.imag < j.imag) ? -1 : 1;
227-
}
228-
229213
static long
230214
complex_hash(PyComplexObject *v)
231215
{
@@ -420,6 +404,47 @@ complex_coerce(PyObject **pv, PyObject **pw)
420404
return 1; /* Can't do it */
421405
}
422406

407+
static PyObject *
408+
complex_richcompare(PyObject *v, PyObject *w, int op)
409+
{
410+
int c;
411+
Py_complex i, j;
412+
PyObject *res;
413+
414+
if (op != Py_EQ && op != Py_NE) {
415+
PyErr_SetString(PyExc_TypeError,
416+
"cannot compare complex numbers using <, <=, >, >=");
417+
return NULL;
418+
}
419+
420+
c = PyNumber_CoerceEx(&v, &w);
421+
if (c < 0)
422+
return NULL;
423+
if (c > 0) {
424+
Py_INCREF(Py_NotImplemented);
425+
return Py_NotImplemented;
426+
}
427+
if (!PyComplex_Check(v) || !PyComplex_Check(w)) {
428+
Py_DECREF(v);
429+
Py_DECREF(w);
430+
Py_INCREF(Py_NotImplemented);
431+
return Py_NotImplemented;
432+
}
433+
434+
i = ((PyComplexObject *)v)->cval;
435+
j = ((PyComplexObject *)w)->cval;
436+
Py_DECREF(v);
437+
Py_DECREF(w);
438+
439+
if ((i.real == j.real && i.imag == j.imag) == (op == Py_EQ))
440+
res = Py_True;
441+
else
442+
res = Py_False;
443+
444+
Py_INCREF(res);
445+
return res;
446+
}
447+
423448
static PyObject *
424449
complex_int(PyObject *v)
425450
{
@@ -474,29 +499,29 @@ complex_getattr(PyComplexObject *self, char *name)
474499
}
475500

476501
static PyNumberMethods complex_as_number = {
477-
(binaryfunc)complex_add, /*nb_add*/
478-
(binaryfunc)complex_sub, /*nb_subtract*/
479-
(binaryfunc)complex_mul, /*nb_multiply*/
480-
(binaryfunc)complex_div, /*nb_divide*/
481-
(binaryfunc)complex_remainder, /*nb_remainder*/
482-
(binaryfunc)complex_divmod, /*nb_divmod*/
483-
(ternaryfunc)complex_pow, /*nb_power*/
484-
(unaryfunc)complex_neg, /*nb_negative*/
485-
(unaryfunc)complex_pos, /*nb_positive*/
486-
(unaryfunc)complex_abs, /*nb_absolute*/
487-
(inquiry)complex_nonzero, /*nb_nonzero*/
488-
0, /*nb_invert*/
489-
0, /*nb_lshift*/
490-
0, /*nb_rshift*/
491-
0, /*nb_and*/
492-
0, /*nb_xor*/
493-
0, /*nb_or*/
494-
(coercion)complex_coerce, /*nb_coerce*/
495-
(unaryfunc)complex_int, /*nb_int*/
496-
(unaryfunc)complex_long, /*nb_long*/
497-
(unaryfunc)complex_float, /*nb_float*/
498-
0, /*nb_oct*/
499-
0, /*nb_hex*/
502+
(binaryfunc)complex_add, /* nb_add */
503+
(binaryfunc)complex_sub, /* nb_subtract */
504+
(binaryfunc)complex_mul, /* nb_multiply */
505+
(binaryfunc)complex_div, /* nb_divide */
506+
(binaryfunc)complex_remainder, /* nb_remainder */
507+
(binaryfunc)complex_divmod, /* nb_divmod */
508+
(ternaryfunc)complex_pow, /* nb_power */
509+
(unaryfunc)complex_neg, /* nb_negative */
510+
(unaryfunc)complex_pos, /* nb_positive */
511+
(unaryfunc)complex_abs, /* nb_absolute */
512+
(inquiry)complex_nonzero, /* nb_nonzero */
513+
0, /* nb_invert */
514+
0, /* nb_lshift */
515+
0, /* nb_rshift */
516+
0, /* nb_and */
517+
0, /* nb_xor */
518+
0, /* nb_or */
519+
(coercion)complex_coerce, /* nb_coerce */
520+
(unaryfunc)complex_int, /* nb_int */
521+
(unaryfunc)complex_long, /* nb_long */
522+
(unaryfunc)complex_float, /* nb_float */
523+
0, /* nb_oct */
524+
0, /* nb_hex */
500525
};
501526

502527
PyTypeObject PyComplex_Type = {
@@ -505,16 +530,26 @@ PyTypeObject PyComplex_Type = {
505530
"complex",
506531
sizeof(PyComplexObject),
507532
0,
508-
(destructor)complex_dealloc, /*tp_dealloc*/
509-
(printfunc)complex_print, /*tp_print*/
510-
(getattrfunc)complex_getattr, /*tp_getattr*/
511-
0, /*tp_setattr*/
512-
(cmpfunc)complex_compare, /*tp_compare*/
513-
(reprfunc)complex_repr, /*tp_repr*/
514-
&complex_as_number, /*tp_as_number*/
515-
0, /*tp_as_sequence*/
516-
0, /*tp_as_mapping*/
517-
(hashfunc)complex_hash, /*tp_hash*/
533+
(destructor)complex_dealloc, /* tp_dealloc */
534+
(printfunc)complex_print, /* tp_print */
535+
(getattrfunc)complex_getattr, /* tp_getattr */
536+
0, /* tp_setattr */
537+
0, /* tp_compare */
538+
(reprfunc)complex_repr, /* tp_repr */
539+
&complex_as_number, /* tp_as_number */
540+
0, /* tp_as_sequence */
541+
0, /* tp_as_mapping */
542+
(hashfunc)complex_hash, /* tp_hash */
543+
0, /* tp_call */
544+
0, /* tp_str */
545+
0, /* tp_getattro */
546+
0, /* tp_setattro */
547+
0, /* tp_as_buffer */
548+
Py_TPFLAGS_DEFAULT, /* tp_flags */
549+
0, /* tp_doc */
550+
0, /* tp_traverse */
551+
0, /* tp_clear */
552+
complex_richcompare, /* tp_richcompare */
518553
};
519554

520555
#endif

0 commit comments

Comments
 (0)