Why is "1.real" a syntax error but "1 .real" valid in Python?
So I saw these two questions on twitter. How is 1.real
a syntax error but 1 .real
is not?
>>> 1.real
File "<stdin>", line 1
1.real
^
SyntaxError: invalid syntax
>>> 1 .real
1
>>> 1. real
File "<stdin>", line 1
1. real
^
SyntaxError: invalid syntax
>>> 1 . real
1
>>> 1..real
1.0
>>> 1 ..real
File "<stdin>", line 1
1 ..real
^
SyntaxError: invalid syntax
>>> 1.. real
1.0
>>> 1 .. real
File "<stdin>", line 1
1 .. real
^
SyntaxError: invalid syntax
I guess that the .
is greedily parsed as part of a number, if possible, making it the float
1.
, instead of being part of the method call.
Spaces are not allowed around the decimal point, but you can have spaces before and after the .
in a method call. If the number is followed by a space, the parse of the number is terminated, so it's unambiguous.
Let's look at the different cases and how they are parsed:
>>> 1.real # parsed as (1.)real -> missing '.'
>>> 1 .real # parsed as (1).real -> okay
>>> 1. real # parsed as (1.)real -> missing '.'
>>> 1 . real # parsed as (1).real -> okay
>>> 1..real # parsed as (1.).real -> okay
>>> 1 ..real # parsed as (1)..real -> one '.' too much
>>> 1.. real # parsed as (1.).real -> okay
>>> 1 .. real # parsed as (1)..real -> one '.' too much
With 1.real
Python is looking for a floating-point numeric literal like 1.0
and you can't have an r
in a float. With 1 .real
Python has taken 1
as an integer and is doing the attribute lookup on that.
It's important to note that the floating-point syntax error handling happens before the .
attribute lookup.
1 .real works because it is the attribute .real called on the integer 1.
1.real does not work, because you imperatively need a space at the end of a float. Otherwise it is a syntax error.