diff options
author | Benjamin Peterson <benjamin@python.org> | 2013-04-13 17:19:01 -0400 |
---|---|---|
committer | Benjamin Peterson <benjamin@python.org> | 2013-04-13 17:19:01 -0400 |
commit | 214a7d267471b22cd458bcdac0ca74d22f2ad96a (patch) | |
tree | cbbb0ff7687599b4e481f4cc2e6de8c1d24a110e | |
parent | c1ab0bd788eeaab6816d5ab2b4a691513c4c9228 (diff) | |
download | cpython-git-214a7d267471b22cd458bcdac0ca74d22f2ad96a.tar.gz |
properly lookup the __round__ special method (closes #17722)
-rw-r--r-- | Lib/test/test_descr.py | 3 | ||||
-rw-r--r-- | Misc/NEWS | 2 | ||||
-rw-r--r-- | 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 index 3776389ebb..ed4b289954 100644 --- a/Lib/test/test_descr.py +++ b/Lib/test/test_descr.py @@ -1743,7 +1743,7 @@ order (MRO) for bases """ 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 @@ order (MRO) for bases """ ("__trunc__", int, zero, set(), {}), ("__ceil__", math.ceil, zero, set(), {}), ("__dir__", dir, empty_seq, set(), {}), + ("__round__", round, zero, set(), {}), ] class Checker(object): @@ -10,6 +10,8 @@ What's New in Python 3.4.0 Alpha 1? 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 index a486b4978c..5291565b81 100644 --- a/Python/bltinmodule.c +++ b/Python/bltinmodule.c @@ -1810,10 +1810,10 @@ For most object types, eval(repr(object)) == object."); 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 @@ builtin_round(PyObject *self, PyObject *args, PyObject *kwds) 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, |