]> granicus.if.org Git - python/commitdiff
Close SF bug 563740. complex() now finds __complex__() in new style classes.
authorRaymond Hettinger <python@rcn.com>
Thu, 6 Jun 2002 15:45:38 +0000 (15:45 +0000)
committerRaymond Hettinger <python@rcn.com>
Thu, 6 Jun 2002 15:45:38 +0000 (15:45 +0000)
Made conversion failure error messages consistent between types.
Added related unittests.

Lib/test/test_b1.py
Objects/abstract.c
Objects/complexobject.c

index 56a5f783c4e1a000f6201930c2f158553cb59d31..afa0cf32f58a9366a74aa533b1be404ce56d4d17 100644 (file)
@@ -101,6 +101,17 @@ print 'compile'
 compile('print 1\n', '', 'exec')
 
 print 'complex'
+class OS:
+   def __complex__(self): return 1+10j
+class NS(object):
+   def __complex__(self): return 1+10j
+if complex(OS()) != 1+10j: raise TestFailed, '__complex__ in old style class'
+if complex(NS()) != 1+10j: raise TestFailed, '__complex__ in new style class'
+if complex("1+10j") != 1+10j: raise TestFailed, 'complex("1+10j")'
+if complex(10) != 10+0j: raise TestFailed, 'complex(10)'
+if complex(10.0) != 10+0j: raise TestFailed, 'complex(10.0)'
+if complex(10L) != 10+0j: raise TestFailed, 'complex(10L)'
+if complex(10+0j) != 10+0j: raise TestFailed, 'complex(10+0j)'
 if complex(1,10) != 1+10j: raise TestFailed, 'complex(1,10)'
 if complex(1,10L) != 1+10j: raise TestFailed, 'complex(1,10L)'
 if complex(1,10.0) != 1+10j: raise TestFailed, 'complex(1,10.0)'
index 917195a200bcdfe1e470ac183059ebb6c15751f2..1f9b60346ef4f311c84fb77f03c8c8eb4db4b761 100644 (file)
@@ -903,7 +903,7 @@ PyNumber_Int(PyObject *o)
        if (!PyObject_AsCharBuffer(o, &buffer, &buffer_len))
                return int_from_string((char*)buffer, buffer_len);
 
-       return type_error("object can't be converted to int");
+       return type_error("int() argument must be a string or a number");
 }
 
 /* Add a check for embedded NULL-bytes in the argument. */
@@ -960,7 +960,7 @@ PyNumber_Long(PyObject *o)
        if (!PyObject_AsCharBuffer(o, &buffer, &buffer_len))
                return long_from_string(buffer, buffer_len);
 
-       return type_error("object can't be converted to long");
+       return type_error("long() argument must be a string or a number");
 }
 
 PyObject *
index adcf85a9fadae29631486b50999383869906af69..774c5463fc3f909f7d17ff5c6864b695a960c830 100644 (file)
@@ -811,10 +811,11 @@ complex_subtype_from_string(PyTypeObject *type, PyObject *v)
 static PyObject *
 complex_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
 {
-       PyObject *r, *i, *tmp;
+       PyObject *r, *i, *tmp, *f;
        PyNumberMethods *nbr, *nbi = NULL;
        Py_complex cr, ci;
        int own_r = 0;
+       static PyObject *complexstr;
        static char *kwlist[] = {"real", "imag", 0};
 
        r = Py_False;
@@ -837,39 +838,35 @@ complex_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
                return NULL;
        }
 
+       /* XXX Hack to support classes with __complex__ method */
+       if (complexstr == NULL) {
+               complexstr = PyString_InternFromString("__complex__");
+               if (complexstr == NULL)
+                       return NULL;
+       }
+       f = PyObject_GetAttr(r, complexstr);
+       if (f == NULL)
+               PyErr_Clear();
+       else {
+               PyObject *args = Py_BuildValue("()");
+               if (args == NULL)
+                       return NULL;
+               r = PyEval_CallObject(f, args);
+               Py_DECREF(args);
+               Py_DECREF(f);
+               if (r == NULL)
+                       return NULL;
+               own_r = 1;
+       }
        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");
+                          "complex() argument must be a string or a number");
                return NULL;
        }
-       /* XXX Hack to support classes with __complex__ method */
-       if (PyInstance_Check(r)) {
-               static PyObject *complexstr;
-               PyObject *f;
-               if (complexstr == NULL) {
-                       complexstr = PyString_InternFromString("__complex__");
-                       if (complexstr == NULL)
-                               return NULL;
-               }
-               f = PyObject_GetAttr(r, complexstr);
-               if (f == NULL)
-                       PyErr_Clear();
-               else {
-                       PyObject *args = Py_BuildValue("()");
-                       if (args == NULL)
-                               return NULL;
-                       r = PyEval_CallObject(f, args);
-                       Py_DECREF(args);
-                       Py_DECREF(f);
-                       if (r == NULL)
-                               return NULL;
-                       own_r = 1;
-               }
-       }
        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