Skip to content

Commit 64708ce

Browse files
committed
Added code to find built-in aliases in the collections typeshed file.
1 parent 096b0c7 commit 64708ce

File tree

3 files changed

+55
-10
lines changed

3 files changed

+55
-10
lines changed

server/src/analyzer/semanticAnalyzer.ts

+4-1
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,10 @@ export abstract class SemanticAnalyzer extends ParseTreeWalker {
126126
this.walkMultiple(node.decorators);
127127

128128
let classFlags = ClassTypeFlags.None;
129-
if (this._currentScope.getType() === ScopeType.BuiltIn || this._fileInfo.isTypingStubFile) {
129+
if (this._currentScope.getType() === ScopeType.BuiltIn ||
130+
this._fileInfo.isTypingStubFile ||
131+
this._fileInfo.isCollectionsStubFile) {
132+
130133
classFlags |= ClassTypeFlags.BuiltInClass;
131134
}
132135
if (node.decorators.length > 0) {

server/src/analyzer/typeAnalyzer.ts

+51-5
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,11 @@ interface EnumClassInfo {
4444
valueType: Type;
4545
}
4646

47+
interface AliasMapEntry {
48+
alias: string;
49+
module: 'builtins' | 'collections';
50+
}
51+
4752
// At some point, we'll cut off the analysis passes and assume
4853
// we're making no forward progress. This should happen only
4954
// on the case of bugs in the analyzer.
@@ -780,16 +785,44 @@ export class TypeAnalyzer extends ParseTreeWalker {
780785
'NoReturn', 'Union', 'Optional', 'List', 'Dict', 'DefaultDict',
781786
'Set', 'FrozenSet', 'Deque', 'ChainMap'];
782787
if (specialTypes.find(t => t === assignedName)) {
788+
const aliasMap: { [name: string]: AliasMapEntry } = {
789+
'List': { alias: 'list', module: 'builtins' },
790+
'Dict': { alias: 'dict', module: 'builtins' },
791+
'DefaultDict': { alias: 'defaultdict', module: 'collections' },
792+
'Set': { alias: 'set', module: 'builtins' },
793+
'FrozenSet': { alias: 'frozenset', module: 'builtins' },
794+
'Deque': { alias: 'deque', module: 'collections' },
795+
'ChainMap': { alias: 'ChainMap', module: 'collections' }
796+
};
797+
783798
// Synthesize a class.
784799
let specialClassType = new ClassType(assignedName,
785800
ClassTypeFlags.BuiltInClass | ClassTypeFlags.SpecialBuiltIn,
786801
DefaultTypeSourceId);
787802

788-
let aliasClass = ScopeUtils.getBuiltInType(this._currentScope,
789-
assignedName.toLowerCase());
790-
if (aliasClass instanceof ClassType) {
791-
specialClassType.addBaseClass(aliasClass, false);
792-
specialClassType.setAliasClass(aliasClass);
803+
// See if we need to locate an alias class to bind it to.
804+
const aliasMapEntry = aliasMap[assignedName];
805+
if (aliasMapEntry) {
806+
let aliasClass: Type | undefined;
807+
const aliasName = aliasMapEntry.alias;
808+
809+
if (aliasMapEntry.module === 'builtins') {
810+
aliasClass = ScopeUtils.getBuiltInType(this._currentScope, aliasName);
811+
} else if (aliasMapEntry.module === 'collections') {
812+
// The typing.pyi file imports collections.
813+
let collectionsScope = this._findCollectionsImportScope();
814+
if (collectionsScope) {
815+
const symbolInfo = collectionsScope.lookUpSymbol(aliasName);
816+
if (symbolInfo) {
817+
aliasClass = symbolInfo.currentType;
818+
}
819+
}
820+
}
821+
822+
if (aliasClass instanceof ClassType) {
823+
specialClassType.addBaseClass(aliasClass, false);
824+
specialClassType.setAliasClass(aliasClass);
825+
}
793826
}
794827

795828
specialType = specialClassType;
@@ -823,6 +856,19 @@ export class TypeAnalyzer extends ParseTreeWalker {
823856
return false;
824857
}
825858

859+
private _findCollectionsImportScope() {
860+
let collectionResults = Object.keys(this._fileInfo.importMap).find(path => {
861+
return path.endsWith('collections/__init__.pyi');
862+
});
863+
864+
if (collectionResults) {
865+
const moduleNode = this._fileInfo.importMap[collectionResults].parseTree;
866+
return AnalyzerNodeInfo.getScope(moduleNode);
867+
}
868+
869+
return undefined;
870+
}
871+
826872
visitName(node: NameNode) {
827873
let symbolInScope = this._currentScope.lookUpSymbolRecursive(node.nameToken.value);
828874

server/src/analyzer/types.ts

-4
Original file line numberDiff line numberDiff line change
@@ -305,10 +305,6 @@ export class ClassType extends Type {
305305
this._classDetails.aliasClass = type;
306306
}
307307

308-
getAliasClass() {
309-
return this._classDetails.aliasClass;
310-
}
311-
312308
addBaseClass(type: Type, isMetaclass: boolean) {
313309
this._classDetails.baseClasses.push({ isMetaclass, type });
314310
}

0 commit comments

Comments
 (0)