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

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.cpython_only
>>> +    def test_base_arg_with_no_x_arg(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) <<where x is s string>>
>>
>> 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