[Python-Dev] [Python-checkins] cpython (3.3): Issue #16045: add more unit tests for built-in int() (original) (raw)

Terry Reedy tjreedy at udel.edu
Mon Dec 24 03:19:14 CET 2012


On 12/23/2012 4:47 PM, Chris Jerdonek wrote:

On Sun, Dec 23, 2012 at 12:03 PM, Terry Reedy <tjreedy at udel.edu> wrote:

+ # For example, PyPy 1.9.0 raised TypeError for these cases because it + # expects x to be a string if base is given. + @support.cpythononly + def testbaseargwithnoxarg(self): + self.assertEquals(int(base=6), 0) + # Even invalid bases don't raise an exception. + self.assertEquals(int(base=1), 0) + self.assertEquals(int(base=1000), 0) + self.assertEquals(int(base='foo'), 0)

I think the above behavior is buggy and should be changed rather than frozen into CPython with a test. According to the docs, PyPy does it right.

In any case, the discrepancy between doc and behavior is a bug and should be fixed one way or the other way. Unlike int(), I do not see a realistic use case for int(base=x) that would make it anything other than a bug.

I support further discussion here. (I did draft the patch, but it was a first version. I did not commit the patch.)

The current online doc gives the signature as int(x=0) int(x, base=10) <>

The 3.3.0 docstring says "When converting a string, use the optional base. It is an error to supply a base when converting a non-string." One way to partially explain CPython's behavior is that when base is provided, the function behaves as if x defaults to '0' rather than 0.

That explanation does not work. int('0', base = invalid) and int(x='0', base=invalid) raise TypeError or ValueError. If providing a value explicit changes behavior, then that value is not the default. To make '0' really be the base-present default, the doc and above behavior should be changed. Or, make '' the default and have int('', base=whatever) return 0 instead of raising. (This would be the actual parallel to the str case.)

This is similar to the behavior of str(), which defaults to b'' when encoding or errors is provided, but otherwise defaults to '':

This is different. Providing b'' explicitly has no effect. str(encoding=x, errors=y) and str(b'', encoding=x, errors=y) act the same. If x or y is not a string, both raise TypeError. (Unlike int and base.) A bad encoding string is ignored because the encoding lookup is not done unless there is something to encode. (This is why the ignore-base base-default should be '', not '0'.) A bad error specification is (I believe) ignored for any error-free bytes/encoding pair because, again, the lookup is only done when needed.

http://docs.python.org/dev/library/stdtypes.html#str

Certainly, accepting any object as a base, violating "The allowed values are 0 and 2-36." just because giving a base is itself invalid is crazy. For further background (and you can see this is the 2.7 commit), int(base='foo') did raise TypeError in 2.7, but this particular case was relaxed in Python 3.

Since the doc was not changed, that introduced a bug.

-- Terry Jan Reedy



More information about the Python-Dev mailing list