8000 Fixed a bug that resulted in a false positive error when `LiteralStri… · codean-io/scip-python@4be5d04 · GitHub
[go: up one dir, main page]

Skip to content

Commit 4be5d04

Browse files
committed
Fixed a bug that resulted in a false positive error when LiteralString was used as the base type in an index expression.
1 parent 6ad84ae commit 4be5d04

File tree

4 files changed

+20
-38
lines changed

4 files changed

+20
-38
lines changed

packages/pyright-internal/src/analyzer/typeEvaluator.ts

Lines changed: 10 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -4782,15 +4782,6 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions
47824782
isAsymmetricDescriptor = true;
47834783
}
47844784
} else {
4785-
// Handle the special case of LiteralString.
4786-
if (
4787-
ClassType.isBuiltIn(baseType, 'LiteralString') &&
4788-
strClassType &&
4789-
isInstantiableClass(strClassType)
4790-
) {
4791-
baseType = ClassType.cloneAsInstance(strClassType);
4792-
}
4793-
47944785
// Handle the special case of 'name' and 'value' members within an enum.
47954786
const enumMemberResult = getTypeOfEnumMember(
47964787
evaluatorInterface,
@@ -11883,15 +11874,6 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions
1188311874
return subtype;
1188411875
}
1188511876

11886-
if (
11887-
isClassInstance(subtype) &&
11888-
ClassType.isBuiltIn(subtype, 'LiteralString') &&
11889-
strClassType &&
11890-
isInstantiableClass(strClassType)
11891-
) {
11892-
return handleSubtype(ClassType.cloneAsInstance(strClassType));
11893-
}
11894-
1189511877
if (isClassInstance(subtype) || isInstantiableClass(subtype) || isTypeVar(subtype)) {
1189611878
return handleSubtype(subtype);
1189711879
}
@@ -14080,7 +14062,16 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions
1408014062
assert(isInstantiableClass(cachedType));
1408114063
return cachedType as ClassType;
1408214064
}
14065+
1408314066
const specialType = createSpecialBuiltInClass(node, assignedName, aliasMapEntry);
14067+
14068+
// Handle 'LiteralString' specially because we want it to act as
14069+
// though it derives from 'str'.
14070+
if (assignedName === 'LiteralString') {
14071+
specialType.details.baseClasses.push(strClassType ?? AnyType.create());
14072+
computeMroLinearization(specialType);
14073+
}
14074+
1408414075
writeTypeCache(node, specialType, EvaluatorFlags.None, /* isIncomplete */ false);
1408514076
return specialType;
1408614077
}
@@ -21011,7 +21002,7 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions
2101121002
}
2101221003
}
2101321004

21014-
let concreteSrcType = makeTopLevelTypeVarsConcrete(srcType);
21005+
const concreteSrcType = makeTopLevelTypeVarsConcrete(srcType);
2101521006
if (isClass(concreteSrcType) && TypeBase.isInstance(concreteSrcType)) {
2101621007
if (destType.literalValue !== undefined) {
2101721008
const srcLiteral = concreteSrcType.literalValue;
@@ -21031,15 +21022,7 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions
2103121022
if (ClassType.isBuiltIn(destType, 'LiteralString')) {
2103221023
if (ClassType.isBuiltIn(concreteSrcType, 'str') && concreteSrcType.literalValue !== undefined) {
2103321024
return true;
21034-
} else if (ClassType.isBuiltIn(concreteSrcType, 'LiteralString')) {
21035-
return true;
2103621025
}
21037-
} else if (
21038-
ClassType.isBuiltIn(concreteSrcType, 'LiteralString') &&
21039-
strClassType &&
21040-
isInstantiableClass(strClassType)
21041-
) {
21042-
concreteSrcType = ClassType.cloneAsInstance(strClassType);
2104321026
}
2104421027

2104521028
if (

packages/pyright-internal/src/languageService/completionProvider.ts

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1366,15 +1366,6 @@ export class CompletionProvider {
13661366
subtype = this._evaluator.makeTopLevelTypeVarsConcrete(subtype);
13671367

13681368
if (isClass(subtype)) {
1369-
// Handle LiteralString specially. Treat it like a 'str' for purposes
1370-
// of completion suggestions.
1371-
if (ClassType.isBuiltIn(subtype, 'LiteralString')) {
1372-
const strObject = this._evaluator.getBuiltInObject(leftExprNode, 'str');
1373-
if (strObject && isClassInstance(strObject)) {
1374-
subtype = strObject;
1375-
}
1376-
}
1377-
13781369
getMembersForClass(subtype, symbolTable, /* includeInstanceVars */ TypeBase.isInstance(subtype));
13791370
} else if (isModule(subtype)) {
13801371
getMembersForModule(subtype, symbolTable);

packages/pyright-internal/src/tests/samples/literalString1.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,3 +63,11 @@ def func5(
6363

6464
# This should generate an error because "b" is not literal.
6565
v4: LiteralString = f"{a} {b}"
66+
67+
68+
def func6(a: LiteralString):
69+
v1 = a.capitalize()
6D4E 70+
71+
v2 = a[0]
72+
73+
a = "hi"

packages/pyright-internal/src/tests/samples/operators8.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -108,8 +108,8 @@ def func4(a: Literal[True], b: Literal[False]):
108108
def func5(
109109
a: mode, b: mode, c: mode, d: mode, e: mode, f: mode, g: mode, h: mode, i: mode
110110
):
111-
# Make sure this degenerate case falls back to "str".
112-
reveal_type(a + b + c + d + e + f + g + h + i, expected_text="str")
111+
# Make sure this degenerate case falls back to "LiteralString".
112+
reveal_type(a + b + c + d + e + f + g + h + i, expected_text="LiteralString")
113113

114114

115115
def func6(x: Literal[1, 3, 5, 7, 11, 13]):

0 commit comments

Comments
 (0)
0