Commit 2400fa4a authored by Tim Peters's avatar Tim Peters

Again perhaps the end of [#460020] bug or feature: unicode() and subclasses.

Inhibited complex unary plus optimization when applied to a complex subtype.
Added PyComplex_CheckExact macro.  Some comments and minor code fiddling.
parent 1140cb2b
...@@ -43,6 +43,7 @@ typedef struct { ...@@ -43,6 +43,7 @@ typedef struct {
extern DL_IMPORT(PyTypeObject) PyComplex_Type; extern DL_IMPORT(PyTypeObject) PyComplex_Type;
#define PyComplex_Check(op) PyObject_TypeCheck(op, &PyComplex_Type) #define PyComplex_Check(op) PyObject_TypeCheck(op, &PyComplex_Type)
#define PyComplex_CheckExact(op) ((op)->ob_type == &PyComplex_Type)
extern DL_IMPORT(PyObject *) PyComplex_FromCComplex(Py_complex); extern DL_IMPORT(PyObject *) PyComplex_FromCComplex(Py_complex);
extern DL_IMPORT(PyObject *) PyComplex_FromDoubles(double real, double imag); extern DL_IMPORT(PyObject *) PyComplex_FromDoubles(double real, double imag);
......
...@@ -1430,6 +1430,30 @@ def inherits(): ...@@ -1430,6 +1430,30 @@ def inherits():
verify(hash(a) == hash(12345.0)) verify(hash(a) == hash(12345.0))
verify((+a).__class__ is float) verify((+a).__class__ is float)
class madcomplex(complex):
def __repr__(self):
return "%.17gj%+.17g" % (self.imag, self.real)
a = madcomplex(-3, 4)
verify(repr(a) == "4j-3")
base = complex(-3, 4)
verify(base.__class__ is complex)
verify(complex(a) == base)
verify(complex(a).__class__ is complex)
a = madcomplex(a) # just trying another form of the constructor
verify(repr(a) == "4j-3")
verify(complex(a) == base)
verify(complex(a).__class__ is complex)
verify(hash(a) == hash(base))
verify((+a).__class__ is complex)
verify((a + 0).__class__ is complex)
verify(a + 0 == base)
verify((a - 0).__class__ is complex)
verify(a - 0 == base)
verify((a * 1).__class__ is complex)
verify(a * 1 == base)
verify((a / 1).__class__ is complex)
verify(a / 1 == base)
class madtuple(tuple): class madtuple(tuple):
_rev = None _rev = None
def rev(self): def rev(self):
......
...@@ -489,8 +489,12 @@ complex_neg(PyComplexObject *v) ...@@ -489,8 +489,12 @@ complex_neg(PyComplexObject *v)
static PyObject * static PyObject *
complex_pos(PyComplexObject *v) complex_pos(PyComplexObject *v)
{ {
Py_INCREF(v); if (PyComplex_CheckExact(v)) {
return (PyObject *)v; Py_INCREF(v);
return (PyObject *)v;
}
else
return PyComplex_FromCComplex(v->cval);
} }
static PyObject * static PyObject *
...@@ -792,11 +796,12 @@ complex_new(PyTypeObject *type, PyObject *args, PyObject *kwds) ...@@ -792,11 +796,12 @@ complex_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
return NULL; return NULL;
if (PyString_Check(r) || PyUnicode_Check(r)) if (PyString_Check(r) || PyUnicode_Check(r))
return complex_subtype_from_string(type, r); return complex_subtype_from_string(type, r);
if ((nbr = r->ob_type->tp_as_number) == NULL ||
nbr->nb_float == NULL || nbr = r->ob_type->tp_as_number;
(i != NULL && if (i != NULL)
((nbi = i->ob_type->tp_as_number) == NULL || nbi = i->ob_type->tp_as_number;
nbi->nb_float == NULL))) { if (nbr == NULL || nbr->nb_float == NULL ||
((i != NULL) && (nbi == NULL || nbi->nb_float == NULL))) {
PyErr_SetString(PyExc_TypeError, PyErr_SetString(PyExc_TypeError,
"complex() arg can't be converted to complex"); "complex() arg can't be converted to complex");
return NULL; return NULL;
...@@ -826,6 +831,9 @@ complex_new(PyTypeObject *type, PyObject *args, PyObject *kwds) ...@@ -826,6 +831,9 @@ complex_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
} }
} }
if (PyComplex_Check(r)) { if (PyComplex_Check(r)) {
/* Note that if r is of a complex subtype, we're only
retaining its real & imag parts here, and the return
value is (properly) of the builtin complex type. */
cr = ((PyComplexObject*)r)->cval; cr = ((PyComplexObject*)r)->cval;
if (own_r) { if (own_r) {
Py_DECREF(r); Py_DECREF(r);
...@@ -868,10 +876,10 @@ complex_new(PyTypeObject *type, PyObject *args, PyObject *kwds) ...@@ -868,10 +876,10 @@ complex_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
} }
static char complex_doc[] = static char complex_doc[] =
"complex(real[, imag]) -> complex number\n\ "complex(real[, imag]) -> complex number\n"
\n\ "\n"
Create a complex number from a real part and an optional imaginary part.\n\ "Create a complex number from a real part and an optional imaginary part.\n"
This is equivalent to (real + imag*1j) where imag defaults to 0."; "This is equivalent to (real + imag*1j) where imag defaults to 0.";
static PyNumberMethods complex_as_number = { static PyNumberMethods complex_as_number = {
(binaryfunc)complex_add, /* nb_add */ (binaryfunc)complex_add, /* nb_add */
......
...@@ -659,7 +659,7 @@ float_subtype_new(PyTypeObject *type, PyObject *args, PyObject *kwds) ...@@ -659,7 +659,7 @@ float_subtype_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
tmp = float_new(&PyFloat_Type, args, kwds); tmp = float_new(&PyFloat_Type, args, kwds);
if (tmp == NULL) if (tmp == NULL)
return NULL; return NULL;
assert(PyFloat_Check(tmp)); assert(PyFloat_CheckExact(tmp));
new = type->tp_alloc(type, 0); new = type->tp_alloc(type, 0);
if (new == NULL) if (new == NULL)
return NULL; return NULL;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment