We can manually parse the statement to tokens and see how cpython works here

$ echo "1.__str__()" | python3 tokenize.py
1,0-1,2: NUMBER '1.'
1,2-1,9: NAME '__str__'
1,9-1,10: OP '('
1,10-1,11: OP ')'
1,11-1,12: NEWLINE '\n'
2,0-2,0: ENDMARKER ''

we can see here, it takes ‘1.’ to a number, and means Floatnumber is in a higher priority than Intnumber.

So we have two ways to make it work:

>>> (1).__str__()
'1'
$ echo "(1).__str__()" | python3 tokenize.py
1,0-1,1: OP '('
1,1-1,2: NUMBER '1'
1,2-1,3: OP ')'
1,3-1,4: OP '.'
1,4-1,11: NAME '__str__'
1,11-1,12: OP '('
1,12-1,13: OP ')'
1,13-1,14: NEWLINE '\n'
2,0-2,0: ENDMARKER ''
>>> 1..__str__()
'1.0'
$ echo "1..__str__()" | python3 tokenize.py
1,0-1,2: NUMBER '1.'
1,2-1,3: OP '.'
1,3-1,10: NAME '__str__'
1,10-1,11: OP '('
1,11-1,12: OP ')'
1,12-1,13: NEWLINE '\n'
2,0-2,0: ENDMARKER ''

But looks like the second one is not the expected one.

Anyway, that’s all.

--

--