[Python-checkins] cpython: properly lookup the __round__ special method (closes #17722)

benjamin.peterson python-checkins at python.org
Sat Apr 13 23:19:10 CEST 2013


http://hg.python.org/cpython/rev/cc59c215f19e
changeset:   83315:cc59c215f19e
user:        Benjamin Peterson <benjamin at python.org>
date:        Sat Apr 13 17:19:01 2013 -0400
summary:
  properly lookup the __round__ special method (closes #17722)

files:
  Lib/test/test_descr.py |   3 ++-
  Misc/NEWS              |   2 ++
  Python/bltinmodule.c   |  25 +++++++++++--------------
  3 files changed, 15 insertions(+), 15 deletions(-)


diff --git a/Lib/test/test_descr.py b/Lib/test/test_descr.py
--- a/Lib/test/test_descr.py
+++ b/Lib/test/test_descr.py
@@ -1743,7 +1743,7 @@
             return b"hello"
         def empty_seq(self):
             return []
-        def zero(self):
+        def zero(self, other=None):
             return 0
         def complex_num(self):
             return 1j
@@ -1789,6 +1789,7 @@
             ("__trunc__", int, zero, set(), {}),
             ("__ceil__", math.ceil, zero, set(), {}),
             ("__dir__", dir, empty_seq, set(), {}),
+            ("__round__", round, zero, set(), {}),
             ]
 
         class Checker(object):
diff --git a/Misc/NEWS b/Misc/NEWS
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -10,6 +10,8 @@
 Core and Builtins
 -----------------
 
+- Issue #17722: When looking up __round__, resolve descriptors.
+
 - Issue #16061: Speed up str.replace() for replacing 1-character strings.
 
 - Issue #17715: Fix segmentation fault from raising an exception in a __trunc__
diff --git a/Python/bltinmodule.c b/Python/bltinmodule.c
--- a/Python/bltinmodule.c
+++ b/Python/bltinmodule.c
@@ -1810,10 +1810,10 @@
 static PyObject *
 builtin_round(PyObject *self, PyObject *args, PyObject *kwds)
 {
-    static PyObject *round_str = NULL;
     PyObject *ndigits = NULL;
     static char *kwlist[] = {"number", "ndigits", 0};
-    PyObject *number, *round;
+    PyObject *number, *round, *result;
+    _Py_IDENTIFIER(__round__);
 
     if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|O:round",
                                      kwlist, &number, &ndigits))
@@ -1824,24 +1824,21 @@
             return NULL;
     }
 
-    if (round_str == NULL) {
-        round_str = PyUnicode_InternFromString("__round__");
-        if (round_str == NULL)
-            return NULL;
-    }
-
-    round = _PyType_Lookup(Py_TYPE(number), round_str);
+    round = _PyObject_LookupSpecial(number, &PyId___round__);
     if (round == NULL) {
-        PyErr_Format(PyExc_TypeError,
-                     "type %.100s doesn't define __round__ method",
-                     Py_TYPE(number)->tp_name);
+        if (!PyErr_Occurred())
+            PyErr_Format(PyExc_TypeError,
+                         "type %.100s doesn't define __round__ method",
+                         Py_TYPE(number)->tp_name);
         return NULL;
     }
 
     if (ndigits == NULL)
-        return PyObject_CallFunction(round, "O", number);
+        result = PyObject_CallFunctionObjArgs(round, NULL);
     else
-        return PyObject_CallFunction(round, "OO", number, ndigits);
+        result = PyObject_CallFunctionObjArgs(round, ndigits, NULL);
+    Py_DECREF(round);
+    return result;
 }
 
 PyDoc_STRVAR(round_doc,

-- 
Repository URL: http://hg.python.org/cpython


More information about the Python-checkins mailing list