]> granicus.if.org Git - python/commitdiff
Again perhaps the end of [#460020] bug or feature: unicode() and subclasses.
authorTim Peters <tim.peters@gmail.com>
Wed, 12 Sep 2001 19:12:49 +0000 (19:12 +0000)
committerTim Peters <tim.peters@gmail.com>
Wed, 12 Sep 2001 19:12:49 +0000 (19:12 +0000)
Inhibited complex unary plus optimization when applied to a complex subtype.
Added PyComplex_CheckExact macro.  Some comments and minor code fiddling.

Include/complexobject.h
Lib/test/test_descr.py
Objects/complexobject.c
Objects/floatobject.c

index edd20698f2de7b60333b3d8d297c69f373ea10f3..b82eb90dcf5e600b5a89d8d2227720e96109d976 100644 (file)
@@ -43,6 +43,7 @@ typedef struct {
 extern DL_IMPORT(PyTypeObject) 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_FromDoubles(double real, double imag);
index b0299790ac0399fb92601201815f31027f1b0f65..f8b7fc7c9f17bc679abed67b2d3664bba0fc6dfd 100644 (file)
@@ -1430,6 +1430,30 @@ def inherits():
     verify(hash(a) == hash(12345.0))
     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):
         _rev = None
         def rev(self):
index 740499319a9fef3b754eb5332adde7bf63afd9ae..a8419e31ae5f23917aa6e0eb90e327d55922fe7a 100644 (file)
@@ -489,8 +489,12 @@ complex_neg(PyComplexObject *v)
 static PyObject *
 complex_pos(PyComplexObject *v)
 {
-       Py_INCREF(v);
-       return (PyObject *)v;
+       if (PyComplex_CheckExact(v)) {
+               Py_INCREF(v);
+               return (PyObject *)v;
+       }
+       else
+               return PyComplex_FromCComplex(v->cval);
 }
 
 static PyObject *
@@ -792,11 +796,12 @@ complex_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
                return NULL;
        if (PyString_Check(r) || PyUnicode_Check(r))
                return complex_subtype_from_string(type, r);
-       if ((nbr = r->ob_type->tp_as_number) == NULL ||
-           nbr->nb_float == NULL ||
-           (i != NULL &&
-            ((nbi = i->ob_type->tp_as_number) == NULL ||
-             nbi->nb_float == NULL))) {
+
+       nbr = r->ob_type->tp_as_number;
+       if (i != NULL)
+               nbi = i->ob_type->tp_as_number;
+       if (nbr == NULL || nbr->nb_float == NULL ||
+           ((i != NULL) && (nbi == NULL || nbi->nb_float == NULL))) {
                PyErr_SetString(PyExc_TypeError,
                           "complex() arg can't be converted to complex");
                return NULL;
@@ -826,6 +831,9 @@ complex_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
                }
        }
        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;
                if (own_r) {
                        Py_DECREF(r);
@@ -868,10 +876,10 @@ complex_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
 }
 
 static char complex_doc[] =
-"complex(real[, imag]) -> complex number\n\
-\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.";
+"complex(real[, imag]) -> complex number\n"
+"\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.";
 
 static PyNumberMethods complex_as_number = {
        (binaryfunc)complex_add,                /* nb_add */
index 880eb0e1e032c9a0d0242edf9db2d48b6e666807..b9a5e1b84d77016af9443605e47bfe29d2610fa3 100644 (file)
@@ -659,7 +659,7 @@ float_subtype_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
        tmp = float_new(&PyFloat_Type, args, kwds);
        if (tmp == NULL)
                return NULL;
-       assert(PyFloat_Check(tmp));
+       assert(PyFloat_CheckExact(tmp));
        new = type->tp_alloc(type, 0);
        if (new == NULL)
                return NULL;