Added support for walrus (assignment) operator within set literal expressions if the python version is >= 3.10. The grammar was changed in 3.10 to support this. This addresses #8216.

This commit is contained in:
Eric Traut 2024-06-24 23:56:08 +02:00
parent 3a263135ab
commit bc1fc9f22b
2 changed files with 25 additions and 8 deletions

View File

@ -866,18 +866,22 @@ export namespace BinaryOperationNode {
export interface AssignmentExpressionNode extends ParseNodeBase {
readonly nodeType: ParseNodeType.AssignmentExpression;
name: NameNode;
walrusToken: Token;
rightExpression: ExpressionNode;
isParenthesized: boolean;
}
export namespace AssignmentExpressionNode {
export function create(name: NameNode, rightExpression: ExpressionNode) {
export function create(name: NameNode, walrusToken: Token, rightExpression: ExpressionNode) {
const node: AssignmentExpressionNode = {
start: name.start,
length: name.length,
nodeType: ParseNodeType.AssignmentExpression,
id: _nextNodeId++,
name,
walrusToken,
rightExpression,
isParenthesized: false,
};
name.parent = node;

View File

@ -3184,7 +3184,7 @@ export class Parser {
const rightExpr = this._parseTestExpression(/* allowAssignmentExpression */ false);
return AssignmentExpressionNode.create(leftExpr, rightExpr);
return AssignmentExpressionNode.create(leftExpr, walrusToken, rightExpr);
}
// or_test: and_test ('or' and_test)*
@ -3910,11 +3910,11 @@ export class Parser {
possibleTupleNode.parenthesized = true;
}
if (possibleTupleNode.nodeType === ParseNodeType.StringList) {
possibleTupleNode.isParenthesized = true;
}
if (possibleTupleNode.nodeType === ParseNodeType.Comprehension) {
if (
possibleTupleNode.nodeType === ParseNodeType.StringList ||
possibleTupleNode.nodeType === ParseNodeType.Comprehension ||
possibleTupleNode.nodeType === ParseNodeType.AssignmentExpression
) {
possibleTupleNode.isParenthesized = true;
}
@ -4140,10 +4140,23 @@ export class Parser {
if (this._consumeTokenIfOperator(OperatorType.Power)) {
doubleStarExpression = this._parseExpression(/* allowUnpack */ false);
} else {
keyExpression = this._parseTestOrStarExpression(/* allowAssignmentExpression */ false);
keyExpression = this._parseTestOrStarExpression(/* allowAssignmentExpression */ true);
// Allow walrus operators in this context only for Python 3.10 and newer.
// Older versions of Python generated a syntax error in this context.
let isWalrusAllowed = this._getLanguageVersion().isGreaterOrEqualTo(pythonVersion3_10);
if (this._consumeTokenIfType(TokenType.Colon)) {
valueExpression = this._parseTestExpression(/* allowAssignmentExpression */ false);
isWalrusAllowed = false;
}
if (
!isWalrusAllowed &&
keyExpression.nodeType === ParseNodeType.AssignmentExpression &&
!keyExpression.isParenthesized
) {
this._addSyntaxError(LocMessage.walrusNotAllowed(), keyExpression.walrusToken);
}
}