mirror of
https://github.com/microsoft/pyright.git
synced 2024-09-19 20:27:45 +03:00
Added code to better handle the obsolete "<>" operator from Python 2 - including a better error message and better parse recovery.
This commit is contained in:
parent
317e853539
commit
2cf7f61fc6
@ -404,6 +404,7 @@ export function printOperator(operator: OperatorType): string {
|
||||
[OperatorType.GreaterThanOrEqual]: '>=',
|
||||
[OperatorType.LeftShift]: '<<',
|
||||
[OperatorType.LeftShiftEqual]: '<<=',
|
||||
[OperatorType.LessOrGreaterThan]: '<>',
|
||||
[OperatorType.LessThan]: '<',
|
||||
[OperatorType.LessThanOrEqual]: '<=',
|
||||
[OperatorType.MatrixMultiply]: '@',
|
||||
|
@ -398,6 +398,7 @@ export namespace Localizer {
|
||||
new ParameterizedString<{ name: string }>(getRawString('Diagnostic.obscuredParameterDeclaration'));
|
||||
export const obscuredVariableDeclaration = () =>
|
||||
new ParameterizedString<{ name: string }>(getRawString('Diagnostic.obscuredVariableDeclaration'));
|
||||
export const operatorLessOrGreaterDeprecated = () => getRawString('Diagnostic.operatorLessOrGreaterDeprecated');
|
||||
export const optionalExtraArgs = () => getRawString('Diagnostic.optionalExtraArgs');
|
||||
export const paramAfterKwargsParam = () => getRawString('Diagnostic.paramAfterKwargsParam');
|
||||
export const paramAlreadyAssigned = () =>
|
||||
|
@ -182,6 +182,7 @@
|
||||
"obscuredFunctionDeclaration": "Function declaration \"{name}\" is obscured by a declaration of the same name",
|
||||
"obscuredParameterDeclaration": "Parameter declaration \"{name}\" is obscured by a declaration of the same name",
|
||||
"obscuredVariableDeclaration": "Declaration \"{name}\" is obscured by a declaration of the same name",
|
||||
"operatorLessOrGreaterDeprecated": "Operator \"<>\" is not supported in Python 3; use \"!=\" instead",
|
||||
"optionalExtraArgs": "Expected one type argument after \"Optional\"",
|
||||
"paramAfterKwargsParam": "Parameter cannot follow \"**\" parameter",
|
||||
"paramAlreadyAssigned": "Parameter \"{name}\" is already assigned",
|
||||
|
@ -1805,6 +1805,10 @@ export class Parser {
|
||||
|
||||
if (Tokenizer.isOperatorComparison(this._peekOperatorType())) {
|
||||
comparisonOperator = this._peekOperatorType();
|
||||
if (comparisonOperator === OperatorType.LessOrGreaterThan) {
|
||||
this._addError(Localizer.Diagnostic.operatorLessOrGreaterDeprecated(), peekToken);
|
||||
comparisonOperator = OperatorType.NotEquals;
|
||||
}
|
||||
this._getNextToken();
|
||||
} else if (this._consumeTokenIfKeyword(KeywordType.In)) {
|
||||
comparisonOperator = OperatorType.In;
|
||||
|
@ -94,6 +94,7 @@ const _operatorInfo: { [key: number]: OperatorFlags } = {
|
||||
[OperatorType.GreaterThanOrEqual]: OperatorFlags.Binary | OperatorFlags.Comparison,
|
||||
[OperatorType.LeftShift]: OperatorFlags.Binary,
|
||||
[OperatorType.LeftShiftEqual]: OperatorFlags.Assignment,
|
||||
[OperatorType.LessOrGreaterThan]: OperatorFlags.Binary | OperatorFlags.Comparison | OperatorFlags.Deprecated,
|
||||
[OperatorType.LessThan]: OperatorFlags.Binary | OperatorFlags.Comparison,
|
||||
[OperatorType.LessThanOrEqual]: OperatorFlags.Binary | OperatorFlags.Comparison,
|
||||
[OperatorType.MatrixMultiply]: OperatorFlags.Binary,
|
||||
@ -869,6 +870,9 @@ export class Tokenizer {
|
||||
if (nextChar === Char.Less) {
|
||||
length = this._cs.lookAhead(2) === Char.Equal ? 3 : 2;
|
||||
operatorType = length === 3 ? OperatorType.LeftShiftEqual : OperatorType.LeftShift;
|
||||
} else if (nextChar === Char.Greater) {
|
||||
length = 2;
|
||||
operatorType = OperatorType.LessOrGreaterThan;
|
||||
} else {
|
||||
length = nextChar === Char.Equal ? 2 : 1;
|
||||
operatorType = length === 2 ? OperatorType.LessThanOrEqual : OperatorType.LessThan;
|
||||
|
@ -68,6 +68,7 @@ export const enum OperatorType {
|
||||
GreaterThanOrEqual,
|
||||
LeftShift,
|
||||
LeftShiftEqual,
|
||||
LessOrGreaterThan,
|
||||
LessThan,
|
||||
LessThanOrEqual,
|
||||
MatrixMultiply,
|
||||
@ -101,6 +102,7 @@ export const enum OperatorFlags {
|
||||
Binary = 1 << 1,
|
||||
Assignment = 1 << 2,
|
||||
Comparison = 1 << 3,
|
||||
Deprecated = 1 << 4,
|
||||
}
|
||||
|
||||
export const enum KeywordType {
|
||||
|
@ -536,6 +536,12 @@ test('Operators4', () => {
|
||||
validateResults(analysisResults, 0);
|
||||
});
|
||||
|
||||
test('Operators5', () => {
|
||||
const analysisResults = TestUtils.typeAnalyzeSampleFiles(['operators5.py']);
|
||||
|
||||
validateResults(analysisResults, 1);
|
||||
});
|
||||
|
||||
test('Optional1', () => {
|
||||
const configOptions = new ConfigOptions('.');
|
||||
|
||||
|
5
server/src/tests/samples/operators5.py
Normal file
5
server/src/tests/samples/operators5.py
Normal file
@ -0,0 +1,5 @@
|
||||
# This sample tests the parsing of the deprecated <> operator.
|
||||
|
||||
# This should generate a single error, not a cascade of errors.
|
||||
if 3 <> 5:
|
||||
print("OK")
|
@ -1259,9 +1259,9 @@ test('Operators', () => {
|
||||
'* ** / // /= //=' +
|
||||
'*= += -= %= **= ' +
|
||||
'& &= | |= ^ ^= ' +
|
||||
':=';
|
||||
':= <>';
|
||||
const results = new Tokenizer().tokenize(text);
|
||||
const lengths = [1, 2, 3, 2, 2, 1, 2, 3, 2, 2, 1, 1, 1, 1, 1, 2, 1, 2, 2, 3, 2, 2, 2, 2, 3, 1, 2, 1, 2, 1, 2, 2];
|
||||
const lengths = [1, 2, 3, 2, 2, 1, 2, 3, 2, 2, 1, 1, 1, 1, 1, 2, 1, 2, 2, 3, 2, 2, 2, 2, 3, 1, 2, 1, 2, 1, 2, 2, 2];
|
||||
const operatorTypes = [
|
||||
OperatorType.LessThan,
|
||||
OperatorType.LeftShift,
|
||||
@ -1295,6 +1295,7 @@ test('Operators', () => {
|
||||
OperatorType.BitwiseXor,
|
||||
OperatorType.BitwiseXorEqual,
|
||||
OperatorType.Walrus,
|
||||
OperatorType.LessOrGreaterThan,
|
||||
];
|
||||
assert.equal(results.tokens.count - _implicitTokenCount, lengths.length);
|
||||
assert.equal(results.tokens.count - _implicitTokenCount, operatorTypes.length);
|
||||
|
Loading…
Reference in New Issue
Block a user