properly lookup the __round__ special method (closes #17722)

This commit is contained in:
Benjamin Peterson 2013-04-13 17:19:01 -04:00
parent c1ab0bd788
commit 214a7d2674
3 changed files with 15 additions and 15 deletions

View File

@ -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):

View File

@ -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__

View File

@ -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,