Is it legal/valid to use float() to convert a string containing integer to float?

Hi,

I’m wondering if float(‘10’) (or any integer string) can be safely converted using float() to float number. Documentation of float() states that:

the input must conform to the following grammar after leading and trailing whitespace characters are removed:

sign           ::=  "+" | "-"
infinity       ::=  "Infinity" | "inf"
nan            ::=  "nan"
numeric_value  ::=  floatnumber | infinity | nan
numeric_string ::=  [sign] numeric_value

where floatnumber, described in Floating point literals is:

floatnumber   ::=  pointfloat | exponentfloat
pointfloat    ::=  [digitpart] fraction | digitpart "."
exponentfloat ::=  (digitpart | pointfloat) exponent
digitpart     ::=  digit (["_"] digit)*
fraction      ::=  "." digitpart
exponent      ::=  ("e" | "E") ["+" | "-"] digitpart

So, according to documentation float(‘10’) is not allowed or rather not defined. Interpreters I’ve used so far have no problem with that and return a valid/expected value (10.0). Is that legal/safe/portable, though? or float(int(‘10’)) should be used instead for a maximum safety?

EDIT: floor → float

Thanks

2 Likes

float('10') is fine. Try it and see:

>>> float('10')
10.0

The OP’s question is not if it works, but whether it works by accident or by design. The documentation suggests the former.

if it is not allowed to have integer strings as input then one of the examples in the documentation would be wrong where it shows float(' -12345\n') gives -12345.0, so I believe the intention was definitely to allow it, it is just a bug in the documentation

also, the two major implementations, cpython and pypy both work as expected, so pretty sure a lot of people already rely on it and it won’t be changed anytime soon even if it was not intended

It seems that ‘integer’ should be added to the “numeric_value” production/

Whether by accident or design, it has worked since at least Python 1.5 and if it were ever changed, that would break backwards compatibility.

The documentation shows five examples of legal strings, one of which is exactly of the form suggested:

>>> float('   -12345\n')
-12345.0

So this is documented as working.

Good spot! It’s got to be intentional that float('10') works; we should fix the grammar in the documentation. Want to open an issue on the CPython repo?

Terry’s suggestion is about right, but should probably be decinteger, not integer. Although actually, I think that doesn’t quite match the way float handles leading zeros. (We could also describe it less formally, like is done for int )

1 Like

Done.

2 Likes

Thank you everyone for clarification.