Noticed a line in our codebase today which I thought surely would have failed the build with syntax error, but tests were passing so apparently it was actually valid python (in both 2.x and 3).
Whitespace is sometimes not required in the conditional expression:
>>> 1if True else 0
1
It doesn't work if the LHS is a variable:
>>> x = 1
>>> xif True else 0
File "<stdin>", line 1
xif True else 0
^
SyntaxError: invalid syntax
But it does seem to still work with other types of literals:
>>> {'hello'}if False else 'potato'
'potato'
What's going on here, is it intentionally part of the grammar for some reason? Is this odd quirk a known/documented behaviour?
With my limited knowledge of lexical processing and tokenizing I'd say what you're seeing is that any piece that can be lexical parsed as "different" (i.e. numbers/dictionaries, etc...) from the
if
are being done so. Most languages ignore spaces and I imagine that Python does the same (excluding, of course indentation levels). Once tokens are generated the grammar itself doesn't care, it most likely looks for an[EXPRESSION] [IF] [EXPRESSION] [ELSE] [EXPRESSION]
grouping, which, again with your examples, would work fine.So in this case,
1if
is not a valid token, so the whitespace is optional. The1
is interpreted as an integer literal of which theif
is not a part. Soif
is interpreted separately and recognized as a keyword.In
xif
however, an identifier is recognized, so Python is not able to see that you wanted to dox if
there.The Python lexer generates two tokens for the input
1if
: the integer1
and the keywordif
, since no token that begins with a digit can contain the stringif
.xif
, on the other hand, is recognized as a valid identifier; there is no reason to believe that it is an identifier followed by a keyword, and so is passed to the parser as a single token.