-
-
Notifications
You must be signed in to change notification settings - Fork 34.2k
Description
Bug report
Bug description:
The syntax for a conditional expression changes depending on the context the logic is found in: If in a conditional expression, or if in a statement.
This can be verified by checking the full grammar specification, which uses an if symbol in two distinct places, once in the "if_stmt" production (itself referenced as an alternative in the "compound_stmt" production) and again as one of a few alternatives for the "expression" production. This would ordinarily be an acceptable way to factor the grammar, if not for the fact that the order of evaluation is inconsistent: the "if_stmt" production accepts expressions in "test, then, else" order and the "expression" production accepts statements in the "then, test, else" order. Unsurprisingly, this is confusing.
And this also violates a long-standing expectation that evaluation happens in a defined order; if I have any two expressions a and b, in that order in a file, the result of b should never impact the evaluation of a, unless a could sometimes impact b (in which case the rule is ambiguous).
Here, when reading the expression production disjunction 'if' disjunction 'else' expression, that ordering suggests that the first "disjunction" would be evaluated first, and the value will affect the execution of the second disjunction.
But in the actual execution, this is not the case:
def x(n):
print(n);
return n;
x(x(1) if x(2) else x(3));In this file, I should expect to see 1 be the first line of output, but surprisingly it's 2: It's skipping over the evaluation of x(1), running x(2), then deciding based on the return value to evaluate x(1).
This mistake appears to have been introduced in https://mail.python.org/pipermail/python-dev/2005-September/056846.html then formalized in https://peps.python.org/pep-0308/
CPython versions tested on:
3.11
Operating systems tested on:
macOS