Bug in int('+␣42')?

The documentation of int(x) and int(x, base=10) specifies:
“If x is not a number or if base is given, then x must be a string, bytes, or bytearray instance representing an integer in radix base. Optionally, the string can be preceded by + or - (with no space in between), have leading zeros, be surrounded by whitespace, and have single underscores interspersed between digits.”
https://docs.python.org/3/library/functions.html?#int
The Python 2 documentation is similar:
https://docs.python.org/2.7/library/functions.html?#int

int('+␣42') is valid or not?
The Python 3 implementation (at least from 3.5.9 to 3.11.0) reject spaces between the sign and the integer. That is the expected behaviour by the documentation.
But spaces between the sign and the integer are valid for Pypy 3.7, Python 2.7, Pypy 2.7 and Jython 2.7!

Is it really a bug or is there no really a precise specification and it is implementation dependent?
I expected that implementations raise a ValuerError for these kind of values.

float('+␣42') is rejected by all implementations.

The expected behavior, by Python 3:

Python 3.9.2 (default, Feb 28 2021, 17:03:44)
[GCC 10.2.1 20210110] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> int('+ 42')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: invalid literal for int() with base 10: '+ 42'
>>> int('- 42')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: invalid literal for int() with base 10: '- 42'
>>> float('+ 42')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: could not convert string to float: '+ 42'

See https://gcc.godbolt.org/z/ETe731KPj to try other Python 3 versions.

The unexpected behavior, by Pypy 3, Python 2, Pypy 2 and Jython 2:

Python 3.7.10 (7.3.5+dfsg-2+deb11u2, Nov 01 2022, 20:16:36)
[PyPy 7.3.5 with GCC 10.2.1 20210110] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>>> int('+ 42')
42
>>>> int('- 42')
-42
>>>> float('+ 42')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: could not convert string to float: '+ 42'
Python 2.7.18 (default, Jul 14 2021, 08:11:37)
[GCC 10.2.1 20210110] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> int('+ 42')
42
>>> int('- 42')
-42
>>> float('+ 42')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: could not convert string to float: + 42
Python 2.7.18 (7.3.3+dfsg-2, May 02 2021, 15:10:01)
[PyPy 7.3.3 with GCC 10.2.1 20210110] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>>> int('+ 42')
42
>>>> int('- 42')
-42
>>>> float('+ 42')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: could not convert string to float: '+ 42'
Jython 2.7.2-DEV (uncontrolled:+, Jan 3 1970, 22:46:05)
[OpenJDK 64-Bit Server VM (Debian)] on java11.0.18
Type "help", "copyright", "credits" or "license" for more information.
>>> int('+ 42')
42
>>> int('- 42')
-42
>>> float('+ 42')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: invalid literal for float: + 42

Is it really a bug or is there no really a precise specification and it is implementation dependent?

It is a bug. While this forum is called “python” it is primarily CPython-oriented. Please open an issue on the PyPy issue tracker.

1 Like

I will do that. But it is also a bug in CPython 2.
I will also report for that.

CPython 2 is no longer maintained so no need to report for that one.

4 Likes

That’s it:

Nice spot! Thanks for helping improve compatibility between PyPy and CPython!

Since I recently changed some of the documentation here in https://github.com/python/cpython/pull/100436, I was curious how far back the “no space in between” wording goes. Looks like it was introduced in this commit: #2580: int() docs revision. · python/cpython@225d3c8 · GitHub

1 Like

Does CPython int tests have one to test that int('+ 1') raises ValueError? It should so that other implementations that do not fail this input will fail the test.

4 Likes

Great point! I think this and a couple other tests were missing, I’ve opened Improve int test coverage by hauntsaninja · Pull Request #104024 · python/cpython · GitHub

2 Likes