Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 214a7d2

Browse files
committed
properly lookup the __round__ special method (closes #17722)
1 parent c1ab0bd commit 214a7d2

3 files changed

Lines changed: 15 additions & 15 deletions

File tree

Lib/test/test_descr.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1743,7 +1743,7 @@ def hello(self):
17431743
return b"hello"
17441744
def empty_seq(self):
17451745
return []
1746-
def zero(self):
1746+
def zero(self, other=None):
17471747
return 0
17481748
def complex_num(self):
17491749
return 1j
@@ -1789,6 +1789,7 @@ def format_impl(self, spec):
17891789
("__trunc__", int, zero, set(), {}),
17901790
("__ceil__", math.ceil, zero, set(), {}),
17911791
("__dir__", dir, empty_seq, set(), {}),
1792+
("__round__", round, zero, set(), {}),
17921793
]
17931794

17941795
class Checker(object):

Misc/NEWS

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ What's New in Python 3.4.0 Alpha 1?
1010
Core and Builtins
1111
-----------------
1212

13+
- Issue #17722: When looking up __round__, resolve descriptors.
14+
1315
- Issue #16061: Speed up str.replace() for replacing 1-character strings.
1416

1517
- Issue #17715: Fix segmentation fault from raising an exception in a __trunc__

Python/bltinmodule.c

Lines changed: 11 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1810,10 +1810,10 @@ For most object types, eval(repr(object)) == object.");
18101810
static PyObject *
18111811
builtin_round(PyObject *self, PyObject *args, PyObject *kwds)
18121812
{
1813-
static PyObject *round_str = NULL;
18141813
PyObject *ndigits = NULL;
18151814
static char *kwlist[] = {"number", "ndigits", 0};
1816-
PyObject *number, *round;
1815+
PyObject *number, *round, *result;
1816+
_Py_IDENTIFIER(__round__);
18171817

18181818
if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|O:round",
18191819
kwlist, &number, &ndigits))
@@ -1824,24 +1824,21 @@ builtin_round(PyObject *self, PyObject *args, PyObject *kwds)
18241824
return NULL;
18251825
}
18261826

1827-
if (round_str == NULL) {
1828-
round_str = PyUnicode_InternFromString("__round__");
1829-
if (round_str == NULL)
1830-
return NULL;
1831-
}
1832-
1833-
round = _PyType_Lookup(Py_TYPE(number), round_str);
1827+
round = _PyObject_LookupSpecial(number, &PyId___round__);
18341828
if (round == NULL) {
1835-
PyErr_Format(PyExc_TypeError,
1836-
"type %.100s doesn't define __round__ method",
1837-
Py_TYPE(number)->tp_name);
1829+
if (!PyErr_Occurred())
1830+
PyErr_Format(PyExc_TypeError,
1831+
"type %.100s doesn't define __round__ method",
1832+
Py_TYPE(number)->tp_name);
18381833
return NULL;
18391834
}
18401835

18411836
if (ndigits == NULL)
1842-
return PyObject_CallFunction(round, "O", number);
1837+
result = PyObject_CallFunctionObjArgs(round, NULL);
18431838
else
1844-
return PyObject_CallFunction(round, "OO", number, ndigits);
1839+
result = PyObject_CallFunctionObjArgs(round, ndigits, NULL);
1840+
Py_DECREF(round);
1841+
return result;
18451842
}
18461843

18471844
PyDoc_STRVAR(round_doc,

0 commit comments

Comments
 (0)