Issue #16772: in int(x, base), non-integer bases must have an __index__ method.

This commit is contained in:
Mark Dickinson 2013-01-27 10:17:52 +00:00
parent 3a62e45b97
commit 07c7136524
4 changed files with 27 additions and 5 deletions

View file

@ -665,6 +665,12 @@ are always available. They are listed here in alphabetical order.
The integer type is described in :ref:`typesnumeric`. The integer type is described in :ref:`typesnumeric`.
.. versionchanged:: 3.4
If *base* is not an instance of :class:`int` and the *base* object has a
:meth:`base.__index__ <object.__index__>` method, that method is called
to obtain an integer for the base. Previous versions used
:meth:`base.__int__ <object.__int__>` instead of :meth:`base.__index__
<object.__index__>`.
.. function:: isinstance(object, classinfo) .. function:: isinstance(object, classinfo)

View file

@ -260,6 +260,23 @@ class IntTestCases(unittest.TestCase):
with self.assertRaises(TypeError): with self.assertRaises(TypeError):
int('0', 5.0) int('0', 5.0)
def test_int_base_indexable(self):
class MyIndexable(object):
def __init__(self, value):
self.value = value
def __index__(self):
return self.value
# Check out of range bases.
for base in 2**100, -2**100, 1, 37:
with self.assertRaises(ValueError):
int('43', base)
# Check in-range bases.
self.assertEqual(int('101', base=MyIndexable(2)), 5)
self.assertEqual(int('101', base=MyIndexable(10)), 101)
self.assertEqual(int('101', base=MyIndexable(36)), 1 + 36**2)
def test_non_numeric_input_types(self): def test_non_numeric_input_types(self):
# Test possible non-numeric types for the argument x, including # Test possible non-numeric types for the argument x, including
# subclasses of the explicitly documented accepted types. # subclasses of the explicitly documented accepted types.

View file

@ -10,6 +10,10 @@ What's New in Python 3.4.0 Alpha 1?
Core and Builtins Core and Builtins
----------------- -----------------
- Issue #16772: The base argument to the int constructor no longer accepts
floats, or other non-integer objects with an __int__ method. Objects
with an __index__ method are now accepted.
- Issue #10156: In the interpreter's initialization phase, unicode globals - Issue #10156: In the interpreter's initialization phase, unicode globals
are now initialized dynamically as needed. are now initialized dynamically as needed.

View file

@ -4283,11 +4283,6 @@ long_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
} }
if (obase == NULL) if (obase == NULL)
return PyNumber_Long(x); return PyNumber_Long(x);
if (!PyLong_Check(obase)) {
PyErr_SetString(PyExc_TypeError,
"int() base must be an integer.");
return NULL;
}
base = PyNumber_AsSsize_t(obase, NULL); base = PyNumber_AsSsize_t(obase, NULL);
if (base == -1 && PyErr_Occurred()) if (base == -1 && PyErr_Occurred())