You might have heard that everything in Python is an object, even literals.
This means, for example, 7 is an object as well, which means it has attributes.
For example, one of these attributes is the bit_length. It returns the amount of bits needed to represent the value it is called upon.
x = 7
x.bit_length()
# Out: 3
Seeing the above code works, you might intuitively think that 7.bit_length() would work as well, only to find out it raises a SyntaxError. Why? because the interpreter needs to differentiate between an attribute access and a floating number (for example 7.2 or 7.bit_length()). It can't, and that's why an exception is raised.
There are a few ways to access an int literals' attributes:
# parenthesis
(7).bit_length()
# a space
7 .bit_length()
Using two dots (like this 7..bit_length()) doesn't work in this case, because that creates a float literal and floats don't have the bit_length() method.
This problem doesn't exist when accessing float literals' attributes since the interperter is "smart" enough to know that a float literal can't contain two ., for example:
7.2.as_integer_ratio()
# Out: (8106479329266893, 1125899906842624)