Skip to content

Commit

Permalink
Add nb_complex slot to PyNumberMethods (was nb_reserved)
Browse files Browse the repository at this point in the history
  • Loading branch information
skirpichev committed Oct 31, 2024
1 parent d467d92 commit aad8868
Show file tree
Hide file tree
Showing 13 changed files with 54 additions and 72 deletions.
11 changes: 3 additions & 8 deletions Doc/c-api/typeobj.rst
Original file line number Diff line number Diff line change
Expand Up @@ -276,7 +276,7 @@ sub-slots
+---------------------------------------------------------+-----------------------------------+---------------+
| :c:member:`~PyNumberMethods.nb_int` | :c:type:`unaryfunc` | __int__ |
+---------------------------------------------------------+-----------------------------------+---------------+
| :c:member:`~PyNumberMethods.nb_reserved` | void * | |
| :c:member:`~PyNumberMethods.nb_complex` | :c:type:`unaryfunc` | __complex__ |
+---------------------------------------------------------+-----------------------------------+---------------+
| :c:member:`~PyNumberMethods.nb_float` | :c:type:`unaryfunc` | __float__ |
+---------------------------------------------------------+-----------------------------------+---------------+
Expand Down Expand Up @@ -2263,7 +2263,7 @@ Number Object Structures
binaryfunc nb_xor;
binaryfunc nb_or;
unaryfunc nb_int;
void *nb_reserved;
unaryfunc nb_complex;
unaryfunc nb_float;

binaryfunc nb_inplace_add;
Expand Down Expand Up @@ -2297,11 +2297,6 @@ Number Object Structures
``Py_NotImplemented``, if another error occurred they must return ``NULL``
and set an exception.

.. note::

The :c:member:`~PyNumberMethods.nb_reserved` field should always be ``NULL``. It
was previously called :c:member:`!nb_long`, and was renamed in
Python 3.0.1.

.. c:member:: binaryfunc PyNumberMethods.nb_add
.. c:member:: binaryfunc PyNumberMethods.nb_subtract
Expand All @@ -2320,7 +2315,7 @@ Number Object Structures
.. c:member:: binaryfunc PyNumberMethods.nb_xor
.. c:member:: binaryfunc PyNumberMethods.nb_or
.. c:member:: unaryfunc PyNumberMethods.nb_int
.. c:member:: void *PyNumberMethods.nb_reserved
.. c:member:: unaryfunc PyNumberMethods.nb_complex
.. c:member:: unaryfunc PyNumberMethods.nb_float
.. c:member:: binaryfunc PyNumberMethods.nb_inplace_add
.. c:member:: binaryfunc PyNumberMethods.nb_inplace_subtract
Expand Down
2 changes: 1 addition & 1 deletion Include/cpython/object.h
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ typedef struct {
binaryfunc nb_xor;
binaryfunc nb_or;
unaryfunc nb_int;
void *nb_reserved; /* the slot formerly known as nb_long */
unaryfunc nb_complex; /* the slot formerly known as nb_long */
unaryfunc nb_float;

binaryfunc nb_inplace_add;
Expand Down
2 changes: 1 addition & 1 deletion Modules/_datetimemodule.c
Original file line number Diff line number Diff line change
Expand Up @@ -3043,7 +3043,7 @@ static PyNumberMethods delta_as_number = {
0, /*nb_xor*/
0, /*nb_or*/
0, /*nb_int*/
0, /*nb_reserved*/
0, /*nb_complex*/
0, /*nb_float*/
0, /*nb_inplace_add*/
0, /*nb_inplace_subtract*/
Expand Down
2 changes: 1 addition & 1 deletion Modules/_testcapimodule.c
Original file line number Diff line number Diff line change
Expand Up @@ -3539,7 +3539,7 @@ static PyNumberMethods matmulType_as_number = {
0, /* nb_xor */
0, /* nb_or */
0, /* nb_int */
0, /* nb_reserved */
0, /* nb_complex */
0, /* nb_float */
0, /* nb_inplace_add */
0, /* nb_inplace_subtract */
Expand Down
2 changes: 1 addition & 1 deletion Objects/boolobject.c
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ static PyNumberMethods bool_as_number = {
bool_xor, /* nb_xor */
bool_or, /* nb_or */
0, /* nb_int */
0, /* nb_reserved */
0, /* nb_complex */
0, /* nb_float */
0, /* nb_inplace_add */
0, /* nb_inplace_subtract */
Expand Down
20 changes: 1 addition & 19 deletions Objects/clinic/complexobject.c.h

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

74 changes: 38 additions & 36 deletions Objects/complexobject.c
Original file line number Diff line number Diff line change
Expand Up @@ -329,34 +329,44 @@ PyComplex_ImagAsDouble(PyObject *op)
static PyObject *
try_complex_special_method(PyObject *op)
{
PyObject *f;

f = _PyObject_LookupSpecial(op, &_Py_ID(__complex__));
if (f) {
PyObject *res = _PyObject_CallNoArgs(f);
Py_DECREF(f);
if (!res || PyComplex_CheckExact(res)) {
return res;
}
if (!PyComplex_Check(res)) {
PyErr_Format(PyExc_TypeError,
"__complex__ returned non-complex (type %.200s)",
Py_TYPE(res)->tp_name);
Py_DECREF(res);
return NULL;
}
/* Issue #29894: warn if 'res' not of exact type complex. */
if (PyErr_WarnFormat(PyExc_DeprecationWarning, 1,
"__complex__ returned non-complex (type %.200s). "
"The ability to return an instance of a strict subclass of complex "
"is deprecated, and may be removed in a future version of Python.",
Py_TYPE(res)->tp_name)) {
Py_DECREF(res);
return NULL;
PyNumberMethods *m = Py_TYPE(op)->tp_as_number;
PyObject *res = NULL;

if (m && m->nb_complex) {
res = m->nb_complex(op);
}
else {
PyObject *f = _PyObject_LookupSpecial(op, &_Py_ID(__complex__));
if (f) {
res = _PyObject_CallNoArgs(f);
Py_DECREF(f);
if (PyErr_WarnEx(PyExc_DeprecationWarning,
"XXX use nb_complex", 1)) {
Py_XDECREF(res);
}
}
}

if (!res || PyComplex_CheckExact(res)) {
return res;
}
return NULL;
if (!PyComplex_Check(res)) {
PyErr_Format(PyExc_TypeError,
"__complex__ returned non-complex (type %.200s)",
Py_TYPE(res)->tp_name);
Py_DECREF(res);
return NULL;
}
/* Issue #29894: warn if 'res' not of exact type complex. */
if (PyErr_WarnFormat(PyExc_DeprecationWarning, 1,
"__complex__ returned non-complex (type %.200s). "
"The ability to return an instance of a strict subclass of complex "
"is deprecated, and may be removed in a future version of Python.",
Py_TYPE(res)->tp_name)) {
Py_DECREF(res);
return NULL;
}
return res;
}

Py_complex
Expand Down Expand Up @@ -740,25 +750,17 @@ complex___format___impl(PyComplexObject *self, PyObject *format_spec)
return _PyUnicodeWriter_Finish(&writer);
}

/*[clinic input]
complex.__complex__
Convert this value to exact type complex.
[clinic start generated code]*/

static PyObject *
complex___complex___impl(PyComplexObject *self)
/*[clinic end generated code: output=e6b35ba3d275dc9c input=3589ada9d27db854]*/
complex_complex(PyObject *self)
{
if (PyComplex_CheckExact(self)) {
return Py_NewRef(self);
}
else {
return PyComplex_FromCComplex(self->cval);
return PyComplex_FromCComplex(((PyComplexObject *)self)->cval);
}
}


static PyObject *
complex_from_string_inner(const char *s, Py_ssize_t len, void *type)
{
Expand Down Expand Up @@ -1192,7 +1194,7 @@ static PyNumberMethods complex_as_number = {
0, /* nb_xor */
0, /* nb_or */
0, /* nb_int */
0, /* nb_reserved */
complex_complex, /* nb_complex */
0, /* nb_float */
0, /* nb_inplace_add */
0, /* nb_inplace_subtract */
Expand Down
2 changes: 1 addition & 1 deletion Objects/floatobject.c
Original file line number Diff line number Diff line change
Expand Up @@ -1857,7 +1857,7 @@ static PyNumberMethods float_as_number = {
0, /* nb_xor */
0, /* nb_or */
float___trunc___impl, /* nb_int */
0, /* nb_reserved */
0, /* nb_complex */
float_float, /* nb_float */
0, /* nb_inplace_add */
0, /* nb_inplace_subtract */
Expand Down
2 changes: 1 addition & 1 deletion Objects/longobject.c
Original file line number Diff line number Diff line change
Expand Up @@ -6522,7 +6522,7 @@ static PyNumberMethods long_as_number = {
long_xor, /*nb_xor*/
long_or, /*nb_or*/
long_long, /*nb_int*/
0, /*nb_reserved*/
0, /*nb_complex*/
long_float, /*nb_float*/
0, /* nb_inplace_add */
0, /* nb_inplace_subtract */
Expand Down
2 changes: 1 addition & 1 deletion Objects/object.c
Original file line number Diff line number Diff line change
Expand Up @@ -2061,7 +2061,7 @@ static PyNumberMethods none_as_number = {
0, /* nb_xor */
0, /* nb_or */
0, /* nb_int */
0, /* nb_reserved */
0, /* nb_complex */
0, /* nb_float */
0, /* nb_inplace_add */
0, /* nb_inplace_subtract */
Expand Down
2 changes: 1 addition & 1 deletion Objects/setobject.c
Original file line number Diff line number Diff line change
Expand Up @@ -2450,7 +2450,7 @@ static PyNumberMethods set_as_number = {
set_xor, /*nb_xor*/
set_or, /*nb_or*/
0, /*nb_int*/
0, /*nb_reserved*/
0, /*nb_complex*/
0, /*nb_float*/
0, /*nb_inplace_add*/
set_isub, /*nb_inplace_subtract*/
Expand Down
3 changes: 3 additions & 0 deletions Objects/typeobject.c
Original file line number Diff line number Diff line change
Expand Up @@ -9781,6 +9781,7 @@ SLOT1BIN(slot_nb_xor, nb_xor, __xor__, __rxor__)
SLOT1BIN(slot_nb_or, nb_or, __or__, __ror__)

SLOT0(slot_nb_int, __int__)
SLOT0(slot_nb_complex, __complex__)
SLOT0(slot_nb_float, __float__)
SLOT1(slot_nb_inplace_add, __iadd__, PyObject *)
SLOT1(slot_nb_inplace_subtract, __isub__, PyObject *)
Expand Down Expand Up @@ -10661,6 +10662,8 @@ static pytype_slotdef slotdefs[] = {
RBINSLOT(__ror__, nb_or, slot_nb_or, "|"),
UNSLOT(__int__, nb_int, slot_nb_int, wrap_unaryfunc,
"int(self)"),
UNSLOT(__complex__, nb_complex, slot_nb_complex, wrap_unaryfunc,
"complex(self)"),
UNSLOT(__float__, nb_float, slot_nb_float, wrap_unaryfunc,
"float(self)"),
IBSLOT(__iadd__, nb_inplace_add, slot_nb_inplace_add,
Expand Down
2 changes: 1 addition & 1 deletion Objects/weakrefobject.c
Original file line number Diff line number Diff line change
Expand Up @@ -809,7 +809,7 @@ static PyNumberMethods proxy_as_number = {
proxy_xor, /*nb_xor*/
proxy_or, /*nb_or*/
proxy_int, /*nb_int*/
0, /*nb_reserved*/
0, /*nb_complex*/
proxy_float, /*nb_float*/
proxy_iadd, /*nb_inplace_add*/
proxy_isub, /*nb_inplace_subtract*/
Expand Down

0 comments on commit aad8868

Please sign in to comment.