@zzzen/pyright-internal 1.2.0-dev.20260809 → 1.2.0-dev.20260823
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/analyzer/analyzerNodeInfo.d.ts +119 -24
- package/dist/analyzer/analyzerNodeInfo.js +408 -89
- package/dist/analyzer/analyzerNodeInfo.js.map +1 -1
- package/dist/analyzer/binder.d.ts +6 -3
- package/dist/analyzer/binder.js +157 -70
- package/dist/analyzer/binder.js.map +1 -1
- package/dist/analyzer/checker.d.ts +5 -2
- package/dist/analyzer/checker.js +92 -34
- package/dist/analyzer/checker.js.map +1 -1
- package/dist/analyzer/codeFlowEngine.d.ts +2 -1
- package/dist/analyzer/codeFlowEngine.js +12 -10
- package/dist/analyzer/codeFlowEngine.js.map +1 -1
- package/dist/analyzer/codeFlowUtils.d.ts +2 -1
- package/dist/analyzer/codeFlowUtils.js +2 -3
- package/dist/analyzer/codeFlowUtils.js.map +1 -1
- package/dist/analyzer/constraintSolver.js +47 -7
- package/dist/analyzer/constraintSolver.js.map +1 -1
- package/dist/analyzer/constructors.js +18 -8
- package/dist/analyzer/constructors.js.map +1 -1
- package/dist/analyzer/dataClasses.d.ts +6 -4
- package/dist/analyzer/dataClasses.js +119 -75
- package/dist/analyzer/dataClasses.js.map +1 -1
- package/dist/analyzer/declarationUtils.d.ts +2 -1
- package/dist/analyzer/declarationUtils.js +2 -2
- package/dist/analyzer/declarationUtils.js.map +1 -1
- package/dist/analyzer/decorators.d.ts +5 -4
- package/dist/analyzer/decorators.js +38 -21
- package/dist/analyzer/decorators.js.map +1 -1
- package/dist/analyzer/enums.d.ts +5 -4
- package/dist/analyzer/enums.js +11 -10
- package/dist/analyzer/enums.js.map +1 -1
- package/dist/analyzer/importResolver.d.ts +1 -1
- package/dist/analyzer/importResolver.js +5 -3
- package/dist/analyzer/importResolver.js.map +1 -1
- package/dist/analyzer/importStatementUtils.d.ts +3 -1
- package/dist/analyzer/importStatementUtils.js +14 -7
- package/dist/analyzer/importStatementUtils.js.map +1 -1
- package/dist/analyzer/namedTuples.d.ts +2 -1
- package/dist/analyzer/namedTuples.js +3 -4
- package/dist/analyzer/namedTuples.js.map +1 -1
- package/dist/analyzer/operations.d.ts +3 -2
- package/dist/analyzer/operations.js +8 -8
- package/dist/analyzer/operations.js.map +1 -1
- package/dist/analyzer/packageTypeVerifier.js +2 -2
- package/dist/analyzer/packageTypeVerifier.js.map +1 -1
- package/dist/analyzer/parseTreeUtils.d.ts +13 -11
- package/dist/analyzer/parseTreeUtils.js +62 -36
- package/dist/analyzer/parseTreeUtils.js.map +1 -1
- package/dist/analyzer/parseTreeWalker.d.ts +7 -2
- package/dist/analyzer/parseTreeWalker.js +29 -175
- package/dist/analyzer/parseTreeWalker.js.map +1 -1
- package/dist/analyzer/patternMatching.d.ts +4 -3
- package/dist/analyzer/patternMatching.js +47 -43
- package/dist/analyzer/patternMatching.js.map +1 -1
- package/dist/analyzer/program.d.ts +12 -0
- package/dist/analyzer/program.js +235 -29
- package/dist/analyzer/program.js.map +1 -1
- package/dist/analyzer/properties.d.ts +4 -3
- package/dist/analyzer/properties.js +7 -8
- package/dist/analyzer/properties.js.map +1 -1
- package/dist/analyzer/protocols.js +14 -2
- package/dist/analyzer/protocols.js.map +1 -1
- package/dist/analyzer/scope.d.ts +3 -0
- package/dist/analyzer/scope.js +10 -0
- package/dist/analyzer/scope.js.map +1 -1
- package/dist/analyzer/scopeUtils.d.ts +4 -3
- package/dist/analyzer/scopeUtils.js +8 -8
- package/dist/analyzer/scopeUtils.js.map +1 -1
- package/dist/analyzer/sentinel.d.ts +2 -1
- package/dist/analyzer/sentinel.js +2 -3
- package/dist/analyzer/sentinel.js.map +1 -1
- package/dist/analyzer/service.js +28 -10
- package/dist/analyzer/service.js.map +1 -1
- package/dist/analyzer/sourceEnumerator.d.ts +5 -0
- package/dist/analyzer/sourceEnumerator.js +57 -3
- package/dist/analyzer/sourceEnumerator.js.map +1 -1
- package/dist/analyzer/sourceFile.d.ts +12 -6
- package/dist/analyzer/sourceFile.js +73 -50
- package/dist/analyzer/sourceFile.js.map +1 -1
- package/dist/analyzer/sourceFileInfoUtils.d.ts +1 -0
- package/dist/analyzer/sourceFileInfoUtils.js +8 -0
- package/dist/analyzer/sourceFileInfoUtils.js.map +1 -1
- package/dist/analyzer/sourceMapper.d.ts +4 -1
- package/dist/analyzer/sourceMapper.js +14 -8
- package/dist/analyzer/sourceMapper.js.map +1 -1
- package/dist/analyzer/symbol.d.ts +4 -1
- package/dist/analyzer/symbol.js +8 -0
- package/dist/analyzer/symbol.js.map +1 -1
- package/dist/analyzer/testWalker.js +2 -1
- package/dist/analyzer/testWalker.js.map +1 -1
- package/dist/analyzer/tracePrinter.d.ts +2 -1
- package/dist/analyzer/tracePrinter.js +2 -2
- package/dist/analyzer/tracePrinter.js.map +1 -1
- package/dist/analyzer/tuples.d.ts +3 -2
- package/dist/analyzer/tuples.js +5 -5
- package/dist/analyzer/tuples.js.map +1 -1
- package/dist/analyzer/typeCacheUtils.d.ts +6 -2
- package/dist/analyzer/typeCacheUtils.js +16 -37
- package/dist/analyzer/typeCacheUtils.js.map +1 -1
- package/dist/analyzer/typeDocStringUtils.d.ts +5 -7
- package/dist/analyzer/typeDocStringUtils.js +229 -132
- package/dist/analyzer/typeDocStringUtils.js.map +1 -1
- package/dist/analyzer/typeEvaluator.d.ts +2 -0
- package/dist/analyzer/typeEvaluator.js +1280 -302
- package/dist/analyzer/typeEvaluator.js.map +1 -1
- package/dist/analyzer/typeEvaluatorTypes.d.ts +2 -0
- package/dist/analyzer/typeEvaluatorTypes.js.map +1 -1
- package/dist/analyzer/typeGuards.d.ts +3 -2
- package/dist/analyzer/typeGuards.js +37 -33
- package/dist/analyzer/typeGuards.js.map +1 -1
- package/dist/analyzer/typeStubWriter.js +12 -9
- package/dist/analyzer/typeStubWriter.js.map +1 -1
- package/dist/analyzer/typeUtils.js +3 -1
- package/dist/analyzer/typeUtils.js.map +1 -1
- package/dist/analyzer/typedDicts.d.ts +4 -3
- package/dist/analyzer/typedDicts.js +15 -14
- package/dist/analyzer/typedDicts.js.map +1 -1
- package/dist/analyzer/types.d.ts +11 -1
- package/dist/analyzer/types.js +48 -0
- package/dist/analyzer/types.js.map +1 -1
- package/dist/commands/dumpFileDebugInfoCommand.js +1 -1
- package/dist/commands/dumpFileDebugInfoCommand.js.map +1 -1
- package/dist/common/collectionUtils.js +15 -6
- package/dist/common/collectionUtils.js.map +1 -1
- package/dist/common/commandLineOptions.d.ts +1 -0
- package/dist/common/commandLineOptions.js.map +1 -1
- package/dist/common/configOptions.d.ts +4 -1
- package/dist/common/configOptions.js +68 -12
- package/dist/common/configOptions.js.map +1 -1
- package/dist/common/envVarUtils.d.ts +1 -0
- package/dist/common/envVarUtils.js +41 -10
- package/dist/common/envVarUtils.js.map +1 -1
- package/dist/common/extensibility.d.ts +3 -1
- package/dist/common/extensibility.js.map +1 -1
- package/dist/common/extraPathGlob.d.ts +12 -0
- package/dist/common/extraPathGlob.js +315 -0
- package/dist/common/extraPathGlob.js.map +1 -0
- package/dist/common/host.d.ts +2 -0
- package/dist/common/host.js.map +1 -1
- package/dist/common/languageServerInterface.d.ts +2 -1
- package/dist/common/languageServerInterface.js.map +1 -1
- package/dist/common/pathConsts.d.ts +1 -0
- package/dist/common/pathConsts.js +11 -1
- package/dist/common/pathConsts.js.map +1 -1
- package/dist/common/processUtils.d.ts +4 -2
- package/dist/common/processUtils.js +3 -0
- package/dist/common/processUtils.js.map +1 -1
- package/dist/common/stringUtils.d.ts +6 -0
- package/dist/common/stringUtils.js +87 -5
- package/dist/common/stringUtils.js.map +1 -1
- package/dist/common/textEditTracker.d.ts +3 -1
- package/dist/common/textEditTracker.js +8 -6
- package/dist/common/textEditTracker.js.map +1 -1
- package/dist/common/textRangeCollection.d.ts +1 -0
- package/dist/common/textRangeCollection.js +32 -1
- package/dist/common/textRangeCollection.js.map +1 -1
- package/dist/common/uri/uriUtils.d.ts +3 -0
- package/dist/common/uri/uriUtils.js +65 -15
- package/dist/common/uri/uriUtils.js.map +1 -1
- package/dist/fileSystemMapping.d.ts +10 -0
- package/dist/fileSystemMapping.js +176 -0
- package/dist/fileSystemMapping.js.map +1 -0
- package/dist/languageService/analyzerServiceExecutor.js +2 -1
- package/dist/languageService/analyzerServiceExecutor.js.map +1 -1
- package/dist/languageService/autoImporter.d.ts +1 -0
- package/dist/languageService/autoImporter.js +32 -5
- package/dist/languageService/autoImporter.js.map +1 -1
- package/dist/languageService/callHierarchyProvider.d.ts +7 -0
- package/dist/languageService/callHierarchyProvider.js +97 -11
- package/dist/languageService/callHierarchyProvider.js.map +1 -1
- package/dist/languageService/completionProvider.d.ts +30 -8
- package/dist/languageService/completionProvider.js +298 -93
- package/dist/languageService/completionProvider.js.map +1 -1
- package/dist/languageService/definitionProvider.js +7 -6
- package/dist/languageService/definitionProvider.js.map +1 -1
- package/dist/languageService/documentHighlightProvider.js +2 -1
- package/dist/languageService/documentHighlightProvider.js.map +1 -1
- package/dist/languageService/documentSymbolCollector.d.ts +3 -1
- package/dist/languageService/documentSymbolCollector.js +78 -14
- package/dist/languageService/documentSymbolCollector.js.map +1 -1
- package/dist/languageService/documentSymbolProvider.js +3 -2
- package/dist/languageService/documentSymbolProvider.js.map +1 -1
- package/dist/languageService/fileWatcherDynamicFeature.js +28 -1
- package/dist/languageService/fileWatcherDynamicFeature.js.map +1 -1
- package/dist/languageService/hoverProvider.d.ts +2 -1
- package/dist/languageService/hoverProvider.js +48 -16
- package/dist/languageService/hoverProvider.js.map +1 -1
- package/dist/languageService/importSorter.d.ts +3 -1
- package/dist/languageService/importSorter.js +4 -2
- package/dist/languageService/importSorter.js.map +1 -1
- package/dist/languageService/importStatementCandidates.js +4 -2
- package/dist/languageService/importStatementCandidates.js.map +1 -1
- package/dist/languageService/quickActions.js +2 -1
- package/dist/languageService/quickActions.js.map +1 -1
- package/dist/languageService/referencesProvider.js +12 -5
- package/dist/languageService/referencesProvider.js.map +1 -1
- package/dist/languageService/signatureHelpProvider.d.ts +3 -0
- package/dist/languageService/signatureHelpProvider.js +56 -18
- package/dist/languageService/signatureHelpProvider.js.map +1 -1
- package/dist/languageService/symbolIndexer.d.ts +2 -1
- package/dist/languageService/symbolIndexer.js +7 -7
- package/dist/languageService/symbolIndexer.js.map +1 -1
- package/dist/languageService/tooltipUtils.d.ts +1 -1
- package/dist/languageService/tooltipUtils.js +103 -35
- package/dist/languageService/tooltipUtils.js.map +1 -1
- package/dist/languageService/workspaceSymbolProvider.js +3 -2
- package/dist/languageService/workspaceSymbolProvider.js.map +1 -1
- package/dist/localization/localize.d.ts +12 -0
- package/dist/localization/localize.js +14 -0
- package/dist/localization/localize.js.map +1 -1
- package/dist/localization/package.nls.cs.json +11 -0
- package/dist/localization/package.nls.de.json +11 -0
- package/dist/localization/package.nls.en-us.json +18 -0
- package/dist/localization/package.nls.es.json +11 -0
- package/dist/localization/package.nls.fr.json +11 -0
- package/dist/localization/package.nls.it.json +11 -0
- package/dist/localization/package.nls.ja.json +11 -0
- package/dist/localization/package.nls.ko.json +11 -0
- package/dist/localization/package.nls.pl.json +11 -0
- package/dist/localization/package.nls.pt-br.json +11 -0
- package/dist/localization/package.nls.qps-ploc.json +11 -0
- package/dist/localization/package.nls.ru.json +11 -0
- package/dist/localization/package.nls.tr.json +11 -0
- package/dist/localization/package.nls.zh-cn.json +12 -1
- package/dist/localization/package.nls.zh-tw.json +13 -2
- package/dist/parser/parseNodes.d.ts +85 -80
- package/dist/parser/parseNodes.js +182 -159
- package/dist/parser/parseNodes.js.map +1 -1
- package/dist/parser/parseTreeUtils.d.ts +3 -0
- package/dist/parser/parseTreeUtils.js +209 -0
- package/dist/parser/parseTreeUtils.js.map +1 -0
- package/dist/parser/parser.d.ts +16 -6
- package/dist/parser/parser.js +210 -144
- package/dist/parser/parser.js.map +1 -1
- package/dist/parser/stringAnnotationInfo.d.ts +16 -0
- package/dist/parser/stringAnnotationInfo.js +26 -0
- package/dist/parser/stringAnnotationInfo.js.map +1 -0
- package/dist/readonlyAugmentedFileSystem.d.ts +2 -9
- package/dist/readonlyAugmentedFileSystem.js +17 -144
- package/dist/readonlyAugmentedFileSystem.js.map +1 -1
- package/dist/server.js +2 -2
- package/dist/server.js.map +1 -1
- package/dist/tests/analyzerNodeInfo.test.d.ts +1 -0
- package/dist/tests/analyzerNodeInfo.test.js +113 -0
- package/dist/tests/analyzerNodeInfo.test.js.map +1 -0
- package/dist/tests/collectionUtils.test.js +46 -0
- package/dist/tests/collectionUtils.test.js.map +1 -1
- package/dist/tests/completions.test.js +34 -0
- package/dist/tests/completions.test.js.map +1 -1
- package/dist/tests/config.test.js +131 -6
- package/dist/tests/config.test.js.map +1 -1
- package/dist/tests/extraPathGlob.test.d.ts +1 -0
- package/dist/tests/extraPathGlob.test.js +434 -0
- package/dist/tests/extraPathGlob.test.js.map +1 -0
- package/dist/tests/fileSystemMapping.test.d.ts +1 -0
- package/dist/tests/fileSystemMapping.test.js +458 -0
- package/dist/tests/fileSystemMapping.test.js.map +1 -0
- package/dist/tests/fourslash/completions.call.typedDict.fourslash.js +23 -0
- package/dist/tests/fourslash/completions.call.typedDict.fourslash.js.map +1 -1
- package/dist/tests/fourslash/completions.call.typedDict.list.fourslash.js +14 -0
- package/dist/tests/fourslash/completions.call.typedDict.list.fourslash.js.map +1 -1
- package/dist/tests/fourslash/completions.call.typedDict.states.fourslash.js +7 -0
- package/dist/tests/fourslash/completions.call.typedDict.states.fourslash.js.map +1 -1
- package/dist/tests/fourslash/completions.callSite.isinstanceNarrowing.fourslash.d.ts +1 -0
- package/dist/tests/fourslash/completions.callSite.isinstanceNarrowing.fourslash.js +41 -0
- package/dist/tests/fourslash/completions.callSite.isinstanceNarrowing.fourslash.js.map +1 -0
- package/dist/tests/fourslash/completions.dictionary.keys.literalTypes.fourslash.js +2 -0
- package/dist/tests/fourslash/completions.dictionary.keys.literalTypes.fourslash.js.map +1 -1
- package/dist/tests/fourslash/completions.fstring.stringLiteral.fourslash.js +5 -0
- package/dist/tests/fourslash/completions.fstring.stringLiteral.fourslash.js.map +1 -1
- package/dist/tests/fourslash/completions.stringLiteral.fourslash.js +4 -0
- package/dist/tests/fourslash/completions.stringLiteral.fourslash.js.map +1 -1
- package/dist/tests/fourslash/findallreferences.protocolMemberVariable.fourslash.d.ts +1 -0
- package/dist/tests/fourslash/findallreferences.protocolMemberVariable.fourslash.js +48 -0
- package/dist/tests/fourslash/findallreferences.protocolMemberVariable.fourslash.js.map +1 -0
- package/dist/tests/fourslash/hover.inherited.docFromSrc.fourslash.js +8 -2
- package/dist/tests/fourslash/hover.inherited.docFromSrc.fourslash.js.map +1 -1
- package/dist/tests/fourslash/hover.inherited.docFromStub.fourslash.js +5 -2
- package/dist/tests/fourslash/hover.inherited.docFromStub.fourslash.js.map +1 -1
- package/dist/tests/fourslash/signature.docstrings.overloaded.fourslash.js +2 -2
- package/dist/tests/fourslash/signature.docstrings.overloaded.fourslash.js.map +1 -1
- package/dist/tests/harness/fourslash/testState.js +1 -1
- package/dist/tests/harness/fourslash/testState.js.map +1 -1
- package/dist/tests/hoverProvider.test.js +38 -0
- package/dist/tests/hoverProvider.test.js.map +1 -1
- package/dist/tests/importStatementUtils.test.js +6 -3
- package/dist/tests/importStatementUtils.test.js.map +1 -1
- package/dist/tests/ipythonMode.test.js +38 -0
- package/dist/tests/ipythonMode.test.js.map +1 -1
- package/dist/tests/parseTreeUtils.test.js +88 -0
- package/dist/tests/parseTreeUtils.test.js.map +1 -1
- package/dist/tests/parser.test.js +60 -3
- package/dist/tests/parser.test.js.map +1 -1
- package/dist/tests/positionUtils.test.js +23 -0
- package/dist/tests/positionUtils.test.js.map +1 -1
- package/dist/tests/pyrightFileSystem.test.js +41 -0
- package/dist/tests/pyrightFileSystem.test.js.map +1 -1
- package/dist/tests/service.test.js +77 -0
- package/dist/tests/service.test.js.map +1 -1
- package/dist/tests/sourceEnumeratorSymlink.test.d.ts +1 -0
- package/dist/tests/sourceEnumeratorSymlink.test.js +203 -0
- package/dist/tests/sourceEnumeratorSymlink.test.js.map +1 -0
- package/dist/tests/stringUtils.test.js +84 -0
- package/dist/tests/stringUtils.test.js.map +1 -1
- package/dist/tests/symlinkAliasInvalidation.test.d.ts +1 -0
- package/dist/tests/symlinkAliasInvalidation.test.js +471 -0
- package/dist/tests/symlinkAliasInvalidation.test.js.map +1 -0
- package/dist/tests/testUtils.d.ts +2 -0
- package/dist/tests/testUtils.js +7 -1
- package/dist/tests/testUtils.js.map +1 -1
- package/dist/tests/textEditUtil.test.js +2 -2
- package/dist/tests/textEditUtil.test.js.map +1 -1
- package/dist/tests/textRangeCollection.test.d.ts +1 -0
- package/dist/tests/textRangeCollection.test.js +137 -0
- package/dist/tests/textRangeCollection.test.js.map +1 -0
- package/dist/tests/typeCacheUtils.test.d.ts +1 -0
- package/dist/tests/typeCacheUtils.test.js +69 -0
- package/dist/tests/typeCacheUtils.test.js.map +1 -0
- package/dist/tests/typeEvaluator1.test.js +24 -3
- package/dist/tests/typeEvaluator1.test.js.map +1 -1
- package/dist/tests/typeEvaluator3.test.js +8 -0
- package/dist/tests/typeEvaluator3.test.js.map +1 -1
- package/dist/tests/typeEvaluator4.test.js +4 -0
- package/dist/tests/typeEvaluator4.test.js.map +1 -1
- package/dist/tests/typeEvaluator5.test.js +12 -0
- package/dist/tests/typeEvaluator5.test.js.map +1 -1
- package/dist/tests/typeEvaluator6.test.js +33 -1
- package/dist/tests/typeEvaluator6.test.js.map +1 -1
- package/dist/tests/typeEvaluator7.test.js +29 -0
- package/dist/tests/typeEvaluator7.test.js.map +1 -1
- package/dist/tests/typeEvaluator8.test.js +318 -4
- package/dist/tests/typeEvaluator8.test.js.map +1 -1
- package/dist/tests/typeServer/typeCache.test.d.ts +1 -0
- package/dist/tests/typeServer/typeCache.test.js +69 -0
- package/dist/tests/typeServer/typeCache.test.js.map +1 -0
- package/dist/tests/typeServer/typeServer.virtualFileRedirect.test.js +18 -0
- package/dist/tests/typeServer/typeServer.virtualFileRedirect.test.js.map +1 -1
- package/dist/tests/types.test.d.ts +1 -0
- package/dist/{analyzer/parseTreeCleaner.js → tests/types.test.js} +23 -25
- package/dist/tests/types.test.js.map +1 -0
- package/dist/tests/uri.test.js +51 -0
- package/dist/tests/uri.test.js.map +1 -1
- package/dist/typeServer/notebookDocumentHandler.d.ts +9 -2
- package/dist/typeServer/notebookDocumentHandler.js +16 -6
- package/dist/typeServer/notebookDocumentHandler.js.map +1 -1
- package/dist/typeServer/programWrapper.d.ts +1 -0
- package/dist/typeServer/programWrapper.js +28 -15
- package/dist/typeServer/programWrapper.js.map +1 -1
- package/dist/typeServer/protocol/tspSupplemental.d.ts +1 -1
- package/dist/typeServer/protocol/tspSupplemental.js +2 -2
- package/dist/typeServer/server.d.ts +13 -2
- package/dist/typeServer/server.js +36 -23
- package/dist/typeServer/server.js.map +1 -1
- package/dist/typeServer/typeCache.d.ts +8 -4
- package/dist/typeServer/typeCache.js +33 -5
- package/dist/typeServer/typeCache.js.map +1 -1
- package/dist/typeServer/typeEvalUtils.d.ts +2 -1
- package/dist/typeServer/typeEvalUtils.js +7 -3
- package/dist/typeServer/typeEvalUtils.js.map +1 -1
- package/dist/typeServer/typeServerFileSystem.d.ts +10 -9
- package/dist/typeServer/typeServerFileSystem.js +16 -12
- package/dist/typeServer/typeServerFileSystem.js.map +1 -1
- package/package.json +7 -5
- package/dist/analyzer/parseTreeCleaner.d.ts +0 -8
- package/dist/analyzer/parseTreeCleaner.js.map +0 -1
|
@@ -196,6 +196,7 @@ const printExpressionTypes = false;
|
|
|
196
196
|
// long analysis times. This number has been tuned empirically.
|
|
197
197
|
exports.maxCodeComplexity = 768;
|
|
198
198
|
function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
199
|
+
const nodeInfo = AnalyzerNodeInfo.createAnalyzerNodeInfoAccessor(evaluatorOptions.nodeInfoReader);
|
|
199
200
|
const symbolResolutionStack = [];
|
|
200
201
|
const speculativeTypeTracker = new typeCacheUtils_1.SpeculativeTypeTracker();
|
|
201
202
|
const suppressedNodeStack = [];
|
|
@@ -203,6 +204,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
203
204
|
let functionRecursionMap = new Map();
|
|
204
205
|
let codeFlowAnalyzerCache = new Map();
|
|
205
206
|
let typeCache = new Map();
|
|
207
|
+
let typeFormTypeCache = new Map();
|
|
206
208
|
let effectiveTypeCache = new Map();
|
|
207
209
|
let expectedTypeCache = new Map();
|
|
208
210
|
let asymmetricAccessorAssignmentCache = new Set();
|
|
@@ -212,8 +214,24 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
212
214
|
let incompleteGenCount = 0;
|
|
213
215
|
const returnTypeInferenceContextStack = [];
|
|
214
216
|
let returnTypeInferenceTypeCache;
|
|
217
|
+
let returnTypeInferenceTypeFormTypeCache;
|
|
215
218
|
const signatureTrackerStack = [];
|
|
216
219
|
let prefetched;
|
|
220
|
+
function getScopeForNode(node) {
|
|
221
|
+
return ScopeUtils.getScopeForNode(node, nodeInfo);
|
|
222
|
+
}
|
|
223
|
+
function getScopeHierarchy(node, stopScope) {
|
|
224
|
+
return ScopeUtils.getScopeHierarchy(node, stopScope, nodeInfo);
|
|
225
|
+
}
|
|
226
|
+
function findTopNodeInScope(node, scope) {
|
|
227
|
+
return ScopeUtils.findTopNodeInScope(node, scope, nodeInfo);
|
|
228
|
+
}
|
|
229
|
+
function getScopeIdForNode(node) {
|
|
230
|
+
return ParseTreeUtils.getScopeIdForNode(node, nodeInfo);
|
|
231
|
+
}
|
|
232
|
+
function getTypeVarScopesForNode(node) {
|
|
233
|
+
return ParseTreeUtils.getTypeVarScopesForNode(node, nodeInfo);
|
|
234
|
+
}
|
|
217
235
|
function runWithCancellationToken(token, callback) {
|
|
218
236
|
// Save the current token and restore it after the callback to support nested calls
|
|
219
237
|
const oldToken = cancellationToken;
|
|
@@ -252,6 +270,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
252
270
|
functionRecursionMap = new Map();
|
|
253
271
|
codeFlowAnalyzerCache = new Map();
|
|
254
272
|
typeCache = new Map();
|
|
273
|
+
typeFormTypeCache = new Map();
|
|
255
274
|
effectiveTypeCache = new Map();
|
|
256
275
|
expectedTypeCache = new Map();
|
|
257
276
|
asymmetricAccessorAssignmentCache = new Set();
|
|
@@ -266,8 +285,51 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
266
285
|
return typeCache.get(node.id);
|
|
267
286
|
}
|
|
268
287
|
}
|
|
288
|
+
function getTypeFormTypeCache(node) {
|
|
289
|
+
if (returnTypeInferenceTypeFormTypeCache && isNodeInReturnTypeInferenceContext(node)) {
|
|
290
|
+
return returnTypeInferenceTypeFormTypeCache;
|
|
291
|
+
}
|
|
292
|
+
return typeFormTypeCache;
|
|
293
|
+
}
|
|
294
|
+
function readTypeFormTypeCacheEntry(node, expectedType) {
|
|
295
|
+
return getTypeFormTypeCache(node)
|
|
296
|
+
.get(node.id)
|
|
297
|
+
?.find((entry) => (0, typeCacheUtils_1.contextualTypeCacheEntryMatches)(entry, expectedType));
|
|
298
|
+
}
|
|
299
|
+
// Contextual reads consult expectedTypeCache and prefer a matching TypeForm result.
|
|
300
|
+
// Runtime-only consumers must use readTypeCacheEntry so this precedence is not
|
|
301
|
+
// accidentally applied where an ordinary runtime type is required.
|
|
302
|
+
function readContextualTypeCacheEntryForNode(node) {
|
|
303
|
+
const expectedType = expectedTypeCache.get(node.id)?.type;
|
|
304
|
+
if (expectedType && expectedTypeWantsTypeForm(expectedType)) {
|
|
305
|
+
return (readTypeFormTypeCacheEntry(node, expectedType) ??
|
|
306
|
+
readTypeFormTypeCacheEntry(node, /* expectedType */ undefined) ??
|
|
307
|
+
readTypeCacheEntry(node));
|
|
308
|
+
}
|
|
309
|
+
return readTypeCacheEntry(node) ?? readTypeFormTypeCacheEntry(node, /* expectedType */ undefined);
|
|
310
|
+
}
|
|
311
|
+
// Bumps the incomplete generation count using the same rules for both the
|
|
312
|
+
// regular type cache and the TypeForm type cache so the two cache-invalidation
|
|
313
|
+
// paths cannot drift. A complete result always bumps the count (invalidating
|
|
314
|
+
// dependent incomplete entries); an incomplete result bumps only when its type
|
|
315
|
+
// differs from the previously-cached value.
|
|
316
|
+
function updateIncompleteGenerationCount(typeResult, oldTypeResult) {
|
|
317
|
+
if (!typeResult.isIncomplete) {
|
|
318
|
+
incompleteGenCount++;
|
|
319
|
+
}
|
|
320
|
+
else if (oldTypeResult !== undefined && !(0, types_1.isTypeSame)(typeResult.type, oldTypeResult.type)) {
|
|
321
|
+
incompleteGenCount++;
|
|
322
|
+
}
|
|
323
|
+
}
|
|
269
324
|
function isTypeCached(node) {
|
|
270
|
-
|
|
325
|
+
// This helper is used by runtime-evaluation guards. A contextual TypeForm
|
|
326
|
+
// entry does not prove that the ordinary runtime type was evaluated.
|
|
327
|
+
return isTypeCacheEntryValid(readTypeCacheEntry(node));
|
|
328
|
+
}
|
|
329
|
+
function isTypeFormTypeCached(node, expectedType) {
|
|
330
|
+
return isTypeCacheEntryValid(readTypeFormTypeCacheEntry(node, expectedType));
|
|
331
|
+
}
|
|
332
|
+
function isTypeCacheEntryValid(cacheEntry) {
|
|
271
333
|
if (!cacheEntry) {
|
|
272
334
|
return false;
|
|
273
335
|
}
|
|
@@ -282,7 +344,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
282
344
|
if (flags !== undefined) {
|
|
283
345
|
const expectedFlags = cacheEntry.flags;
|
|
284
346
|
if (expectedFlags !== undefined && flags !== expectedFlags) {
|
|
285
|
-
const fileInfo =
|
|
347
|
+
const fileInfo = nodeInfo.getFileInfo(node);
|
|
286
348
|
const position = (0, positionUtils_1.convertOffsetToPosition)(node.start, fileInfo.lines);
|
|
287
349
|
const message = `Type cache flag mismatch for node type ${node.nodeType} ` +
|
|
288
350
|
`(parent ${node.parent?.nodeType ?? 'none'}): ` +
|
|
@@ -300,20 +362,29 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
300
362
|
return cacheEntry.typeResult.type;
|
|
301
363
|
}
|
|
302
364
|
function writeTypeCache(node, typeResult, flags, inferenceContext, allowSpeculativeCaching = false) {
|
|
365
|
+
const useTypeFormCache = (flags !== undefined && (flags & 1073741824 /* EvalFlags.TypeFormArg */) !== 0) ||
|
|
366
|
+
(!!inferenceContext && expectedTypeWantsTypeForm(inferenceContext.expectedType));
|
|
367
|
+
if (useTypeFormCache) {
|
|
368
|
+
const expectedType = inferenceContext?.expectedType;
|
|
369
|
+
// Speculative TypeForm results are not retained, so they must not invalidate
|
|
370
|
+
// persistent incomplete entries through the global generation counter.
|
|
371
|
+
if (isSpeculativeModeInUse(node)) {
|
|
372
|
+
return;
|
|
373
|
+
}
|
|
374
|
+
const typeFormCache = getTypeFormTypeCache(node);
|
|
375
|
+
const cacheEntries = typeFormCache.get(node.id) ?? [];
|
|
376
|
+
const oldEntry = cacheEntries.find((entry) => (0, typeCacheUtils_1.contextualTypeCacheEntryMatches)(entry, expectedType));
|
|
377
|
+
updateIncompleteGenerationCount(typeResult, oldEntry?.typeResult);
|
|
378
|
+
typeFormCache.set(node.id, (0, typeCacheUtils_1.addContextualTypeCacheEntry)(cacheEntries, { typeResult, flags, incompleteGenCount, expectedType }));
|
|
379
|
+
return;
|
|
380
|
+
}
|
|
303
381
|
// Should we use a temporary cache associated with a contextual
|
|
304
382
|
// analysis of a function, contextualized based on call-site argument types?
|
|
305
383
|
const typeCacheToUse = returnTypeInferenceTypeCache && isNodeInReturnTypeInferenceContext(node)
|
|
306
384
|
? returnTypeInferenceTypeCache
|
|
307
385
|
: typeCache;
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
}
|
|
311
|
-
else {
|
|
312
|
-
const oldValue = typeCacheToUse.get(node.id);
|
|
313
|
-
if (oldValue !== undefined && !(0, types_1.isTypeSame)(typeResult.type, oldValue.typeResult.type)) {
|
|
314
|
-
incompleteGenCount++;
|
|
315
|
-
}
|
|
316
|
-
}
|
|
386
|
+
const oldValue = typeCacheToUse.get(node.id);
|
|
387
|
+
updateIncompleteGenerationCount(typeResult, oldValue?.typeResult);
|
|
317
388
|
typeCacheToUse.set(node.id, { typeResult, flags, incompleteGenCount });
|
|
318
389
|
// If the entry is located within a part of the parse tree that is currently being
|
|
319
390
|
// "speculatively" evaluated, track it so we delete the cached entry when we leave
|
|
@@ -404,7 +475,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
404
475
|
// type of surrounding statements to be evaluated.
|
|
405
476
|
function getType(node) {
|
|
406
477
|
initializePrefetchedTypes(node);
|
|
407
|
-
let type =
|
|
478
|
+
let type = evaluateContextualTypeForSubnode(node, () => {
|
|
408
479
|
evaluateTypesForExpressionInContext(node);
|
|
409
480
|
})?.type;
|
|
410
481
|
// If this is a type parameter with a calculated variance, see if we
|
|
@@ -441,18 +512,24 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
441
512
|
return type;
|
|
442
513
|
}
|
|
443
514
|
function getTypeResult(node) {
|
|
444
|
-
return
|
|
515
|
+
return evaluateContextualTypeForSubnode(node, () => {
|
|
445
516
|
evaluateTypesForExpressionInContext(node);
|
|
446
517
|
});
|
|
447
518
|
}
|
|
448
519
|
function getTypeResultForDecorator(node) {
|
|
449
|
-
return
|
|
520
|
+
return evaluateContextualTypeForSubnode(node, () => {
|
|
450
521
|
evaluateTypesForExpressionInContext(node.d.expr);
|
|
451
522
|
});
|
|
452
523
|
}
|
|
453
524
|
// Reads the type of the node from the cache.
|
|
454
525
|
function getCachedType(node) {
|
|
455
|
-
|
|
526
|
+
// Prefer the ordinary runtime type when both caches contain an entry for this node.
|
|
527
|
+
// Fall back to the contextual cache so TypeForm-only evaluations remain discoverable.
|
|
528
|
+
const cacheEntry = readTypeCacheEntry(node) ?? readContextualTypeCacheEntryForNode(node);
|
|
529
|
+
if (!cacheEntry || cacheEntry.typeResult.isIncomplete) {
|
|
530
|
+
return undefined;
|
|
531
|
+
}
|
|
532
|
+
return cacheEntry.typeResult.type;
|
|
456
533
|
}
|
|
457
534
|
// Determines the expected type of a specified node based on surrounding
|
|
458
535
|
// context. For example, if it's a subexpression of an argument expression,
|
|
@@ -512,7 +589,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
512
589
|
// Some of these types have cyclical dependencies on each other,
|
|
513
590
|
// so don't re-enter this block once we start executing it.
|
|
514
591
|
prefetched = {};
|
|
515
|
-
const fileInfo =
|
|
592
|
+
const fileInfo = nodeInfo.getFileInfo(node);
|
|
516
593
|
prefetched.objectClass = getBuiltInType(node, 'object');
|
|
517
594
|
prefetched.typeClass = getBuiltInType(node, 'type');
|
|
518
595
|
prefetched.functionClass = getTypesType(node, 'FunctionType') ?? getBuiltInType(node, 'function');
|
|
@@ -570,8 +647,21 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
570
647
|
}
|
|
571
648
|
}
|
|
572
649
|
function getTypeOfExpression(node, flags = 0 /* EvalFlags.None */, inferenceContext) {
|
|
650
|
+
let useTypeFormCache = (flags & 1073741824 /* EvalFlags.TypeFormArg */) !== 0;
|
|
651
|
+
if (inferenceContext) {
|
|
652
|
+
inferenceContext.expectedType = (0, typeUtils_1.transformPossibleRecursiveTypeAlias)(inferenceContext.expectedType);
|
|
653
|
+
useTypeFormCache || (useTypeFormCache = expectedTypeWantsTypeForm(inferenceContext.expectedType));
|
|
654
|
+
if (expectedTypeRequiresTypeForm(inferenceContext.expectedType)) {
|
|
655
|
+
flags |= 1073741824 /* EvalFlags.TypeFormArg */;
|
|
656
|
+
}
|
|
657
|
+
}
|
|
658
|
+
if ((flags & 1073741824 /* EvalFlags.TypeFormArg */) !== 0 && (flags & 33554432 /* EvalFlags.NoConvertSpecialForm */) === 0) {
|
|
659
|
+
flags |= 32 /* EvalFlags.NoParamSpec */ | 64 /* EvalFlags.NoTypeVarTuple */;
|
|
660
|
+
}
|
|
573
661
|
// Is this type already cached?
|
|
574
|
-
const cacheEntry =
|
|
662
|
+
const cacheEntry = useTypeFormCache
|
|
663
|
+
? readTypeFormTypeCacheEntry(node, inferenceContext?.expectedType)
|
|
664
|
+
: readTypeCacheEntry(node);
|
|
575
665
|
if (cacheEntry) {
|
|
576
666
|
if (!cacheEntry.typeResult.isIncomplete || cacheEntry.incompleteGenCount === incompleteGenCount) {
|
|
577
667
|
if (printExpressionTypes) {
|
|
@@ -581,7 +671,9 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
581
671
|
}
|
|
582
672
|
}
|
|
583
673
|
// Is it cached in the speculative type cache?
|
|
584
|
-
const specCacheEntry =
|
|
674
|
+
const specCacheEntry = useTypeFormCache
|
|
675
|
+
? undefined
|
|
676
|
+
: speculativeTypeTracker.getSpeculativeType(node, inferenceContext?.expectedType);
|
|
585
677
|
if (specCacheEntry) {
|
|
586
678
|
if (!specCacheEntry.typeResult.isIncomplete ||
|
|
587
679
|
specCacheEntry.incompleteGenerationCount === incompleteGenCount) {
|
|
@@ -599,9 +691,6 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
599
691
|
// the cancellation check. If the operation is canceled, an exception
|
|
600
692
|
// will be thrown at this point.
|
|
601
693
|
checkForCancellation();
|
|
602
|
-
if (inferenceContext) {
|
|
603
|
-
inferenceContext.expectedType = (0, typeUtils_1.transformPossibleRecursiveTypeAlias)(inferenceContext.expectedType);
|
|
604
|
-
}
|
|
605
694
|
// If we haven't already fetched some core type definitions from the
|
|
606
695
|
// typeshed stubs, do so here. It would be better to fetch this when it's
|
|
607
696
|
// needed in assignType, but we don't have access to the parse tree
|
|
@@ -613,7 +702,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
613
702
|
typeResult.type.priv.includePromotions &&
|
|
614
703
|
!typeResult.type.priv.includeSubclasses &&
|
|
615
704
|
types_1.ClassType.isBuiltIn(typeResult.type, 'bytes')) {
|
|
616
|
-
if (
|
|
705
|
+
if (nodeInfo.getFileInfo(node).diagnosticRuleSet.disableBytesTypePromotions) {
|
|
617
706
|
typeResult = {
|
|
618
707
|
...typeResult,
|
|
619
708
|
type: types_1.ClassType.cloneRemoveTypePromotions(typeResult.type),
|
|
@@ -680,7 +769,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
680
769
|
break;
|
|
681
770
|
}
|
|
682
771
|
case 52 /* ParseNodeType.Tuple */: {
|
|
683
|
-
typeResult = (0, tuples_1.getTypeOfTuple)(evaluatorInterface, node, flags, inferenceContext);
|
|
772
|
+
typeResult = (0, tuples_1.getTypeOfTuple)(evaluatorInterface, node, flags, inferenceContext, nodeInfo);
|
|
684
773
|
break;
|
|
685
774
|
}
|
|
686
775
|
case 14 /* ParseNodeType.Constant */: {
|
|
@@ -715,7 +804,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
715
804
|
if (expectingInstantiable && node.d.operator !== 6 /* OperatorType.BitwiseOr */) {
|
|
716
805
|
effectiveFlags &= ~128 /* EvalFlags.InstantiableType */;
|
|
717
806
|
}
|
|
718
|
-
typeResult = (0, operations_1.getTypeOfBinaryOperation)(evaluatorInterface, node, effectiveFlags, inferenceContext);
|
|
807
|
+
typeResult = (0, operations_1.getTypeOfBinaryOperation)(evaluatorInterface, node, effectiveFlags, inferenceContext, nodeInfo);
|
|
719
808
|
break;
|
|
720
809
|
}
|
|
721
810
|
case 5 /* ParseNodeType.AugmentedAssignment */: {
|
|
@@ -736,7 +825,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
736
825
|
break;
|
|
737
826
|
}
|
|
738
827
|
case 51 /* ParseNodeType.Ternary */: {
|
|
739
|
-
typeResult = (0, operations_1.getTypeOfTernaryOperation)(evaluatorInterface, node, flags, inferenceContext);
|
|
828
|
+
typeResult = (0, operations_1.getTypeOfTernaryOperation)(evaluatorInterface, node, flags, inferenceContext, nodeInfo);
|
|
740
829
|
break;
|
|
741
830
|
}
|
|
742
831
|
case 11 /* ParseNodeType.Comprehension */: {
|
|
@@ -838,7 +927,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
838
927
|
name = type.shared.name;
|
|
839
928
|
}
|
|
840
929
|
if (isTypeCheckingOnly) {
|
|
841
|
-
const fileInfo =
|
|
930
|
+
const fileInfo = nodeInfo.getFileInfo(node);
|
|
842
931
|
if (!fileInfo.isStubFile) {
|
|
843
932
|
addDiagnostic(diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.LocMessage.typeCheckOnly().format({ name }), node);
|
|
844
933
|
}
|
|
@@ -966,7 +1055,8 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
966
1055
|
}
|
|
967
1056
|
function getTypeOfStringList(node, flags, inferenceContext) {
|
|
968
1057
|
let typeResult;
|
|
969
|
-
if ((flags & 8 /* EvalFlags.StrLiteralAsType */) !== 0 &&
|
|
1058
|
+
if ((flags & 8 /* EvalFlags.StrLiteralAsType */) !== 0 &&
|
|
1059
|
+
((flags & 1073741824 /* EvalFlags.TypeFormArg */) === 0 || (flags & 33554432 /* EvalFlags.NoConvertSpecialForm */) !== 0)) {
|
|
970
1060
|
return getTypeOfStringListAsType(node, flags);
|
|
971
1061
|
}
|
|
972
1062
|
const isBytesNode = (node) => (node.d.token.flags & 32 /* StringTokenFlags.Bytes */) !== 0;
|
|
@@ -1071,9 +1161,9 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
1071
1161
|
if ((flags & 16777216 /* EvalFlags.ParsesStringLiteral */) === 0) {
|
|
1072
1162
|
updatedFlags |= 524288 /* EvalFlags.NotParsed */;
|
|
1073
1163
|
}
|
|
1074
|
-
|
|
1075
|
-
if (
|
|
1076
|
-
return getTypeOfExpression(
|
|
1164
|
+
const annotation = nodeInfo.getStringAnnotation(node);
|
|
1165
|
+
if (annotation && (flags & 256 /* EvalFlags.TypeExpression */) !== 0) {
|
|
1166
|
+
return getTypeOfExpression(annotation, updatedFlags);
|
|
1077
1167
|
}
|
|
1078
1168
|
if (node.d.strings.length === 1) {
|
|
1079
1169
|
const tokenFlags = node.d.strings[0].d.token.flags;
|
|
@@ -1213,7 +1303,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
1213
1303
|
});
|
|
1214
1304
|
}
|
|
1215
1305
|
function getTypeOfAnnotation(node, options) {
|
|
1216
|
-
const fileInfo =
|
|
1306
|
+
const fileInfo = nodeInfo.getFileInfo(node);
|
|
1217
1307
|
// Special-case the typing.pyi file, which contains some special
|
|
1218
1308
|
// types that the type analyzer needs to interpret differently.
|
|
1219
1309
|
if (fileInfo.isTypingStubFile || fileInfo.isTypingExtensionsStubFile) {
|
|
@@ -2346,7 +2436,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
2346
2436
|
return getTypeOfModule(node, symbolName, ['_typeshed']);
|
|
2347
2437
|
}
|
|
2348
2438
|
function getTypeOfModule(node, symbolName, nameParts) {
|
|
2349
|
-
const fileInfo =
|
|
2439
|
+
const fileInfo = nodeInfo.getFileInfo(node);
|
|
2350
2440
|
const lookupResult = importLookup({ nameParts, importingFileUri: fileInfo.fileUri });
|
|
2351
2441
|
if (!lookupResult) {
|
|
2352
2442
|
return undefined;
|
|
@@ -2358,8 +2448,8 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
2358
2448
|
return getEffectiveTypeOfSymbol(symbol);
|
|
2359
2449
|
}
|
|
2360
2450
|
function checkCodeFlowTooComplex(node) {
|
|
2361
|
-
const scopeNode = node.nodeType === 31 /* ParseNodeType.Function */ ? node : ParseTreeUtils.getExecutionScopeNode(node);
|
|
2362
|
-
const codeComplexity =
|
|
2451
|
+
const scopeNode = node.nodeType === 31 /* ParseNodeType.Function */ ? node : ParseTreeUtils.getExecutionScopeNode(node, nodeInfo);
|
|
2452
|
+
const codeComplexity = nodeInfo.getCodeFlowComplexity(scopeNode);
|
|
2363
2453
|
if (codeComplexity > exports.maxCodeComplexity) {
|
|
2364
2454
|
let errorRange = scopeNode;
|
|
2365
2455
|
if (scopeNode.nodeType === 31 /* ParseNodeType.Function */) {
|
|
@@ -2368,7 +2458,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
2368
2458
|
else if (scopeNode.nodeType === 36 /* ParseNodeType.Module */) {
|
|
2369
2459
|
errorRange = { start: 0, length: 0 };
|
|
2370
2460
|
}
|
|
2371
|
-
const fileInfo =
|
|
2461
|
+
const fileInfo = nodeInfo.getFileInfo(node);
|
|
2372
2462
|
addDiagnosticForTextRange(fileInfo, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.LocMessage.codeTooComplexToAnalyze(), errorRange);
|
|
2373
2463
|
return true;
|
|
2374
2464
|
}
|
|
@@ -2384,18 +2474,18 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
2384
2474
|
if (checkCodeFlowTooComplex(node)) {
|
|
2385
2475
|
return typeEvaluatorTypes_1.Reachability.Reachable;
|
|
2386
2476
|
}
|
|
2387
|
-
const flowNode =
|
|
2477
|
+
const flowNode = nodeInfo.getFlowNode(node);
|
|
2388
2478
|
if (!flowNode) {
|
|
2389
2479
|
if (node.parent) {
|
|
2390
2480
|
return getNodeReachability(node.parent, sourceNode);
|
|
2391
2481
|
}
|
|
2392
2482
|
return typeEvaluatorTypes_1.Reachability.UnreachableStructural;
|
|
2393
2483
|
}
|
|
2394
|
-
const sourceFlowNode = sourceNode ?
|
|
2484
|
+
const sourceFlowNode = sourceNode ? nodeInfo.getFlowNode(sourceNode) : undefined;
|
|
2395
2485
|
return codeFlowEngine.getFlowNodeReachability(flowNode, sourceFlowNode);
|
|
2396
2486
|
}
|
|
2397
2487
|
function getAfterNodeReachability(node) {
|
|
2398
|
-
const returnFlowNode =
|
|
2488
|
+
const returnFlowNode = nodeInfo.getAfterFlowNode(node);
|
|
2399
2489
|
if (!returnFlowNode) {
|
|
2400
2490
|
return typeEvaluatorTypes_1.Reachability.UnreachableStructural;
|
|
2401
2491
|
}
|
|
@@ -2406,7 +2496,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
2406
2496
|
if (reachability !== typeEvaluatorTypes_1.Reachability.Reachable) {
|
|
2407
2497
|
return reachability;
|
|
2408
2498
|
}
|
|
2409
|
-
const executionScopeNode = ParseTreeUtils.getExecutionScopeNode(node);
|
|
2499
|
+
const executionScopeNode = ParseTreeUtils.getExecutionScopeNode(node, nodeInfo);
|
|
2410
2500
|
if (!isFlowNodeReachableUsingNeverNarrowing(executionScopeNode, returnFlowNode)) {
|
|
2411
2501
|
return typeEvaluatorTypes_1.Reachability.UnreachableByAnalysis;
|
|
2412
2502
|
}
|
|
@@ -2429,8 +2519,8 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
2429
2519
|
if (checkCodeFlowTooComplex(sourceNode)) {
|
|
2430
2520
|
return true;
|
|
2431
2521
|
}
|
|
2432
|
-
const sourceFlowNode =
|
|
2433
|
-
const sinkFlowNode =
|
|
2522
|
+
const sourceFlowNode = nodeInfo.getFlowNode(sourceNode);
|
|
2523
|
+
const sinkFlowNode = nodeInfo.getFlowNode(sinkNode);
|
|
2434
2524
|
if (!sourceFlowNode || !sinkFlowNode) {
|
|
2435
2525
|
return false;
|
|
2436
2526
|
}
|
|
@@ -2448,7 +2538,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
2448
2538
|
return;
|
|
2449
2539
|
}
|
|
2450
2540
|
if (!isDiagnosticSuppressedForNode(node)) {
|
|
2451
|
-
const fileInfo =
|
|
2541
|
+
const fileInfo = nodeInfo.getFileInfo(node);
|
|
2452
2542
|
const reportTypeReachability = fileInfo.diagnosticRuleSet.enableReachabilityAnalysis;
|
|
2453
2543
|
if (reachability === typeEvaluatorTypes_1.Reachability.UnreachableStructural ||
|
|
2454
2544
|
reachability === typeEvaluatorTypes_1.Reachability.UnreachableStaticCondition ||
|
|
@@ -2463,7 +2553,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
2463
2553
|
}
|
|
2464
2554
|
function addDeprecated(message, node) {
|
|
2465
2555
|
if (!isDiagnosticSuppressedForNode(node)) {
|
|
2466
|
-
const fileInfo =
|
|
2556
|
+
const fileInfo = nodeInfo.getFileInfo(node);
|
|
2467
2557
|
fileInfo.diagnosticSink.addDeprecatedWithTextRange(message, node);
|
|
2468
2558
|
}
|
|
2469
2559
|
}
|
|
@@ -2476,7 +2566,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
2476
2566
|
return undefined;
|
|
2477
2567
|
}
|
|
2478
2568
|
if (isNodeReachable(node)) {
|
|
2479
|
-
const fileInfo =
|
|
2569
|
+
const fileInfo = nodeInfo.getFileInfo(node);
|
|
2480
2570
|
return fileInfo.diagnosticSink.addDiagnosticWithTextRange(diagLevel, message, range ?? node);
|
|
2481
2571
|
}
|
|
2482
2572
|
return undefined;
|
|
@@ -2501,7 +2591,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
2501
2591
|
return suppressedEntries.every((entry) => !entry.suppressedDiags);
|
|
2502
2592
|
}
|
|
2503
2593
|
function addDiagnostic(rule, message, node, range) {
|
|
2504
|
-
const fileInfo =
|
|
2594
|
+
const fileInfo = nodeInfo.getFileInfo(node);
|
|
2505
2595
|
const diagLevel = fileInfo.diagnosticRuleSet[rule];
|
|
2506
2596
|
if (diagLevel === 'none') {
|
|
2507
2597
|
return undefined;
|
|
@@ -2509,7 +2599,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
2509
2599
|
const containingFunction = ParseTreeUtils.getEnclosingFunction(node);
|
|
2510
2600
|
if (containingFunction) {
|
|
2511
2601
|
// Should we suppress this diagnostic because it's within an unannotated function?
|
|
2512
|
-
const fileInfo =
|
|
2602
|
+
const fileInfo = nodeInfo.getFileInfo(node);
|
|
2513
2603
|
if (!fileInfo.diagnosticRuleSet.analyzeUnannotatedFunctions) {
|
|
2514
2604
|
// Is the target node within the body of the function? If so, suppress the diagnostic.
|
|
2515
2605
|
if (ParseTreeUtils.isUnannotatedFunction(containingFunction) &&
|
|
@@ -2519,7 +2609,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
2519
2609
|
}
|
|
2520
2610
|
// Should we suppress this diagnostic because it's within a no_type_check function?
|
|
2521
2611
|
const containingClassNode = ParseTreeUtils.getEnclosingClass(containingFunction, /* stopAtFunction */ true);
|
|
2522
|
-
const functionInfo = (0, decorators_1.getFunctionInfoFromDecorators)(evaluatorInterface, containingFunction, !!containingClassNode);
|
|
2612
|
+
const functionInfo = (0, decorators_1.getFunctionInfoFromDecorators)(evaluatorInterface, containingFunction, !!containingClassNode, nodeInfo);
|
|
2523
2613
|
if ((functionInfo.flags & 524288 /* FunctionTypeFlags.NoTypeCheck */) !== 0) {
|
|
2524
2614
|
return undefined;
|
|
2525
2615
|
}
|
|
@@ -2551,7 +2641,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
2551
2641
|
}
|
|
2552
2642
|
const declarations = symbolWithScope.symbol.getDeclarations();
|
|
2553
2643
|
let declaredType = getDeclaredTypeOfSymbol(symbolWithScope.symbol)?.type;
|
|
2554
|
-
const fileInfo =
|
|
2644
|
+
const fileInfo = nodeInfo.getFileInfo(nameNode);
|
|
2555
2645
|
// If this is a class scope and there is no type declared for this class variable,
|
|
2556
2646
|
// see if a parent class has a type declared.
|
|
2557
2647
|
if (declaredType === undefined && symbolWithScope.scope.type === 3 /* ScopeType.Class */) {
|
|
@@ -2571,7 +2661,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
2571
2661
|
const isTypeAlias = !!declaredType && (0, types_1.isClassInstance)(declaredType) && types_1.ClassType.isBuiltIn(declaredType, 'TypeAlias');
|
|
2572
2662
|
if (declaredType && !isTypeAlias) {
|
|
2573
2663
|
let diagAddendum = new diagnostic_1.DiagnosticAddendum();
|
|
2574
|
-
const liveScopeIds =
|
|
2664
|
+
const liveScopeIds = getTypeVarScopesForNode(nameNode);
|
|
2575
2665
|
const boundDeclaredType = (0, typeUtils_1.makeTypeVarsBound)(declaredType, liveScopeIds);
|
|
2576
2666
|
const srcType = (0, typeUtils_1.makeTypeVarsBound)(typeResult.type, liveScopeIds);
|
|
2577
2667
|
if (!assignType(boundDeclaredType, srcType, diagAddendum)) {
|
|
@@ -2597,7 +2687,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
2597
2687
|
// appears to be a constant, use the strict source type. If it's a member
|
|
2598
2688
|
// variable that can be overridden by a child class, use the more general
|
|
2599
2689
|
// version by stripping off the literal and TypeForm.
|
|
2600
|
-
const scope =
|
|
2690
|
+
const scope = getScopeForNode(nameNode);
|
|
2601
2691
|
if (scope?.type === 3 /* ScopeType.Class */) {
|
|
2602
2692
|
if (types_1.TypeBase.isInstance(destType) &&
|
|
2603
2693
|
!(0, symbolNameUtils_1.isConstantName)(nameValue) &&
|
|
@@ -2695,7 +2785,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
2695
2785
|
}
|
|
2696
2786
|
function assignTypeToMemberVariable(node, typeResult, isInstanceMember, srcExprNode) {
|
|
2697
2787
|
const memberName = node.d.member.d.value;
|
|
2698
|
-
const fileInfo =
|
|
2788
|
+
const fileInfo = nodeInfo.getFileInfo(node);
|
|
2699
2789
|
const classDef = ParseTreeUtils.getEnclosingClass(node);
|
|
2700
2790
|
if (!classDef) {
|
|
2701
2791
|
return;
|
|
@@ -3101,8 +3191,8 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
3101
3191
|
return type;
|
|
3102
3192
|
}
|
|
3103
3193
|
function markNamesAccessed(node, names) {
|
|
3104
|
-
const fileInfo =
|
|
3105
|
-
const scope =
|
|
3194
|
+
const fileInfo = nodeInfo.getFileInfo(node);
|
|
3195
|
+
const scope = getScopeForNode(node);
|
|
3106
3196
|
if (scope) {
|
|
3107
3197
|
names.forEach((symbolName) => {
|
|
3108
3198
|
const symbolInScope = scope.lookUpSymbolRecursive(symbolName);
|
|
@@ -3327,7 +3417,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
3327
3417
|
}
|
|
3328
3418
|
}
|
|
3329
3419
|
function getTypeOfName(node, flags) {
|
|
3330
|
-
const fileInfo =
|
|
3420
|
+
const fileInfo = nodeInfo.getFileInfo(node);
|
|
3331
3421
|
const name = node.d.value;
|
|
3332
3422
|
let symbol;
|
|
3333
3423
|
let type;
|
|
@@ -3448,6 +3538,10 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
3448
3538
|
type = types_1.UnknownType.create();
|
|
3449
3539
|
}
|
|
3450
3540
|
}
|
|
3541
|
+
if ((0, types_1.isTypeVarTuple)(type) && (flags & 64 /* EvalFlags.NoTypeVarTuple */) !== 0 && !type.priv.isInUnion) {
|
|
3542
|
+
addDiagnostic(diagnosticRules_1.DiagnosticRule.reportInvalidTypeForm, localize_1.LocMessage.typeVarTupleContext(), node);
|
|
3543
|
+
type = types_1.UnknownType.create();
|
|
3544
|
+
}
|
|
3451
3545
|
// If we're expecting a type expression and got a sentinel literal instance,
|
|
3452
3546
|
// treat it as its instantiable counterpart. This is similar to how None
|
|
3453
3547
|
// is treated in a type expression context.
|
|
@@ -3458,16 +3552,64 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
3458
3552
|
if ((flags & 256 /* EvalFlags.TypeExpression */) === 0) {
|
|
3459
3553
|
reportUseOfTypeCheckOnly(type, node);
|
|
3460
3554
|
}
|
|
3461
|
-
if ((flags & 128 /* EvalFlags.InstantiableType */) !== 0) {
|
|
3555
|
+
if ((flags & (128 /* EvalFlags.InstantiableType */ | 1073741824 /* EvalFlags.TypeFormArg */)) !== 0) {
|
|
3462
3556
|
if ((flags & 1024 /* EvalFlags.AllowGeneric */) === 0) {
|
|
3463
3557
|
if ((0, types_1.isInstantiableClass)(type) && types_1.ClassType.isBuiltIn(type, 'Generic')) {
|
|
3464
3558
|
addDiagnostic(diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.LocMessage.genericNotAllowed(), node);
|
|
3559
|
+
if ((flags & 1073741824 /* EvalFlags.TypeFormArg */) !== 0) {
|
|
3560
|
+
type = types_1.UnknownType.create();
|
|
3561
|
+
}
|
|
3465
3562
|
}
|
|
3466
3563
|
}
|
|
3467
3564
|
}
|
|
3468
3565
|
return { type, isIncomplete };
|
|
3469
3566
|
}
|
|
3567
|
+
const typeFormSpecialFormDiagnosticFactories = [
|
|
3568
|
+
['Final', () => localize_1.LocMessage.finalContext()],
|
|
3569
|
+
['Optional', () => localize_1.LocMessage.optionalExtraArgs()],
|
|
3570
|
+
['Protocol', () => localize_1.LocMessage.protocolNotAllowed()],
|
|
3571
|
+
['TypedDict', () => localize_1.LocMessage.typedDictNotAllowed()],
|
|
3572
|
+
['TypeAlias', () => localize_1.LocMessage.typeAnnotationVariable()],
|
|
3573
|
+
['Literal', () => localize_1.LocMessage.literalNotAllowed()],
|
|
3574
|
+
[['TypeGuard', 'TypeIs'], () => localize_1.LocMessage.typeGuardArgCount()],
|
|
3575
|
+
['Union', () => localize_1.LocMessage.unionTypeArgCount()],
|
|
3576
|
+
['Annotated', () => localize_1.LocMessage.annotatedTypeArgMissing()],
|
|
3577
|
+
['ClassVar', () => localize_1.LocMessage.classVarNotAllowed()],
|
|
3578
|
+
['Required', () => localize_1.LocMessage.requiredArgCount()],
|
|
3579
|
+
['NotRequired', () => localize_1.LocMessage.notRequiredArgCount()],
|
|
3580
|
+
['ReadOnly', () => localize_1.LocMessage.readOnlyArgCount()],
|
|
3581
|
+
['Unpack', () => localize_1.LocMessage.unpackArgCount()],
|
|
3582
|
+
['Concatenate', () => localize_1.LocMessage.concatenateContext()],
|
|
3583
|
+
];
|
|
3584
|
+
function rejectBareSpecialFormInTypeForm(type, node) {
|
|
3585
|
+
for (const [className, diagnosticFactory] of typeFormSpecialFormDiagnosticFactories) {
|
|
3586
|
+
if (types_1.ClassType.isBuiltIn(type, className)) {
|
|
3587
|
+
addDiagnostic(diagnosticRules_1.DiagnosticRule.reportInvalidTypeForm, diagnosticFactory(), node);
|
|
3588
|
+
return types_1.UnknownType.create();
|
|
3589
|
+
}
|
|
3590
|
+
}
|
|
3591
|
+
return undefined;
|
|
3592
|
+
}
|
|
3470
3593
|
function addTypeFormForSymbol(node, type, flags, includesVarDecl) {
|
|
3594
|
+
const isIndexBase = node.parent?.nodeType === 27 /* ParseNodeType.Index */ && node.parent.d.leftExpr === node;
|
|
3595
|
+
if ((flags & 1073741824 /* EvalFlags.TypeFormArg */) !== 0 && (0, types_1.isTypeVar)(type) && types_1.TypeVarType.isSelf(type)) {
|
|
3596
|
+
type = types_1.TypeBase.cloneWithTypeForm(type, (0, typeUtils_1.convertToInstance)(type));
|
|
3597
|
+
}
|
|
3598
|
+
if ((flags & 1073741824 /* EvalFlags.TypeFormArg */) !== 0 && (0, types_1.isInstantiableClass)(type) && !isIndexBase) {
|
|
3599
|
+
if (isTypeFormClass(type)) {
|
|
3600
|
+
return createTypeFormType(type, node, /* typeArgs */ undefined);
|
|
3601
|
+
}
|
|
3602
|
+
const rejectedType = rejectBareSpecialFormInTypeForm(type, node);
|
|
3603
|
+
if (rejectedType) {
|
|
3604
|
+
return rejectedType;
|
|
3605
|
+
}
|
|
3606
|
+
if (types_1.ClassType.isBuiltIn(type, 'Self')) {
|
|
3607
|
+
type = createSelfType(type, node, /* typeArgs */ undefined, flags);
|
|
3608
|
+
if ((0, types_1.isTypeVar)(type)) {
|
|
3609
|
+
type = types_1.TypeBase.cloneWithTypeForm(type, (0, typeUtils_1.convertToInstance)(type));
|
|
3610
|
+
}
|
|
3611
|
+
}
|
|
3612
|
+
}
|
|
3471
3613
|
const isValid = isSymbolValidTypeExpression(type, includesVarDecl);
|
|
3472
3614
|
// If the type already has type information associated with it, don't replace.
|
|
3473
3615
|
if (type.props?.typeForm) {
|
|
@@ -3486,7 +3628,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
3486
3628
|
}
|
|
3487
3629
|
if ((0, types_1.isTypeVar)(type) && type.priv.scopeId && !type.shared.isSynthesized) {
|
|
3488
3630
|
if (!(0, types_1.isTypeVarTuple)(type) || !type.priv.isInUnion) {
|
|
3489
|
-
const liveScopeIds =
|
|
3631
|
+
const liveScopeIds = getTypeVarScopesForNode(node);
|
|
3490
3632
|
type = types_1.TypeBase.cloneWithTypeForm(type, (0, typeUtils_1.convertToInstance)((0, typeUtils_1.makeTypeVarsBound)(type, liveScopeIds)));
|
|
3491
3633
|
}
|
|
3492
3634
|
}
|
|
@@ -3535,7 +3677,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
3535
3677
|
return type;
|
|
3536
3678
|
}
|
|
3537
3679
|
// Disable for assignments in the typings.pyi file, since it defines special forms.
|
|
3538
|
-
const fileInfo =
|
|
3680
|
+
const fileInfo = nodeInfo.getFileInfo(node);
|
|
3539
3681
|
if (fileInfo.isTypingStubFile) {
|
|
3540
3682
|
return type;
|
|
3541
3683
|
}
|
|
@@ -3598,28 +3740,27 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
3598
3740
|
// If the symbol is modified in scopes other than the one in which it is
|
|
3599
3741
|
// declared (e.g. through a nonlocal or global binding), it is not eligible
|
|
3600
3742
|
// for code flow analysis.
|
|
3601
|
-
if (!decls.every((decl) => decl.type === 2 /* DeclarationType.Param */ ||
|
|
3602
|
-
ScopeUtils.getScopeForNode(decl.node) === symbolWithScope.scope)) {
|
|
3743
|
+
if (!decls.every((decl) => decl.type === 2 /* DeclarationType.Param */ || getScopeForNode(decl.node) === symbolWithScope.scope)) {
|
|
3603
3744
|
return undefined;
|
|
3604
3745
|
}
|
|
3605
3746
|
// If the symbol is a non-final variable in the global scope, it is not
|
|
3606
3747
|
// eligible because it could be modified by other modules.
|
|
3607
3748
|
if (!decls.every((decl) => decl.type !== 1 /* DeclarationType.Variable */ ||
|
|
3608
3749
|
decl.isFinal ||
|
|
3609
|
-
|
|
3750
|
+
getScopeForNode(decl.node)?.type !== 4 /* ScopeType.Module */)) {
|
|
3610
3751
|
return undefined;
|
|
3611
3752
|
}
|
|
3612
3753
|
// If the symbol is a variable captured by an inner function
|
|
3613
3754
|
// or lambda, see if we can infer the type from the outer scope.
|
|
3614
|
-
const scopeHierarchy =
|
|
3755
|
+
const scopeHierarchy = getScopeHierarchy(node, symbolWithScope.scope);
|
|
3615
3756
|
if (scopeHierarchy && scopeHierarchy.length >= 2) {
|
|
3616
3757
|
// Find the parse node associated with the scope that is just inside of the
|
|
3617
3758
|
// scope that declares the captured variable.
|
|
3618
|
-
const innerScopeNode =
|
|
3759
|
+
const innerScopeNode = findTopNodeInScope(node, scopeHierarchy[scopeHierarchy.length - 2]);
|
|
3619
3760
|
if (innerScopeNode?.nodeType === 31 /* ParseNodeType.Function */ ||
|
|
3620
3761
|
innerScopeNode?.nodeType === 33 /* ParseNodeType.Lambda */ ||
|
|
3621
3762
|
innerScopeNode?.nodeType === 10 /* ParseNodeType.Class */) {
|
|
3622
|
-
const innerScopeCodeFlowNode =
|
|
3763
|
+
const innerScopeCodeFlowNode = nodeInfo.getFlowNode(innerScopeNode);
|
|
3623
3764
|
if (innerScopeCodeFlowNode) {
|
|
3624
3765
|
// See if any of the assignments of the symbol are reachable
|
|
3625
3766
|
// from this node. If so, we cannot apply any narrowing because
|
|
@@ -3630,7 +3771,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
3630
3771
|
if (decl.type === 2 /* DeclarationType.Param */) {
|
|
3631
3772
|
return true;
|
|
3632
3773
|
}
|
|
3633
|
-
const declCodeFlowNode =
|
|
3774
|
+
const declCodeFlowNode = nodeInfo.getFlowNode(decl.node);
|
|
3634
3775
|
if (!declCodeFlowNode) {
|
|
3635
3776
|
return false;
|
|
3636
3777
|
}
|
|
@@ -3749,7 +3890,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
3749
3890
|
container: enclosingScope.d.name.d.value,
|
|
3750
3891
|
}), node);
|
|
3751
3892
|
}
|
|
3752
|
-
const scopeIdToAssign =
|
|
3893
|
+
const scopeIdToAssign = getScopeIdForNode(enclosingScope);
|
|
3753
3894
|
return types_1.TypeVarType.cloneForScopeId(type, scopeIdToAssign, enclosingScope.d.name.d.value, enclosingScope.nodeType === 31 /* ParseNodeType.Function */ ? 1 /* TypeVarScopeType.Function */ : 0 /* TypeVarScopeType.Class */);
|
|
3754
3895
|
}
|
|
3755
3896
|
if ((flags & 4096 /* EvalFlags.AllowTypeVarWithoutScopeId */) === 0) {
|
|
@@ -3774,7 +3915,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
3774
3915
|
}
|
|
3775
3916
|
const enclosingClass = ParseTreeUtils.getEnclosingClass(node);
|
|
3776
3917
|
if (enclosingClass) {
|
|
3777
|
-
const liveTypeVarScopeIds =
|
|
3918
|
+
const liveTypeVarScopeIds = getTypeVarScopesForNode(enclosingClass);
|
|
3778
3919
|
if (!liveTypeVarScopeIds.includes(scopeId)) {
|
|
3779
3920
|
addDiagnostic(diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.LocMessage.typeVarInvalidForMemberVariable().format({
|
|
3780
3921
|
name: types_1.TypeVarType.getReadableName(type),
|
|
@@ -3794,7 +3935,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
3794
3935
|
// Is this a generic class that needs to be specialized?
|
|
3795
3936
|
if ((0, types_1.isInstantiableClass)(type)) {
|
|
3796
3937
|
if ((flags & 128 /* EvalFlags.InstantiableType */) !== 0 && (flags & 512 /* EvalFlags.AllowMissingTypeArgs */) === 0) {
|
|
3797
|
-
if (!type.props?.typeAliasInfo && (0, typeUtils_1.requiresTypeArgs)(type)) {
|
|
3938
|
+
if (!type.props?.typeAliasInfo && !isTypeFormClass(type) && (0, typeUtils_1.requiresTypeArgs)(type)) {
|
|
3798
3939
|
if (!type.priv.typeArgs || !type.priv.isTypeArgExplicit) {
|
|
3799
3940
|
addDiagnostic(diagnosticRules_1.DiagnosticRule.reportMissingTypeArgument, localize_1.LocMessage.typeArgsMissingForClass().format({
|
|
3800
3941
|
name: type.priv.aliasName || type.shared.name,
|
|
@@ -3995,7 +4136,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
3995
4136
|
}
|
|
3996
4137
|
}
|
|
3997
4138
|
if (!skipPartialUnknownCheck) {
|
|
3998
|
-
reportPossibleUnknownAssignment(
|
|
4139
|
+
reportPossibleUnknownAssignment(nodeInfo.getFileInfo(node).diagnosticRuleSet.reportUnknownMemberType, diagnosticRules_1.DiagnosticRule.reportUnknownMemberType, node.d.member, typeResult.type, node,
|
|
3999
4140
|
/* ignoreEmptyContainers */ false);
|
|
4000
4141
|
}
|
|
4001
4142
|
// Cache the type information in the member name node.
|
|
@@ -4006,7 +4147,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
4006
4147
|
let baseType = (0, typeUtils_1.transformPossibleRecursiveTypeAlias)(baseTypeResult.type);
|
|
4007
4148
|
const memberName = node.d.member.d.value;
|
|
4008
4149
|
let diag = new diagnostic_1.DiagnosticAddendum();
|
|
4009
|
-
const fileInfo =
|
|
4150
|
+
const fileInfo = nodeInfo.getFileInfo(node);
|
|
4010
4151
|
let type;
|
|
4011
4152
|
let narrowedTypeForSet;
|
|
4012
4153
|
let typeErrors = false;
|
|
@@ -4098,7 +4239,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
4098
4239
|
(0, types_1.isClass)(prefetched.functionClass)) {
|
|
4099
4240
|
baseType = types_1.ClassType.cloneAsInstance(prefetched.functionClass);
|
|
4100
4241
|
}
|
|
4101
|
-
const enumMemberResult = (0, enums_1.getTypeOfEnumMember)(evaluatorInterface, node, baseType, memberName, isIncomplete);
|
|
4242
|
+
const enumMemberResult = (0, enums_1.getTypeOfEnumMember)(evaluatorInterface, node, baseType, memberName, isIncomplete, nodeInfo);
|
|
4102
4243
|
if (enumMemberResult) {
|
|
4103
4244
|
if (usage.method === 'get') {
|
|
4104
4245
|
typeResult = enumMemberResult;
|
|
@@ -4448,7 +4589,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
4448
4589
|
if (errorNode &&
|
|
4449
4590
|
(0, types_1.isInstantiableClass)(memberInfo.classType) &&
|
|
4450
4591
|
types_1.ClassType.isSameGenericClass(memberInfo.classType, isAccessedThroughObject ? types_1.ClassType.cloneAsInstantiable(classType) : classType)) {
|
|
4451
|
-
setSymbolAccessed(
|
|
4592
|
+
setSymbolAccessed(nodeInfo.getFileInfo(errorNode), memberInfo.symbol, errorNode);
|
|
4452
4593
|
}
|
|
4453
4594
|
// Special-case `__init_subclass` and `__class_getitem__` because
|
|
4454
4595
|
// these are always treated as class methods even if they're not
|
|
@@ -4956,13 +5097,13 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
4956
5097
|
// they don't result in runtime exceptions when used in this manner.
|
|
4957
5098
|
let skipSubscriptCheck = (flags & 32768 /* EvalFlags.VarTypeAnnotation */) !== 0;
|
|
4958
5099
|
if (skipSubscriptCheck) {
|
|
4959
|
-
const scopeNode = ParseTreeUtils.getExecutionScopeNode(node);
|
|
5100
|
+
const scopeNode = ParseTreeUtils.getExecutionScopeNode(node, nodeInfo);
|
|
4960
5101
|
if (scopeNode?.nodeType === 36 /* ParseNodeType.Module */) {
|
|
4961
5102
|
skipSubscriptCheck = false;
|
|
4962
5103
|
}
|
|
4963
5104
|
}
|
|
4964
5105
|
if (!skipSubscriptCheck) {
|
|
4965
|
-
const fileInfo =
|
|
5106
|
+
const fileInfo = nodeInfo.getFileInfo(node);
|
|
4966
5107
|
if ((0, types_1.isInstantiableClass)(baseTypeResult.type) &&
|
|
4967
5108
|
types_1.ClassType.isBuiltIn(baseTypeResult.type) &&
|
|
4968
5109
|
!baseTypeResult.type.priv.aliasName) {
|
|
@@ -5199,6 +5340,10 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
5199
5340
|
}), { ...aliasInfo, typeArgs: defaultTypeArgs });
|
|
5200
5341
|
return type;
|
|
5201
5342
|
}
|
|
5343
|
+
function convertTypeArgToInstance(type, flags) {
|
|
5344
|
+
const contextualType = (flags & 1073741824 /* EvalFlags.TypeFormArg */) !== 0 ? type.props?.typeForm ?? type : type;
|
|
5345
|
+
return (0, typeUtils_1.convertToInstance)(contextualType);
|
|
5346
|
+
}
|
|
5202
5347
|
// Handles index expressions that are providing type arguments for a
|
|
5203
5348
|
// generic type alias.
|
|
5204
5349
|
function createSpecializedTypeAlias(node, baseType, flags) {
|
|
@@ -5318,7 +5463,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
5318
5463
|
}
|
|
5319
5464
|
let typeArgType;
|
|
5320
5465
|
if (index < typeArgs.length) {
|
|
5321
|
-
typeArgType = (
|
|
5466
|
+
typeArgType = convertTypeArgToInstance(typeArgs[index].type, flags);
|
|
5322
5467
|
}
|
|
5323
5468
|
else if (param.shared.isDefaultExplicit) {
|
|
5324
5469
|
typeArgType = solveAndApplyConstraints(param, constraints, {
|
|
@@ -5473,11 +5618,15 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
5473
5618
|
if (types_1.ClassType.isBuiltIn(concreteSubtype, 'InitVar')) {
|
|
5474
5619
|
// Special-case InitVar, used in dataclasses.
|
|
5475
5620
|
const typeArgs = getTypeArgs(node, flags);
|
|
5476
|
-
|
|
5477
|
-
|
|
5621
|
+
const isTypeFormArg = (flags & 1073741824 /* EvalFlags.TypeFormArg */) !== 0;
|
|
5622
|
+
if ((flags & 256 /* EvalFlags.TypeExpression */) !== 0 || isTypeFormArg) {
|
|
5623
|
+
if (isTypeFormArg || (flags & 32768 /* EvalFlags.VarTypeAnnotation */) === 0) {
|
|
5478
5624
|
addDiagnostic(diagnosticRules_1.DiagnosticRule.reportInvalidTypeForm, localize_1.LocMessage.initVarNotAllowed(), node.d.leftExpr);
|
|
5479
5625
|
}
|
|
5480
5626
|
}
|
|
5627
|
+
if (isTypeFormArg) {
|
|
5628
|
+
return types_1.UnknownType.create();
|
|
5629
|
+
}
|
|
5481
5630
|
if (typeArgs.length === 1) {
|
|
5482
5631
|
return typeArgs[0].type;
|
|
5483
5632
|
}
|
|
@@ -5503,7 +5652,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
5503
5652
|
const isFinalAnnotation = (0, types_1.isInstantiableClass)(concreteSubtype) && types_1.ClassType.isBuiltIn(concreteSubtype, 'Final');
|
|
5504
5653
|
const isClassVarAnnotation = (0, types_1.isInstantiableClass)(concreteSubtype) && types_1.ClassType.isBuiltIn(concreteSubtype, 'ClassVar');
|
|
5505
5654
|
// This feature is currently experimental.
|
|
5506
|
-
const supportsTypedDictTypeArg =
|
|
5655
|
+
const supportsTypedDictTypeArg = nodeInfo.getFileInfo(node).diagnosticRuleSet.enableExperimentalFeatures &&
|
|
5507
5656
|
types_1.ClassType.isBuiltIn(concreteSubtype, 'TypedDict');
|
|
5508
5657
|
let typeArgs = getTypeArgs(node, flags, {
|
|
5509
5658
|
isAnnotatedClass,
|
|
@@ -5562,12 +5711,16 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
5562
5711
|
}
|
|
5563
5712
|
return types_1.UnknownType.create();
|
|
5564
5713
|
});
|
|
5565
|
-
// In case we didn't walk the list items above, do so now.
|
|
5566
|
-
//
|
|
5714
|
+
// In case we didn't walk the list items above, do so now. TypeForm arguments
|
|
5715
|
+
// use a separate cache, so check it when the enclosing expression is a TypeForm.
|
|
5567
5716
|
if (!baseTypeResult.isIncomplete) {
|
|
5717
|
+
const isTypeFormArg = (flags & 1073741824 /* EvalFlags.TypeFormArg */) !== 0;
|
|
5568
5718
|
node.d.items.forEach((item) => {
|
|
5569
|
-
|
|
5570
|
-
|
|
5719
|
+
const isItemCached = isTypeFormArg
|
|
5720
|
+
? isTypeFormTypeCached(item.d.valueExpr, /* expectedType */ undefined)
|
|
5721
|
+
: isTypeCached(item.d.valueExpr);
|
|
5722
|
+
if (!isItemCached) {
|
|
5723
|
+
getTypeOfExpression(item.d.valueExpr, flags & (4 /* EvalFlags.ForwardRefs */ | 1073741824 /* EvalFlags.TypeFormArg */));
|
|
5571
5724
|
}
|
|
5572
5725
|
});
|
|
5573
5726
|
}
|
|
@@ -5862,7 +6015,9 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
5862
6015
|
function getTypeArgs(node, flags, options) {
|
|
5863
6016
|
const typeArgs = [];
|
|
5864
6017
|
let adjFlags = flags | 33554432 /* EvalFlags.NoConvertSpecialForm */;
|
|
5865
|
-
adjFlags
|
|
6018
|
+
if ((adjFlags & 1073741824 /* EvalFlags.TypeFormArg */) !== 0) {
|
|
6019
|
+
adjFlags |= 256 /* EvalFlags.TypeExpression */;
|
|
6020
|
+
}
|
|
5866
6021
|
const allowFinalClassVar = () => {
|
|
5867
6022
|
// If the annotation is a variable within the body of a dataclass, a
|
|
5868
6023
|
// Final is allowed with a ClassVar annotation. In all other cases,
|
|
@@ -5917,7 +6072,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
5917
6072
|
// treated as a type. The others can be regular (non-type) objects.
|
|
5918
6073
|
adjFlags =
|
|
5919
6074
|
32 /* EvalFlags.NoParamSpec */ | 64 /* EvalFlags.NoTypeVarTuple */ | 2 /* EvalFlags.NoSpecialize */ | 131072 /* EvalFlags.NoClassVar */;
|
|
5920
|
-
if ((0, analyzerFileInfo_1.isAnnotationEvaluationPostponed)(
|
|
6075
|
+
if ((0, analyzerFileInfo_1.isAnnotationEvaluationPostponed)(nodeInfo.getFileInfo(node))) {
|
|
5921
6076
|
adjFlags |= 4 /* EvalFlags.ForwardRefs */;
|
|
5922
6077
|
}
|
|
5923
6078
|
typeResult = {
|
|
@@ -6007,7 +6162,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
6007
6162
|
function getTypeArg(node, flags, supportsDictExpression) {
|
|
6008
6163
|
let typeResult;
|
|
6009
6164
|
let adjustedFlags = flags | 128 /* EvalFlags.InstantiableType */ | 1 /* EvalFlags.ConvertEllipsisToAny */ | 8 /* EvalFlags.StrLiteralAsType */;
|
|
6010
|
-
const fileInfo =
|
|
6165
|
+
const fileInfo = nodeInfo.getFileInfo(node);
|
|
6011
6166
|
if (fileInfo.isStubFile) {
|
|
6012
6167
|
adjustedFlags |= 4 /* EvalFlags.ForwardRefs */;
|
|
6013
6168
|
}
|
|
@@ -6024,7 +6179,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
6024
6179
|
}
|
|
6025
6180
|
else if (node.nodeType === 18 /* ParseNodeType.Dictionary */ && supportsDictExpression) {
|
|
6026
6181
|
const inlinedTypeDict = prefetched?.typedDictClass && (0, types_1.isInstantiableClass)(prefetched.typedDictClass)
|
|
6027
|
-
? (0, typedDicts_1.createTypedDictTypeInlined)(evaluatorInterface, node, prefetched.typedDictClass)
|
|
6182
|
+
? (0, typedDicts_1.createTypedDictTypeInlined)(evaluatorInterface, node, prefetched.typedDictClass, nodeInfo)
|
|
6028
6183
|
: undefined;
|
|
6029
6184
|
const keyTypeFallback = prefetched?.strClass && (0, types_1.isInstantiableClass)(prefetched.strClass)
|
|
6030
6185
|
? prefetched.strClass
|
|
@@ -6190,13 +6345,21 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
6190
6345
|
// have invalid type parameters.
|
|
6191
6346
|
const isCyclicalTypeVarCall = (0, types_1.isInstantiableClass)(baseTypeResult.type) &&
|
|
6192
6347
|
types_1.ClassType.isBuiltIn(baseTypeResult.type, 'TypeVar') &&
|
|
6193
|
-
|
|
6194
|
-
|
|
6348
|
+
nodeInfo.getFileInfo(node).isTypingStubFile;
|
|
6349
|
+
const isTypeFormCall = (0, types_1.isInstantiableClass)(baseTypeResult.type) && isTypeFormClass(baseTypeResult.type);
|
|
6350
|
+
if (!isCyclicalTypeVarCall && !isTypeFormCall) {
|
|
6195
6351
|
argList.forEach((arg) => {
|
|
6196
|
-
|
|
6197
|
-
|
|
6198
|
-
|
|
6199
|
-
|
|
6352
|
+
const valueExpression = arg.valueExpression;
|
|
6353
|
+
if (valueExpression &&
|
|
6354
|
+
valueExpression.nodeType !== 48 /* ParseNodeType.StringList */ &&
|
|
6355
|
+
!isTypeCached(valueExpression)) {
|
|
6356
|
+
const expectedType = expectedTypeCache.get(valueExpression.id)?.type;
|
|
6357
|
+
if (isTypeFormTypeCached(valueExpression, expectedType)) {
|
|
6358
|
+
suppressDiagnostics(valueExpression, () => getTypeOfExpression(valueExpression));
|
|
6359
|
+
}
|
|
6360
|
+
else {
|
|
6361
|
+
getTypeOfExpression(valueExpression);
|
|
6362
|
+
}
|
|
6200
6363
|
}
|
|
6201
6364
|
});
|
|
6202
6365
|
}
|
|
@@ -6266,6 +6429,166 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
6266
6429
|
}
|
|
6267
6430
|
return typeFormResult;
|
|
6268
6431
|
}
|
|
6432
|
+
function expandEnumTypeForLiteralComparison(typeToExpand, comparisonType, concretizeTypeVars) {
|
|
6433
|
+
// Assignment checks apply this at each recursive assignType call so existing
|
|
6434
|
+
// variance and constraint handling remains intact. Keep this equivalence
|
|
6435
|
+
// relation aligned with the recursive normalization used by assert_type below.
|
|
6436
|
+
if (!containsTopLevelLiteralEnum(comparisonType)) {
|
|
6437
|
+
return typeToExpand;
|
|
6438
|
+
}
|
|
6439
|
+
const literalEnumClasses = collectLiteralEnumClasses(comparisonType);
|
|
6440
|
+
if (literalEnumClasses.length === 0) {
|
|
6441
|
+
return typeToExpand;
|
|
6442
|
+
}
|
|
6443
|
+
// Concretize top-level TypeVars only to probe for a matching enum subtype.
|
|
6444
|
+
// If no enum expansion actually occurs (for example, an unrelated source
|
|
6445
|
+
// TypeVar whose bound is not one of the comparison's enum classes), preserve
|
|
6446
|
+
// the original type rather than replacing the TypeVar with its bound. Doing so
|
|
6447
|
+
// keeps unrelated invariant comparisons like `list[T]` vs `list[ColorLiterals]`
|
|
6448
|
+
// unaffected.
|
|
6449
|
+
const concreteType = concretizeTypeVars ? makeTopLevelTypeVarsConcrete(typeToExpand) : typeToExpand;
|
|
6450
|
+
const expandedType = expandEnumTypeForLiteralClasses(concreteType, literalEnumClasses);
|
|
6451
|
+
return expandedType === concreteType ? typeToExpand : expandedType;
|
|
6452
|
+
}
|
|
6453
|
+
function containsTopLevelLiteralEnum(type) {
|
|
6454
|
+
if ((0, types_1.isClassInstance)(type) && types_1.ClassType.isEnumClass(type) && type.priv.literalValue instanceof types_1.EnumLiteral) {
|
|
6455
|
+
return true;
|
|
6456
|
+
}
|
|
6457
|
+
if (!(0, types_1.isUnion)(type)) {
|
|
6458
|
+
return false;
|
|
6459
|
+
}
|
|
6460
|
+
return type.priv.includesEnumLiteral;
|
|
6461
|
+
}
|
|
6462
|
+
function expandEnumTypeForLiteralClasses(typeToExpand, literalEnumClasses) {
|
|
6463
|
+
if (literalEnumClasses.length === 0) {
|
|
6464
|
+
return typeToExpand;
|
|
6465
|
+
}
|
|
6466
|
+
return (0, typeUtils_1.mapSubtypes)(typeToExpand, (subtype) => {
|
|
6467
|
+
if ((0, types_1.isClassInstance)(subtype) &&
|
|
6468
|
+
types_1.ClassType.isEnumClass(subtype) &&
|
|
6469
|
+
!types_1.ClassType.isEnumMemberSetMayBeIncomplete(subtype) &&
|
|
6470
|
+
subtype.priv.literalValue === undefined &&
|
|
6471
|
+
literalEnumClasses.some((enumClass) => types_1.ClassType.isSameGenericClass(enumClass, subtype))) {
|
|
6472
|
+
const literalTypes = (0, typeGuards_1.enumerateLiteralsForType)(evaluatorInterface, subtype);
|
|
6473
|
+
if (literalTypes && literalTypes.length > 0) {
|
|
6474
|
+
return (0, types_1.combineTypes)(literalTypes);
|
|
6475
|
+
}
|
|
6476
|
+
}
|
|
6477
|
+
return subtype;
|
|
6478
|
+
});
|
|
6479
|
+
}
|
|
6480
|
+
function collectLiteralEnumClasses(type, literalEnumClasses = [], recursively = false, recursionCount = 0) {
|
|
6481
|
+
if (recursionCount > types_1.maxTypeRecursionCount) {
|
|
6482
|
+
return literalEnumClasses;
|
|
6483
|
+
}
|
|
6484
|
+
recursionCount++;
|
|
6485
|
+
if (recursively && (0, types_1.isFunction)(type)) {
|
|
6486
|
+
type.shared.parameters.forEach((_, index) => collectLiteralEnumClasses(types_1.FunctionType.getParamType(type, index), literalEnumClasses, recursively, recursionCount));
|
|
6487
|
+
const returnType = types_1.FunctionType.getEffectiveReturnType(type);
|
|
6488
|
+
if (returnType) {
|
|
6489
|
+
collectLiteralEnumClasses(returnType, literalEnumClasses, recursively, recursionCount);
|
|
6490
|
+
}
|
|
6491
|
+
}
|
|
6492
|
+
else if (recursively && (0, types_1.isOverloaded)(type)) {
|
|
6493
|
+
types_1.OverloadedType.getOverloads(type).forEach((overload) => collectLiteralEnumClasses(overload, literalEnumClasses, recursively, recursionCount));
|
|
6494
|
+
const implementation = types_1.OverloadedType.getImplementation(type);
|
|
6495
|
+
if (implementation) {
|
|
6496
|
+
collectLiteralEnumClasses(implementation, literalEnumClasses, recursively, recursionCount);
|
|
6497
|
+
}
|
|
6498
|
+
}
|
|
6499
|
+
(0, typeUtils_1.doForEachSubtype)(type, (subtype) => {
|
|
6500
|
+
if (!(0, types_1.isClass)(subtype)) {
|
|
6501
|
+
return;
|
|
6502
|
+
}
|
|
6503
|
+
if ((0, types_1.isClassInstance)(subtype) &&
|
|
6504
|
+
types_1.ClassType.isEnumClass(subtype) &&
|
|
6505
|
+
subtype.priv.literalValue instanceof types_1.EnumLiteral &&
|
|
6506
|
+
!literalEnumClasses.some((enumClass) => types_1.ClassType.isSameGenericClass(enumClass, subtype))) {
|
|
6507
|
+
literalEnumClasses.push(subtype);
|
|
6508
|
+
}
|
|
6509
|
+
if (recursively && subtype.priv.typeArgs) {
|
|
6510
|
+
if (subtype.priv.tupleTypeArgs) {
|
|
6511
|
+
subtype.priv.tupleTypeArgs.forEach((typeArg) => collectLiteralEnumClasses(typeArg.type, literalEnumClasses, recursively, recursionCount));
|
|
6512
|
+
}
|
|
6513
|
+
else {
|
|
6514
|
+
subtype.priv.typeArgs.forEach((typeArg) => collectLiteralEnumClasses(typeArg, literalEnumClasses, recursively, recursionCount));
|
|
6515
|
+
}
|
|
6516
|
+
}
|
|
6517
|
+
});
|
|
6518
|
+
return literalEnumClasses;
|
|
6519
|
+
}
|
|
6520
|
+
function normalizeEnumTypes(typeToNormalize, literalEnumClasses, recursionCount = 0) {
|
|
6521
|
+
if (recursionCount > types_1.maxTypeRecursionCount) {
|
|
6522
|
+
return typeToNormalize;
|
|
6523
|
+
}
|
|
6524
|
+
recursionCount++;
|
|
6525
|
+
typeToNormalize = expandEnumTypeForLiteralClasses(typeToNormalize, literalEnumClasses);
|
|
6526
|
+
if ((0, types_1.isUnion)(typeToNormalize)) {
|
|
6527
|
+
return (0, typeUtils_1.mapSubtypes)(typeToNormalize, (subtype) => normalizeEnumTypes(subtype, literalEnumClasses, recursionCount));
|
|
6528
|
+
}
|
|
6529
|
+
if ((0, types_1.isFunction)(typeToNormalize)) {
|
|
6530
|
+
let typeChanged = false;
|
|
6531
|
+
const parameterTypes = typeToNormalize.shared.parameters.map((_, index) => {
|
|
6532
|
+
const parameterType = types_1.FunctionType.getParamType(typeToNormalize, index);
|
|
6533
|
+
const normalizedType = normalizeEnumTypes(parameterType, literalEnumClasses, recursionCount);
|
|
6534
|
+
typeChanged || (typeChanged = normalizedType !== parameterType);
|
|
6535
|
+
return normalizedType;
|
|
6536
|
+
});
|
|
6537
|
+
const returnType = types_1.FunctionType.getEffectiveReturnType(typeToNormalize);
|
|
6538
|
+
const normalizedReturnType = returnType
|
|
6539
|
+
? normalizeEnumTypes(returnType, literalEnumClasses, recursionCount)
|
|
6540
|
+
: undefined;
|
|
6541
|
+
typeChanged || (typeChanged = normalizedReturnType !== returnType);
|
|
6542
|
+
return typeChanged
|
|
6543
|
+
? types_1.FunctionType.specialize(typeToNormalize, {
|
|
6544
|
+
parameterTypes,
|
|
6545
|
+
parameterDefaultTypes: typeToNormalize.priv.specializedTypes?.parameterDefaultTypes,
|
|
6546
|
+
returnType: normalizedReturnType,
|
|
6547
|
+
})
|
|
6548
|
+
: typeToNormalize;
|
|
6549
|
+
}
|
|
6550
|
+
if ((0, types_1.isOverloaded)(typeToNormalize)) {
|
|
6551
|
+
let typeChanged = false;
|
|
6552
|
+
const overloads = types_1.OverloadedType.getOverloads(typeToNormalize).map((overload) => {
|
|
6553
|
+
const normalizedType = normalizeEnumTypes(overload, literalEnumClasses, recursionCount);
|
|
6554
|
+
typeChanged || (typeChanged = normalizedType !== overload);
|
|
6555
|
+
return (0, types_1.isFunction)(normalizedType) ? normalizedType : overload;
|
|
6556
|
+
});
|
|
6557
|
+
const implementation = types_1.OverloadedType.getImplementation(typeToNormalize);
|
|
6558
|
+
const normalizedImplementation = implementation
|
|
6559
|
+
? normalizeEnumTypes(implementation, literalEnumClasses, recursionCount)
|
|
6560
|
+
: undefined;
|
|
6561
|
+
typeChanged || (typeChanged = normalizedImplementation !== implementation);
|
|
6562
|
+
return typeChanged ? types_1.OverloadedType.create(overloads, normalizedImplementation) : typeToNormalize;
|
|
6563
|
+
}
|
|
6564
|
+
if (!(0, types_1.isClass)(typeToNormalize) || !typeToNormalize.priv.typeArgs) {
|
|
6565
|
+
return typeToNormalize;
|
|
6566
|
+
}
|
|
6567
|
+
if (typeToNormalize.priv.tupleTypeArgs) {
|
|
6568
|
+
let typeChanged = false;
|
|
6569
|
+
const tupleTypeArgs = typeToNormalize.priv.tupleTypeArgs.map((typeArg) => {
|
|
6570
|
+
const normalizedType = normalizeEnumTypes(typeArg.type, literalEnumClasses, recursionCount);
|
|
6571
|
+
if (normalizedType !== typeArg.type) {
|
|
6572
|
+
typeChanged = true;
|
|
6573
|
+
}
|
|
6574
|
+
return { ...typeArg, type: normalizedType };
|
|
6575
|
+
});
|
|
6576
|
+
return typeChanged
|
|
6577
|
+
? (0, typeUtils_1.specializeTupleClass)(typeToNormalize, tupleTypeArgs, !!typeToNormalize.priv.isTypeArgExplicit, !!typeToNormalize.priv.isUnpacked)
|
|
6578
|
+
: typeToNormalize;
|
|
6579
|
+
}
|
|
6580
|
+
let typeChanged = false;
|
|
6581
|
+
const typeArgs = typeToNormalize.priv.typeArgs.map((typeArg) => {
|
|
6582
|
+
const normalizedType = normalizeEnumTypes(typeArg, literalEnumClasses, recursionCount);
|
|
6583
|
+
if (normalizedType !== typeArg) {
|
|
6584
|
+
typeChanged = true;
|
|
6585
|
+
}
|
|
6586
|
+
return normalizedType;
|
|
6587
|
+
});
|
|
6588
|
+
return typeChanged
|
|
6589
|
+
? types_1.ClassType.specialize(typeToNormalize, typeArgs, typeToNormalize.priv.isTypeArgExplicit)
|
|
6590
|
+
: typeToNormalize;
|
|
6591
|
+
}
|
|
6269
6592
|
function getTypeOfAssertType(node, inferenceContext) {
|
|
6270
6593
|
if (node.d.args.length !== 2 ||
|
|
6271
6594
|
node.d.args[0].d.argCategory !== 0 /* ArgCategory.Simple */ ||
|
|
@@ -6286,11 +6609,23 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
6286
6609
|
// The spec is unclear on whether this is the correct behavior, but it seems to be
|
|
6287
6610
|
// what mypy does -- and what various library authors expect.
|
|
6288
6611
|
const arg0Type = stripTypeGuard(arg0TypeResult.type);
|
|
6289
|
-
|
|
6612
|
+
const typeSameOptions = {
|
|
6290
6613
|
treatAnySameAsUnknown: true,
|
|
6291
6614
|
ignorePseudoGeneric: true,
|
|
6292
6615
|
ignoreConditions: true,
|
|
6293
|
-
}
|
|
6616
|
+
};
|
|
6617
|
+
let typesMatch = (0, types_1.isTypeSame)(assertedType, arg0Type, typeSameOptions);
|
|
6618
|
+
if (!typesMatch) {
|
|
6619
|
+
// Unlike assignType, assert_type requires exact structural identity, so
|
|
6620
|
+
// normalize both types recursively. Keep this equivalence relation aligned
|
|
6621
|
+
// with expandEnumTypeForLiteralComparison, which assignType applies as it recurses.
|
|
6622
|
+
const literalEnumClasses = collectLiteralEnumClasses(assertedType, [], /* recursively */ true);
|
|
6623
|
+
collectLiteralEnumClasses(arg0Type, literalEnumClasses, /* recursively */ true);
|
|
6624
|
+
const normalizedAssertedType = normalizeEnumTypes(assertedType, literalEnumClasses);
|
|
6625
|
+
const normalizedArg0Type = normalizeEnumTypes(arg0Type, literalEnumClasses);
|
|
6626
|
+
typesMatch = (0, types_1.isTypeSame)(normalizedAssertedType, normalizedArg0Type, typeSameOptions);
|
|
6627
|
+
}
|
|
6628
|
+
if (!typesMatch) {
|
|
6294
6629
|
const srcDestTypes = printSrcDestTypes(arg0TypeResult.type, assertedType, { expandTypeAlias: true });
|
|
6295
6630
|
addDiagnostic(diagnosticRules_1.DiagnosticRule.reportAssertTypeFailure, localize_1.LocMessage.assertTypeTypeMismatch().format({
|
|
6296
6631
|
expected: srcDestTypes.destType,
|
|
@@ -6375,7 +6710,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
6375
6710
|
let curNode = node;
|
|
6376
6711
|
let scope;
|
|
6377
6712
|
while (curNode) {
|
|
6378
|
-
scope =
|
|
6713
|
+
scope = getScopeForNode(curNode);
|
|
6379
6714
|
// Stop when we get a valid scope that's not a list comprehension
|
|
6380
6715
|
// scope. That includes lambdas, functions, classes, and modules.
|
|
6381
6716
|
if (scope && scope.type !== 1 /* ScopeType.Comprehension */) {
|
|
@@ -6407,7 +6742,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
6407
6742
|
if (node.d.args.length > 2) {
|
|
6408
6743
|
addDiagnostic(diagnosticRules_1.DiagnosticRule.reportCallIssue, localize_1.LocMessage.superCallArgCount(), node.d.args[2]);
|
|
6409
6744
|
}
|
|
6410
|
-
const enclosingFunction = ParseTreeUtils.getEnclosingFunctionEvaluationScope(node);
|
|
6745
|
+
const enclosingFunction = ParseTreeUtils.getEnclosingFunctionEvaluationScope(node, nodeInfo);
|
|
6411
6746
|
const enclosingClass = enclosingFunction ? ParseTreeUtils.getEnclosingClass(enclosingFunction) : undefined;
|
|
6412
6747
|
const enclosingClassType = enclosingClass ? getTypeOfClass(enclosingClass)?.classType : undefined;
|
|
6413
6748
|
// Determine which class the "super" call is applied to. If
|
|
@@ -6429,7 +6764,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
6429
6764
|
// This results in a runtime exception.
|
|
6430
6765
|
if (enclosingFunction) {
|
|
6431
6766
|
const functionInfo = (0, decorators_1.getFunctionInfoFromDecorators)(evaluatorInterface, enclosingFunction,
|
|
6432
|
-
/* isInClass */ true);
|
|
6767
|
+
/* isInClass */ true, nodeInfo);
|
|
6433
6768
|
if ((functionInfo?.flags & 4 /* FunctionTypeFlags.StaticMethod */) !== 0) {
|
|
6434
6769
|
addDiagnostic(diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.LocMessage.superCallZeroArgFormStaticMethod(), node.d.leftExpr);
|
|
6435
6770
|
}
|
|
@@ -6496,7 +6831,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
6496
6831
|
if (methodType.shared.parameters.length > 0 &&
|
|
6497
6832
|
types_1.FunctionParam.isTypeDeclared(methodType.shared.parameters[0])) {
|
|
6498
6833
|
let paramType = types_1.FunctionType.getParamType(methodType, 0);
|
|
6499
|
-
const liveScopeIds =
|
|
6834
|
+
const liveScopeIds = getTypeVarScopesForNode(node);
|
|
6500
6835
|
paramType = (0, typeUtils_1.makeTypeVarsBound)(paramType, liveScopeIds);
|
|
6501
6836
|
implicitBindToType = makeTopLevelTypeVarsConcrete(paramType);
|
|
6502
6837
|
}
|
|
@@ -6672,13 +7007,18 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
6672
7007
|
// list will grow to include union expansions.
|
|
6673
7008
|
function validateOverloadsWithExpandedTypes(errorNode, expandedArgTypes, argParamMatches, constraints, skipUnknownArgCheck, inferenceContext) {
|
|
6674
7009
|
const returnTypes = [];
|
|
7010
|
+
const specializedInitSelfTypes = [];
|
|
6675
7011
|
let matchedOverloads = [];
|
|
6676
7012
|
let isTypeIncomplete = false;
|
|
6677
|
-
|
|
7013
|
+
const overloadsUsedForCall = [];
|
|
6678
7014
|
let isDefinitiveMatchFound = false;
|
|
7015
|
+
let hasInitSelfMaterializationAmbiguity = false;
|
|
7016
|
+
let hasEffectiveInitSelfType = false;
|
|
6679
7017
|
const speculativeNode = getSpeculativeNodeForCall(errorNode);
|
|
6680
7018
|
for (let expandedTypesIndex = 0; expandedTypesIndex < expandedArgTypes.length; expandedTypesIndex++) {
|
|
7019
|
+
const overloadsUsedStartIndex = overloadsUsedForCall.length;
|
|
6681
7020
|
let matchedOverload;
|
|
7021
|
+
let effectiveInitSelfType;
|
|
6682
7022
|
const argTypeOverride = expandedArgTypes[expandedTypesIndex];
|
|
6683
7023
|
const hasArgTypeOverride = argTypeOverride.some((a) => a !== undefined);
|
|
6684
7024
|
let possibleMatchResults = [];
|
|
@@ -6718,9 +7058,12 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
6718
7058
|
constraints: effectiveConstraints,
|
|
6719
7059
|
returnType: callResult.returnType,
|
|
6720
7060
|
argResults: callResult.argResults ?? [],
|
|
7061
|
+
specializedInitSelfType: callResult.specializedInitSelfType,
|
|
6721
7062
|
};
|
|
6722
7063
|
matchedOverloads.push(matchedOverloadInfo);
|
|
6723
|
-
if (callResult.anyOrUnknownArg ||
|
|
7064
|
+
if (callResult.anyOrUnknownArg ||
|
|
7065
|
+
matchResults.unpackedArgOfUnknownLength ||
|
|
7066
|
+
possibleMatchResults.length > 0) {
|
|
6724
7067
|
possibleMatchResults.push(matchedOverloadInfo);
|
|
6725
7068
|
if (callResult.anyOrUnknownArg) {
|
|
6726
7069
|
if ((0, typeUtils_1.isIncompleteUnknown)(callResult.anyOrUnknownArg)) {
|
|
@@ -6730,6 +7073,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
6730
7073
|
}
|
|
6731
7074
|
else {
|
|
6732
7075
|
returnTypes.push(callResult.returnType);
|
|
7076
|
+
effectiveInitSelfType = getEffectiveInitSelfType(matchedOverloadInfo);
|
|
6733
7077
|
isDefinitiveMatchFound = true;
|
|
6734
7078
|
break;
|
|
6735
7079
|
}
|
|
@@ -6743,20 +7087,53 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
6743
7087
|
if (!isDefinitiveMatchFound && possibleMatchResults.length > 0) {
|
|
6744
7088
|
possibleMatchResults = filterOverloadMatchesForUnpackedArgs(possibleMatchResults);
|
|
6745
7089
|
possibleMatchResults = filterOverloadMatchesForAnyArgs(possibleMatchResults);
|
|
7090
|
+
// Keep diagnostic bookkeeping aligned with the candidates that remain possible.
|
|
7091
|
+
// This applies to both top-level gradual arguments and nested materialization,
|
|
7092
|
+
// so deprecation diagnostics are reported only for retained overloads.
|
|
7093
|
+
overloadsUsedForCall.splice(overloadsUsedStartIndex, overloadsUsedForCall.length - overloadsUsedStartIndex, ...possibleMatchResults.map((result) => result.overload));
|
|
6746
7094
|
// Did the filtering produce a single result? If so, we're done.
|
|
6747
7095
|
if (possibleMatchResults.length === 1) {
|
|
6748
|
-
overloadsUsedForCall = [possibleMatchResults[0].overload];
|
|
6749
7096
|
returnTypes.push(possibleMatchResults[0].returnType);
|
|
7097
|
+
effectiveInitSelfType = getEffectiveInitSelfType(possibleMatchResults[0]);
|
|
6750
7098
|
matchedOverloads = [possibleMatchResults[0]];
|
|
6751
7099
|
}
|
|
6752
7100
|
else {
|
|
7101
|
+
const firstArgParamPairs = getOverloadArgParamPairs(possibleMatchResults[0]);
|
|
7102
|
+
let ambiguousMatchIncludesNestedAny = false;
|
|
7103
|
+
let ambiguousMatchIncludesNestedUnknown = false;
|
|
7104
|
+
let ambiguousMatchIncludesTopLevelAnyOrUnknown = false;
|
|
7105
|
+
firstArgParamPairs.forEach((pair, index) => {
|
|
7106
|
+
const paramTypes = possibleMatchResults.map((match) => {
|
|
7107
|
+
const argParamPairs = getOverloadArgParamPairs(match);
|
|
7108
|
+
return index < argParamPairs.length ? argParamPairs[index].paramType : types_1.UnknownType.create();
|
|
7109
|
+
});
|
|
7110
|
+
if (!(0, typeUtils_1.areTypesSame)(paramTypes, { treatAnySameAsUnknown: true })) {
|
|
7111
|
+
if ((0, types_1.isAnyOrUnknown)(pair.argType)) {
|
|
7112
|
+
ambiguousMatchIncludesTopLevelAnyOrUnknown = true;
|
|
7113
|
+
}
|
|
7114
|
+
else {
|
|
7115
|
+
const anyOrUnknown = getAnyOrUnknownInInvariantPosition(pair.argType);
|
|
7116
|
+
if (anyOrUnknown && (0, types_1.isAny)(anyOrUnknown)) {
|
|
7117
|
+
ambiguousMatchIncludesNestedAny = true;
|
|
7118
|
+
}
|
|
7119
|
+
else if (anyOrUnknown && (0, types_1.isUnknown)(anyOrUnknown)) {
|
|
7120
|
+
ambiguousMatchIncludesNestedUnknown = true;
|
|
7121
|
+
}
|
|
7122
|
+
}
|
|
7123
|
+
}
|
|
7124
|
+
});
|
|
6753
7125
|
// Eliminate any return types that are subsumed by other return types.
|
|
6754
7126
|
let dedupedMatchResults = [];
|
|
6755
7127
|
let dedupedResultsIncludeAny = false;
|
|
7128
|
+
const isInitSelfMaterializationAmbiguity = (ambiguousMatchIncludesNestedAny || ambiguousMatchIncludesNestedUnknown) &&
|
|
7129
|
+
possibleMatchResults.some((result) => !!result.specializedInitSelfType);
|
|
6756
7130
|
possibleMatchResults.forEach((result) => {
|
|
7131
|
+
const resultType = isInitSelfMaterializationAmbiguity
|
|
7132
|
+
? getEffectiveOverloadReturnType(result)
|
|
7133
|
+
: result.returnType;
|
|
6757
7134
|
let isSubtypeSubsumed = false;
|
|
6758
7135
|
for (let dedupedIndex = 0; dedupedIndex < dedupedMatchResults.length; dedupedIndex++) {
|
|
6759
|
-
if (assignType(dedupedMatchResults[dedupedIndex],
|
|
7136
|
+
if (assignType(dedupedMatchResults[dedupedIndex], resultType)) {
|
|
6760
7137
|
const anyOrUnknown = (0, typeUtils_1.containsAnyOrUnknown)(dedupedMatchResults[dedupedIndex],
|
|
6761
7138
|
/* recurse */ false);
|
|
6762
7139
|
if (!anyOrUnknown) {
|
|
@@ -6767,8 +7144,8 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
6767
7144
|
}
|
|
6768
7145
|
break;
|
|
6769
7146
|
}
|
|
6770
|
-
else if (assignType(
|
|
6771
|
-
const anyOrUnknown = (0, typeUtils_1.containsAnyOrUnknown)(
|
|
7147
|
+
else if (assignType(resultType, dedupedMatchResults[dedupedIndex])) {
|
|
7148
|
+
const anyOrUnknown = (0, typeUtils_1.containsAnyOrUnknown)(resultType, /* recurse */ false);
|
|
6772
7149
|
if (!anyOrUnknown) {
|
|
6773
7150
|
dedupedMatchResults[dedupedIndex] = types_1.NeverType.createNever();
|
|
6774
7151
|
}
|
|
@@ -6779,13 +7156,19 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
6779
7156
|
}
|
|
6780
7157
|
}
|
|
6781
7158
|
if (!isSubtypeSubsumed) {
|
|
6782
|
-
dedupedMatchResults.push(
|
|
7159
|
+
dedupedMatchResults.push(resultType);
|
|
6783
7160
|
}
|
|
6784
7161
|
});
|
|
6785
7162
|
dedupedMatchResults = dedupedMatchResults.filter((t) => !(0, types_1.isNever)(t));
|
|
6786
7163
|
const combinedTypes = (0, types_1.combineTypes)(dedupedMatchResults);
|
|
6787
7164
|
let returnType = combinedTypes;
|
|
6788
|
-
if (
|
|
7165
|
+
if (ambiguousMatchIncludesNestedUnknown) {
|
|
7166
|
+
returnType = types_1.UnknownType.createPossibleType(combinedTypes, possibleMatchInvolvesIncompleteUnknown);
|
|
7167
|
+
}
|
|
7168
|
+
else if (ambiguousMatchIncludesNestedAny && !ambiguousMatchIncludesTopLevelAnyOrUnknown) {
|
|
7169
|
+
returnType = types_1.AnyType.create();
|
|
7170
|
+
}
|
|
7171
|
+
else if (dedupedMatchResults.length > 1) {
|
|
6789
7172
|
// If one or more of the deduped types is Any or contains Any,
|
|
6790
7173
|
// we will assume that the person who defined the overload really
|
|
6791
7174
|
// wanted Any rather than Unknown. In cases where the deduped types
|
|
@@ -6798,13 +7181,33 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
6798
7181
|
returnType = types_1.UnknownType.createPossibleType(combinedTypes, possibleMatchInvolvesIncompleteUnknown);
|
|
6799
7182
|
}
|
|
6800
7183
|
}
|
|
6801
|
-
|
|
7184
|
+
if (isInitSelfMaterializationAmbiguity) {
|
|
7185
|
+
// Overloaded __init__ methods normally return None. Preserve that
|
|
7186
|
+
// ordinary return as a placeholder while union-expanded calls are
|
|
7187
|
+
// combined, and carry the effective constructed types separately.
|
|
7188
|
+
// validateInitMethod consumes specializedInitSelfType to reconstruct
|
|
7189
|
+
// the constructor result after call validation is complete.
|
|
7190
|
+
effectiveInitSelfType = returnType;
|
|
7191
|
+
hasInitSelfMaterializationAmbiguity = true;
|
|
7192
|
+
returnTypes.push(possibleMatchResults[0].returnType);
|
|
7193
|
+
}
|
|
7194
|
+
else {
|
|
7195
|
+
returnTypes.push(returnType);
|
|
7196
|
+
}
|
|
6802
7197
|
}
|
|
6803
7198
|
}
|
|
7199
|
+
if (effectiveInitSelfType) {
|
|
7200
|
+
specializedInitSelfTypes.push(effectiveInitSelfType);
|
|
7201
|
+
hasEffectiveInitSelfType = true;
|
|
7202
|
+
}
|
|
6804
7203
|
if (!matchedOverload) {
|
|
6805
7204
|
return { argumentErrors: true, isTypeIncomplete, overloadsUsedForCall };
|
|
6806
7205
|
}
|
|
6807
7206
|
}
|
|
7207
|
+
// Union expansion requires one constructor handoff per expanded argument list.
|
|
7208
|
+
// Materialization ambiguity requires a combined handoff even when there is only
|
|
7209
|
+
// one argument list because multiple overload candidates contribute to its result.
|
|
7210
|
+
const shouldCombineInitSelfTypes = hasInitSelfMaterializationAmbiguity || (expandedArgTypes.length > 1 && hasEffectiveInitSelfType);
|
|
6808
7211
|
// We found a match for all of the expanded argument lists. Copy the
|
|
6809
7212
|
// resulting type var context back into the caller's type var context.
|
|
6810
7213
|
// Use the type var context from the last matched overload because it
|
|
@@ -6814,7 +7217,9 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
6814
7217
|
}
|
|
6815
7218
|
// And run through the first expanded argument list one more time to
|
|
6816
7219
|
// populate the type cache.
|
|
6817
|
-
const finalConstraints =
|
|
7220
|
+
const finalConstraints = shouldCombineInitSelfTypes
|
|
7221
|
+
? matchedOverloads[0].constraints
|
|
7222
|
+
: constraints ?? matchedOverloads[0].constraints;
|
|
6818
7223
|
const finalCallResult = validateArgTypesWithContext(errorNode, matchedOverloads[0].matchResults, finalConstraints, skipUnknownArgCheck, inferenceContext);
|
|
6819
7224
|
if (finalCallResult.isTypeIncomplete) {
|
|
6820
7225
|
isTypeIncomplete = true;
|
|
@@ -6824,7 +7229,9 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
6824
7229
|
anyOrUnknownArg: finalCallResult.anyOrUnknownArg,
|
|
6825
7230
|
returnType: (0, types_1.combineTypes)(returnTypes),
|
|
6826
7231
|
isTypeIncomplete,
|
|
6827
|
-
specializedInitSelfType:
|
|
7232
|
+
specializedInitSelfType: specializedInitSelfTypes.length > 0 && shouldCombineInitSelfTypes
|
|
7233
|
+
? (0, types_1.combineTypes)(specializedInitSelfTypes)
|
|
7234
|
+
: finalCallResult.specializedInitSelfType,
|
|
6828
7235
|
overloadsUsedForCall,
|
|
6829
7236
|
};
|
|
6830
7237
|
}
|
|
@@ -6842,28 +7249,303 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
6842
7249
|
}
|
|
6843
7250
|
return unpackedArgsOverloads;
|
|
6844
7251
|
}
|
|
7252
|
+
// assignType cannot be used for this detection because it accepts Any and Unknown
|
|
7253
|
+
// without exposing whether acceptance depends on a gradual invariant type argument.
|
|
7254
|
+
function getAnyOrUnknownInInvariantPosition(type, recursionCount = 0) {
|
|
7255
|
+
if (recursionCount > types_1.maxTypeRecursionCount) {
|
|
7256
|
+
return undefined;
|
|
7257
|
+
}
|
|
7258
|
+
recursionCount++;
|
|
7259
|
+
let result;
|
|
7260
|
+
const addResult = (newResult) => {
|
|
7261
|
+
if (newResult) {
|
|
7262
|
+
result = result ? (0, typeUtils_1.preserveUnknown)(result, newResult) : newResult;
|
|
7263
|
+
}
|
|
7264
|
+
};
|
|
7265
|
+
if ((0, types_1.isUnion)(type)) {
|
|
7266
|
+
(0, typeUtils_1.doForEachSubtype)(type, (subtype) => {
|
|
7267
|
+
addResult(getAnyOrUnknownInInvariantPosition(subtype, recursionCount));
|
|
7268
|
+
});
|
|
7269
|
+
return result;
|
|
7270
|
+
}
|
|
7271
|
+
if (!(0, types_1.isClass)(type)) {
|
|
7272
|
+
return undefined;
|
|
7273
|
+
}
|
|
7274
|
+
// Tuple entries are covariant, but they can contain an invariant type.
|
|
7275
|
+
if (type.priv.tupleTypeArgs) {
|
|
7276
|
+
type.priv.tupleTypeArgs.forEach((typeArg) => {
|
|
7277
|
+
addResult(getAnyOrUnknownInInvariantPosition(typeArg.type, recursionCount));
|
|
7278
|
+
});
|
|
7279
|
+
return result;
|
|
7280
|
+
}
|
|
7281
|
+
if (!type.priv.typeArgs) {
|
|
7282
|
+
return undefined;
|
|
7283
|
+
}
|
|
7284
|
+
inferVarianceForClass(type);
|
|
7285
|
+
const typeParams = types_1.ClassType.getTypeParams(type);
|
|
7286
|
+
type.priv.typeArgs.forEach((typeArg, index) => {
|
|
7287
|
+
const typeParam = index < typeParams.length ? typeParams[index] : undefined;
|
|
7288
|
+
const variance = typeParam ? types_1.TypeVarType.getVariance(typeParam) : 2 /* Variance.Invariant */;
|
|
7289
|
+
if (variance === 2 /* Variance.Invariant */) {
|
|
7290
|
+
addResult((0, typeUtils_1.containsAnyOrUnknown)(typeArg, /* recurse */ true));
|
|
7291
|
+
}
|
|
7292
|
+
else {
|
|
7293
|
+
addResult(getAnyOrUnknownInInvariantPosition(typeArg, recursionCount));
|
|
7294
|
+
}
|
|
7295
|
+
});
|
|
7296
|
+
return result;
|
|
7297
|
+
}
|
|
7298
|
+
function getEffectiveOverloadReturnType(match) {
|
|
7299
|
+
return getEffectiveInitSelfType(match) ?? match.returnType;
|
|
7300
|
+
}
|
|
7301
|
+
function getEffectiveInitSelfType(match) {
|
|
7302
|
+
if (match.specializedInitSelfType) {
|
|
7303
|
+
return match.specializedInitSelfType;
|
|
7304
|
+
}
|
|
7305
|
+
const boundToType = match.overload.priv.boundToType;
|
|
7306
|
+
if (match.overload.shared.name === '__init__' && boundToType && (0, types_1.isClassInstance)(boundToType)) {
|
|
7307
|
+
return solveAndApplyConstraints(boundToType, match.constraints, {
|
|
7308
|
+
replaceUnsolved: {
|
|
7309
|
+
scopeIds: (0, typeUtils_1.getTypeVarScopeIds)(boundToType),
|
|
7310
|
+
tupleClassType: getTupleClassType(),
|
|
7311
|
+
},
|
|
7312
|
+
});
|
|
7313
|
+
}
|
|
7314
|
+
return undefined;
|
|
7315
|
+
}
|
|
7316
|
+
function getOverloadArgParamPairs(match) {
|
|
7317
|
+
const pairs = [];
|
|
7318
|
+
// argResults and argParams share validation order: supplied arguments in caller
|
|
7319
|
+
// order, followed by synthesized defaults. Preserve that order so the same index
|
|
7320
|
+
// across overloads represents the same supplied argument, even for keyword calls.
|
|
7321
|
+
match.argResults.forEach((argResult, index) => {
|
|
7322
|
+
const argParam = index < match.matchResults.argParams.length ? match.matchResults.argParams[index] : undefined;
|
|
7323
|
+
if (!argParam?.isDefaultArg) {
|
|
7324
|
+
pairs.push({
|
|
7325
|
+
argType: argResult.argType,
|
|
7326
|
+
paramType: argParam?.paramType ?? types_1.UnknownType.create(),
|
|
7327
|
+
});
|
|
7328
|
+
}
|
|
7329
|
+
});
|
|
7330
|
+
if (match.overload.priv.boundToType && match.overload.priv.strippedFirstParamType) {
|
|
7331
|
+
pairs.unshift({
|
|
7332
|
+
argType: match.overload.priv.boundToType,
|
|
7333
|
+
paramType: match.overload.priv.strippedFirstParamType,
|
|
7334
|
+
});
|
|
7335
|
+
}
|
|
7336
|
+
return pairs;
|
|
7337
|
+
}
|
|
7338
|
+
function combineMaterializationCoverage(results) {
|
|
7339
|
+
if (results.some((result) => result === false)) {
|
|
7340
|
+
return false;
|
|
7341
|
+
}
|
|
7342
|
+
return results.some((result) => result === undefined) ? undefined : true;
|
|
7343
|
+
}
|
|
7344
|
+
function areAllMaterializationsEquivalent(destType, srcType, recursionCount = 0) {
|
|
7345
|
+
if (recursionCount > types_1.maxTypeRecursionCount) {
|
|
7346
|
+
return undefined;
|
|
7347
|
+
}
|
|
7348
|
+
recursionCount++;
|
|
7349
|
+
if (!(0, typeUtils_1.containsAnyOrUnknown)(srcType, /* recurse */ true)) {
|
|
7350
|
+
return (0, types_1.isTypeSame)(destType, srcType, { treatAnySameAsUnknown: true });
|
|
7351
|
+
}
|
|
7352
|
+
if ((0, types_1.isAnyOrUnknown)(destType)) {
|
|
7353
|
+
return true;
|
|
7354
|
+
}
|
|
7355
|
+
if ((0, types_1.isTypeSame)(destType, srcType, { treatAnySameAsUnknown: true })) {
|
|
7356
|
+
return true;
|
|
7357
|
+
}
|
|
7358
|
+
if ((0, types_1.isTypeVar)(destType) ||
|
|
7359
|
+
(0, types_1.isUnion)(destType) ||
|
|
7360
|
+
(0, types_1.isFunction)(destType) ||
|
|
7361
|
+
(0, types_1.isOverloaded)(destType) ||
|
|
7362
|
+
((0, types_1.isClass)(destType) && types_1.ClassType.isProtocolClass(destType))) {
|
|
7363
|
+
return undefined;
|
|
7364
|
+
}
|
|
7365
|
+
if ((0, types_1.isAnyOrUnknown)(srcType)) {
|
|
7366
|
+
return false;
|
|
7367
|
+
}
|
|
7368
|
+
if ((0, types_1.isUnion)(srcType) || (0, types_1.isUnion)(destType) || (0, types_1.isFunction)(srcType) || (0, types_1.isFunction)(destType)) {
|
|
7369
|
+
return undefined;
|
|
7370
|
+
}
|
|
7371
|
+
if (!(0, types_1.isClass)(destType) || !(0, types_1.isClass)(srcType)) {
|
|
7372
|
+
return false;
|
|
7373
|
+
}
|
|
7374
|
+
if (!types_1.ClassType.isSameGenericClass(destType, srcType)) {
|
|
7375
|
+
return false;
|
|
7376
|
+
}
|
|
7377
|
+
if (destType.priv.tupleTypeArgs || srcType.priv.tupleTypeArgs) {
|
|
7378
|
+
const destTupleTypeArgs = destType.priv.tupleTypeArgs;
|
|
7379
|
+
const srcTupleTypeArgs = srcType.priv.tupleTypeArgs;
|
|
7380
|
+
if (!destTupleTypeArgs ||
|
|
7381
|
+
!srcTupleTypeArgs ||
|
|
7382
|
+
destTupleTypeArgs.length !== srcTupleTypeArgs.length ||
|
|
7383
|
+
destTupleTypeArgs.some((destTypeArg, index) => destTypeArg.isUnbounded !== srcTupleTypeArgs[index].isUnbounded)) {
|
|
7384
|
+
return false;
|
|
7385
|
+
}
|
|
7386
|
+
return combineMaterializationCoverage(srcTupleTypeArgs.map((srcTypeArg, index) => areAllMaterializationsEquivalent(destTupleTypeArgs[index].type, srcTypeArg.type, recursionCount)));
|
|
7387
|
+
}
|
|
7388
|
+
const destTypeArgs = destType.priv.typeArgs;
|
|
7389
|
+
const srcTypeArgs = srcType.priv.typeArgs;
|
|
7390
|
+
if (!destTypeArgs || !srcTypeArgs || destTypeArgs.length !== srcTypeArgs.length) {
|
|
7391
|
+
return false;
|
|
7392
|
+
}
|
|
7393
|
+
return combineMaterializationCoverage(srcTypeArgs.map((srcTypeArg, index) => areAllMaterializationsEquivalent(destTypeArgs[index], srcTypeArg, recursionCount)));
|
|
7394
|
+
}
|
|
7395
|
+
function areAllMaterializationsAssignable(destType, srcType, recursionCount = 0) {
|
|
7396
|
+
if (recursionCount > types_1.maxTypeRecursionCount) {
|
|
7397
|
+
return undefined;
|
|
7398
|
+
}
|
|
7399
|
+
recursionCount++;
|
|
7400
|
+
if (!(0, typeUtils_1.containsAnyOrUnknown)(srcType, /* recurse */ true)) {
|
|
7401
|
+
return assignType(destType, srcType);
|
|
7402
|
+
}
|
|
7403
|
+
if ((0, types_1.isAnyOrUnknown)(destType)) {
|
|
7404
|
+
return true;
|
|
7405
|
+
}
|
|
7406
|
+
if ((0, types_1.isTypeSame)(destType, srcType, { treatAnySameAsUnknown: true })) {
|
|
7407
|
+
return true;
|
|
7408
|
+
}
|
|
7409
|
+
if ((0, types_1.isTypeVar)(destType) ||
|
|
7410
|
+
(0, types_1.isUnion)(destType) ||
|
|
7411
|
+
(0, types_1.isFunction)(destType) ||
|
|
7412
|
+
(0, types_1.isOverloaded)(destType) ||
|
|
7413
|
+
((0, types_1.isClass)(destType) && types_1.ClassType.isProtocolClass(destType))) {
|
|
7414
|
+
return undefined;
|
|
7415
|
+
}
|
|
7416
|
+
if ((0, types_1.isAnyOrUnknown)(srcType)) {
|
|
7417
|
+
return assignType(destType, getObjectType());
|
|
7418
|
+
}
|
|
7419
|
+
if ((0, types_1.isUnion)(srcType) ||
|
|
7420
|
+
(0, types_1.isUnion)(destType) ||
|
|
7421
|
+
(0, types_1.isFunction)(srcType) ||
|
|
7422
|
+
(0, types_1.isFunction)(destType) ||
|
|
7423
|
+
(0, types_1.isOverloaded)(srcType) ||
|
|
7424
|
+
(0, types_1.isOverloaded)(destType)) {
|
|
7425
|
+
return undefined;
|
|
7426
|
+
}
|
|
7427
|
+
if (!(0, types_1.isClass)(destType) || !(0, types_1.isClass)(srcType)) {
|
|
7428
|
+
return false;
|
|
7429
|
+
}
|
|
7430
|
+
if ((0, typeUtils_1.isTupleClass)(destType) && (0, typeUtils_1.isTupleClass)(srcType)) {
|
|
7431
|
+
const destTupleTypeArgs = destType.priv.tupleTypeArgs;
|
|
7432
|
+
const srcTupleTypeArgs = srcType.priv.tupleTypeArgs;
|
|
7433
|
+
if (!destTupleTypeArgs || !srcTupleTypeArgs) {
|
|
7434
|
+
return undefined;
|
|
7435
|
+
}
|
|
7436
|
+
if (destTupleTypeArgs.length === 1 && destTupleTypeArgs[0].isUnbounded) {
|
|
7437
|
+
return combineMaterializationCoverage(srcTupleTypeArgs.map((srcTypeArg) => areAllMaterializationsAssignable(destTupleTypeArgs[0].type, srcTypeArg.type, recursionCount)));
|
|
7438
|
+
}
|
|
7439
|
+
if (destTupleTypeArgs.length !== srcTupleTypeArgs.length ||
|
|
7440
|
+
destTupleTypeArgs.some((destTypeArg, index) => destTypeArg.isUnbounded !== srcTupleTypeArgs[index].isUnbounded)) {
|
|
7441
|
+
return false;
|
|
7442
|
+
}
|
|
7443
|
+
return combineMaterializationCoverage(srcTupleTypeArgs.map((srcTypeArg, index) => areAllMaterializationsAssignable(destTupleTypeArgs[index].type, srcTypeArg.type, recursionCount)));
|
|
7444
|
+
}
|
|
7445
|
+
let specializedSrcType;
|
|
7446
|
+
if (types_1.ClassType.isSameGenericClass(destType, srcType)) {
|
|
7447
|
+
specializedSrcType = srcType;
|
|
7448
|
+
}
|
|
7449
|
+
else {
|
|
7450
|
+
const instantiableDestType = (0, types_1.isClassInstance)(destType) ? types_1.ClassType.cloneAsInstantiable(destType) : destType;
|
|
7451
|
+
const baseClass = srcType.shared.mro.find((mroClass) => (0, types_1.isClass)(mroClass) && types_1.ClassType.isSameGenericClass(instantiableDestType, mroClass));
|
|
7452
|
+
if (baseClass && (0, types_1.isClass)(baseClass)) {
|
|
7453
|
+
specializedSrcType = (0, typeUtils_1.specializeForBaseClass)(srcType, baseClass);
|
|
7454
|
+
}
|
|
7455
|
+
}
|
|
7456
|
+
if (!specializedSrcType) {
|
|
7457
|
+
return types_1.ClassType.isBuiltIn(destType, 'object') ? true : undefined;
|
|
7458
|
+
}
|
|
7459
|
+
const typeParams = types_1.ClassType.getTypeParams(destType);
|
|
7460
|
+
if (typeParams.length === 0) {
|
|
7461
|
+
return true;
|
|
7462
|
+
}
|
|
7463
|
+
const destTypeArgs = destType.priv.typeArgs;
|
|
7464
|
+
const srcTypeArgs = specializedSrcType.priv.typeArgs;
|
|
7465
|
+
if (!destTypeArgs) {
|
|
7466
|
+
return true;
|
|
7467
|
+
}
|
|
7468
|
+
if (!srcTypeArgs) {
|
|
7469
|
+
return false;
|
|
7470
|
+
}
|
|
7471
|
+
inferVarianceForClass(destType);
|
|
7472
|
+
return combineMaterializationCoverage(srcTypeArgs.map((srcTypeArg, index) => {
|
|
7473
|
+
const destTypeArg = index < destTypeArgs.length ? destTypeArgs[index] : types_1.UnknownType.create();
|
|
7474
|
+
const typeParam = index < typeParams.length ? typeParams[index] : undefined;
|
|
7475
|
+
const variance = typeParam ? types_1.TypeVarType.getVariance(typeParam) : 2 /* Variance.Invariant */;
|
|
7476
|
+
if (variance === 3 /* Variance.Covariant */) {
|
|
7477
|
+
return areAllMaterializationsAssignable(destTypeArg, srcTypeArg, recursionCount);
|
|
7478
|
+
}
|
|
7479
|
+
if (variance === 2 /* Variance.Invariant */) {
|
|
7480
|
+
return areAllMaterializationsEquivalent(destTypeArg, srcTypeArg, recursionCount);
|
|
7481
|
+
}
|
|
7482
|
+
return undefined;
|
|
7483
|
+
}));
|
|
7484
|
+
}
|
|
6845
7485
|
// Determines whether multiple incompatible overloads match
|
|
6846
7486
|
// due to an Any or Unknown argument type.
|
|
6847
7487
|
function filterOverloadMatchesForAnyArgs(matches) {
|
|
6848
7488
|
if (matches.length < 2) {
|
|
6849
7489
|
return matches;
|
|
6850
7490
|
}
|
|
6851
|
-
|
|
6852
|
-
|
|
7491
|
+
let firstArgParamPairs = getOverloadArgParamPairs(matches[0]);
|
|
7492
|
+
const hasInvariantAnyOrUnknownArg = firstArgParamPairs.some((pair) => getAnyOrUnknownInInvariantPosition(pair.argType));
|
|
7493
|
+
// If all of the effective return types match, select the first one.
|
|
7494
|
+
if ((0, typeUtils_1.areTypesSame)(matches.map((match) => hasInvariantAnyOrUnknownArg ? getEffectiveOverloadReturnType(match) : match.returnType), { treatAnySameAsUnknown: true })) {
|
|
6853
7495
|
return [matches[0]];
|
|
6854
7496
|
}
|
|
6855
|
-
|
|
6856
|
-
|
|
6857
|
-
|
|
7497
|
+
// Apply overload step 5 to arguments that contain a gradual type in an
|
|
7498
|
+
// invariant position. An overload that covers all materializations
|
|
7499
|
+
// eliminates only the overloads that follow it.
|
|
7500
|
+
if (hasInvariantAnyOrUnknownArg) {
|
|
7501
|
+
let materializationCheckSupported = true;
|
|
7502
|
+
for (let matchIndex = 0; matchIndex < matches.length; matchIndex++) {
|
|
7503
|
+
const argParamPairs = getOverloadArgParamPairs(matches[matchIndex]);
|
|
7504
|
+
const coverage = argParamPairs.length === firstArgParamPairs.length
|
|
7505
|
+
? combineMaterializationCoverage(argParamPairs.map((pair, index) => {
|
|
7506
|
+
const argType = firstArgParamPairs[index].argType;
|
|
7507
|
+
return areAllMaterializationsAssignable(pair.paramType, argType);
|
|
7508
|
+
}))
|
|
7509
|
+
: false;
|
|
7510
|
+
if (coverage === undefined) {
|
|
7511
|
+
materializationCheckSupported = false;
|
|
7512
|
+
break;
|
|
7513
|
+
}
|
|
7514
|
+
if (coverage) {
|
|
7515
|
+
matches = matches.slice(0, matchIndex + 1);
|
|
7516
|
+
break;
|
|
7517
|
+
}
|
|
7518
|
+
}
|
|
7519
|
+
if (materializationCheckSupported) {
|
|
7520
|
+
if (matches.length < 2) {
|
|
7521
|
+
return matches;
|
|
7522
|
+
}
|
|
7523
|
+
if ((0, typeUtils_1.areTypesSame)(matches.map((match) => getEffectiveOverloadReturnType(match)), { treatAnySameAsUnknown: true })) {
|
|
7524
|
+
return [matches[0]];
|
|
7525
|
+
}
|
|
7526
|
+
firstArgParamPairs = getOverloadArgParamPairs(matches[0]);
|
|
7527
|
+
for (let i = 0; i < firstArgParamPairs.length; i++) {
|
|
7528
|
+
if (getAnyOrUnknownInInvariantPosition(firstArgParamPairs[i].argType)) {
|
|
7529
|
+
const paramTypes = matches.map((match) => {
|
|
7530
|
+
const argParamPairs = getOverloadArgParamPairs(match);
|
|
7531
|
+
return i < argParamPairs.length ? argParamPairs[i].paramType : types_1.UnknownType.create();
|
|
7532
|
+
});
|
|
7533
|
+
if (!(0, typeUtils_1.areTypesSame)(paramTypes, { treatAnySameAsUnknown: true })) {
|
|
7534
|
+
return matches;
|
|
7535
|
+
}
|
|
7536
|
+
}
|
|
7537
|
+
}
|
|
7538
|
+
}
|
|
6858
7539
|
}
|
|
6859
7540
|
let foundAmbiguousAnyArg = false;
|
|
6860
|
-
for (let i = 0; i <
|
|
7541
|
+
for (let i = 0; i < firstArgParamPairs.length; i++) {
|
|
6861
7542
|
// If the arg is Any or Unknown, see if the corresponding
|
|
6862
7543
|
// parameter types differ in any way.
|
|
6863
|
-
if ((0, types_1.isAnyOrUnknown)(
|
|
6864
|
-
const paramTypes = matches.map((match) =>
|
|
6865
|
-
|
|
6866
|
-
: types_1.UnknownType.create()
|
|
7544
|
+
if ((0, types_1.isAnyOrUnknown)(firstArgParamPairs[i].argType)) {
|
|
7545
|
+
const paramTypes = matches.map((match) => {
|
|
7546
|
+
const argParamPairs = getOverloadArgParamPairs(match);
|
|
7547
|
+
return i < argParamPairs.length ? argParamPairs[i].paramType : types_1.UnknownType.create();
|
|
7548
|
+
});
|
|
6867
7549
|
if (!(0, typeUtils_1.areTypesSame)(paramTypes, { treatAnySameAsUnknown: true })) {
|
|
6868
7550
|
foundAmbiguousAnyArg = true;
|
|
6869
7551
|
}
|
|
@@ -6874,7 +7556,8 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
6874
7556
|
// that one of the arguments is an unpacked iterator, and it maps to
|
|
6875
7557
|
// an indeterminate number of parameters, which means that the overload
|
|
6876
7558
|
// selection is ambiguous.
|
|
6877
|
-
if (foundAmbiguousAnyArg ||
|
|
7559
|
+
if (foundAmbiguousAnyArg ||
|
|
7560
|
+
matches.some((match) => getOverloadArgParamPairs(match).length !== firstArgParamPairs.length)) {
|
|
6878
7561
|
return matches;
|
|
6879
7562
|
}
|
|
6880
7563
|
return [matches[0]];
|
|
@@ -7227,7 +7910,8 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
7227
7910
|
if (types_1.FunctionType.isBuiltIn(type, 'namedtuple')) {
|
|
7228
7911
|
addDiagnostic(diagnosticRules_1.DiagnosticRule.reportUntypedNamedTuple, localize_1.LocMessage.namedTupleNoTypes(), errorNode);
|
|
7229
7912
|
const result = {
|
|
7230
|
-
returnType: (0, namedTuples_1.createNamedTupleType)(evaluatorInterface, errorNode, argList,
|
|
7913
|
+
returnType: (0, namedTuples_1.createNamedTupleType)(evaluatorInterface, errorNode, argList,
|
|
7914
|
+
/* includesTypes */ false, nodeInfo),
|
|
7231
7915
|
};
|
|
7232
7916
|
validateArgs(errorNode, argList, { type: type }, constraints, skipUnknownArgCheck, inferenceContext);
|
|
7233
7917
|
return result;
|
|
@@ -7301,18 +7985,20 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
7301
7985
|
return undefined;
|
|
7302
7986
|
}
|
|
7303
7987
|
let isAbstract = false;
|
|
7304
|
-
const lastFunctionInfo = (0, decorators_1.getFunctionInfoFromDecorators)(evaluatorInterface, lastDecl.node,
|
|
7988
|
+
const lastFunctionInfo = (0, decorators_1.getFunctionInfoFromDecorators)(evaluatorInterface, lastDecl.node,
|
|
7989
|
+
/* isInClass */ true, nodeInfo);
|
|
7305
7990
|
if ((lastFunctionInfo.flags & 8 /* FunctionTypeFlags.AbstractMethod */) !== 0) {
|
|
7306
7991
|
isAbstract = true;
|
|
7307
7992
|
}
|
|
7308
|
-
const isStubFile =
|
|
7993
|
+
const isStubFile = nodeInfo.getFileInfo(lastDecl.node).isStubFile;
|
|
7309
7994
|
// In an overloaded method, the first overload can also be marked abstract.
|
|
7310
7995
|
// In stub files, there is no implementation, so this is the only way to mark
|
|
7311
7996
|
// an overloaded method as abstract.
|
|
7312
7997
|
const firstDecl = symbol.getDeclarations()[0];
|
|
7313
7998
|
let firstFunctionInfo;
|
|
7314
7999
|
if (firstDecl !== lastDecl && firstDecl.type === 5 /* DeclarationType.Function */) {
|
|
7315
|
-
firstFunctionInfo = (0, decorators_1.getFunctionInfoFromDecorators)(evaluatorInterface, firstDecl.node,
|
|
8000
|
+
firstFunctionInfo = (0, decorators_1.getFunctionInfoFromDecorators)(evaluatorInterface, firstDecl.node,
|
|
8001
|
+
/* isInClass */ true, nodeInfo);
|
|
7316
8002
|
if ((firstFunctionInfo.flags & 8 /* FunctionTypeFlags.AbstractMethod */) !== 0) {
|
|
7317
8003
|
isAbstract = true;
|
|
7318
8004
|
}
|
|
@@ -7462,7 +8148,8 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
7462
8148
|
}
|
|
7463
8149
|
if (className === 'NamedTuple') {
|
|
7464
8150
|
const result = {
|
|
7465
|
-
returnType: (0, namedTuples_1.createNamedTupleType)(evaluatorInterface, errorNode, argList,
|
|
8151
|
+
returnType: (0, namedTuples_1.createNamedTupleType)(evaluatorInterface, errorNode, argList,
|
|
8152
|
+
/* includesTypes */ true, nodeInfo),
|
|
7466
8153
|
};
|
|
7467
8154
|
const initTypeResult = (0, constructors_1.getBoundInitMethod)(evaluatorInterface, errorNode, types_1.ClassType.cloneAsInstance(expandedCallType),
|
|
7468
8155
|
/* diag */ undefined, 0 /* MemberAccessFlags.Default */);
|
|
@@ -7480,14 +8167,16 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
7480
8167
|
if (expandedCallType.shared.fullName === 'builtins.sentinel' ||
|
|
7481
8168
|
expandedCallType.shared.fullName === 'typing_extensions.sentinel' ||
|
|
7482
8169
|
expandedCallType.shared.fullName === 'typing_extensions.Sentinel') {
|
|
7483
|
-
return { returnType: (0, sentinel_1.createSentinelType)(evaluatorInterface, errorNode, argList) };
|
|
8170
|
+
return { returnType: (0, sentinel_1.createSentinelType)(evaluatorInterface, errorNode, argList, nodeInfo) };
|
|
7484
8171
|
}
|
|
7485
8172
|
if (types_1.ClassType.isSpecialFormClass(expandedCallType)) {
|
|
7486
8173
|
addDiagnostic(diagnosticRules_1.DiagnosticRule.reportCallIssue, localize_1.LocMessage.typeNotIntantiable().format({ type: className }), errorNode);
|
|
7487
8174
|
return { returnType: types_1.UnknownType.create(), argumentErrors: true };
|
|
7488
8175
|
}
|
|
7489
8176
|
if (className === 'TypedDict') {
|
|
7490
|
-
return {
|
|
8177
|
+
return {
|
|
8178
|
+
returnType: (0, typedDicts_1.createTypedDictType)(evaluatorInterface, errorNode, expandedCallType, argList, nodeInfo),
|
|
8179
|
+
};
|
|
7491
8180
|
}
|
|
7492
8181
|
if (className === 'auto' && argList.length === 0) {
|
|
7493
8182
|
return { returnType: (0, enums_1.getEnumAutoValueType)(evaluatorInterface, errorNode) };
|
|
@@ -7498,9 +8187,9 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
7498
8187
|
expandedCallType.shared.effectiveMetaclass &&
|
|
7499
8188
|
(0, types_1.isClass)(expandedCallType.shared.effectiveMetaclass) &&
|
|
7500
8189
|
(0, enums_1.isEnumMetaclass)(expandedCallType.shared.effectiveMetaclass) &&
|
|
7501
|
-
!(0, enums_1.isEnumClassWithMembers)(evaluatorInterface, expandedCallType)) {
|
|
8190
|
+
!(0, enums_1.isEnumClassWithMembers)(evaluatorInterface, expandedCallType, nodeInfo)) {
|
|
7502
8191
|
return {
|
|
7503
|
-
returnType: (0, enums_1.createEnumType)(evaluatorInterface, errorNode, expandedCallType, argList) ??
|
|
8192
|
+
returnType: (0, enums_1.createEnumType)(evaluatorInterface, errorNode, expandedCallType, argList, nodeInfo) ??
|
|
7504
8193
|
(0, typeUtils_1.convertToInstance)(unexpandedCallType),
|
|
7505
8194
|
};
|
|
7506
8195
|
}
|
|
@@ -7574,7 +8263,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
7574
8263
|
newClassName = firstArgType.priv.literalValue;
|
|
7575
8264
|
}
|
|
7576
8265
|
}
|
|
7577
|
-
const newClassType = types_1.ClassType.createInstantiable(newClassName, '', '',
|
|
8266
|
+
const newClassType = types_1.ClassType.createInstantiable(newClassName, '', '', nodeInfo.getFileInfo(errorNode).fileUri, 0 /* ClassTypeFlags.None */, ParseTreeUtils.getTypeSourceId(errorNode), types_1.ClassType.cloneAsInstantiable(returnType), types_1.ClassType.cloneAsInstantiable(returnType));
|
|
7578
8267
|
newClassType.shared.baseClasses.push(getBuiltInType(errorNode, 'object'));
|
|
7579
8268
|
newClassType.shared.effectiveMetaclass = expandedCallType;
|
|
7580
8269
|
newClassType.shared.declaration = returnType.shared.declaration;
|
|
@@ -7618,7 +8307,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
7618
8307
|
}
|
|
7619
8308
|
// Verify that the cast is necessary.
|
|
7620
8309
|
let castToType = getTypeOfArgExpectingType(argList[0], { typeExpression: true }).type;
|
|
7621
|
-
const liveScopeIds =
|
|
8310
|
+
const liveScopeIds = getTypeVarScopesForNode(errorNode);
|
|
7622
8311
|
castToType = (0, typeUtils_1.makeTypeVarsBound)(castToType, liveScopeIds);
|
|
7623
8312
|
let castFromType = getTypeOfArg(argList[1], /* inferenceContext */ undefined).type;
|
|
7624
8313
|
if (castFromType.props?.specialForm) {
|
|
@@ -8595,7 +9284,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
8595
9284
|
return validateArgTypesWithExpectedType(errorNode, matchResults, constraints, skipUnknownArgCheck, expectedType, returnType);
|
|
8596
9285
|
}
|
|
8597
9286
|
function validateArgTypesWithExpectedType(errorNode, matchResults, constraints, skipUnknownArgCheck = false, expectedType, returnType) {
|
|
8598
|
-
const liveTypeVarScopes =
|
|
9287
|
+
const liveTypeVarScopes = getTypeVarScopesForNode(errorNode);
|
|
8599
9288
|
let assignFlags = 2048 /* AssignTypeFlags.PopulateExpectedType */;
|
|
8600
9289
|
if ((0, typeUtils_1.containsLiteralType)(expectedType, /* includeTypeArgs */ true)) {
|
|
8601
9290
|
assignFlags |= 256 /* AssignTypeFlags.RetainLiteralsForTypeVar */;
|
|
@@ -8628,7 +9317,9 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
8628
9317
|
let argumentErrors = false;
|
|
8629
9318
|
let argumentMatchScore = 0;
|
|
8630
9319
|
let specializedInitSelfType;
|
|
8631
|
-
let anyOrUnknownArg
|
|
9320
|
+
let anyOrUnknownArg = type.priv.boundToType
|
|
9321
|
+
? getAnyOrUnknownInInvariantPosition(type.priv.boundToType)
|
|
9322
|
+
: undefined;
|
|
8632
9323
|
const speculativeNode = getSpeculativeNodeForCall(errorNode);
|
|
8633
9324
|
const typeCondition = (0, typeUtils_1.getTypeCondition)(type);
|
|
8634
9325
|
const paramSpec = types_1.FunctionType.getParamSpecFromArgsKwargs(type);
|
|
@@ -8726,10 +9417,11 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
8726
9417
|
if (argResult.condition) {
|
|
8727
9418
|
condition = types_1.TypeCondition.combine(condition, argResult.condition) ?? [];
|
|
8728
9419
|
}
|
|
8729
|
-
|
|
8730
|
-
|
|
8731
|
-
|
|
8732
|
-
|
|
9420
|
+
const argAnyOrUnknown = (0, types_1.isAnyOrUnknown)(argResult.argType)
|
|
9421
|
+
? argResult.argType
|
|
9422
|
+
: getAnyOrUnknownInInvariantPosition(argResult.argType);
|
|
9423
|
+
if (argAnyOrUnknown && !argParam.isDefaultArg) {
|
|
9424
|
+
anyOrUnknownArg = anyOrUnknownArg ? (0, typeUtils_1.preserveUnknown)(argAnyOrUnknown, anyOrUnknownArg) : argAnyOrUnknown;
|
|
8733
9425
|
}
|
|
8734
9426
|
if (paramSpec) {
|
|
8735
9427
|
if (argParam.argument.argCategory === 1 /* ArgCategory.UnpackedList */) {
|
|
@@ -8813,7 +9505,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
8813
9505
|
if ((0, types_1.isUnpackedClass)(specializedReturnType)) {
|
|
8814
9506
|
specializedReturnType = types_1.ClassType.cloneForPacked(specializedReturnType);
|
|
8815
9507
|
}
|
|
8816
|
-
const liveTypeVarScopes =
|
|
9508
|
+
const liveTypeVarScopes = getTypeVarScopesForNode(errorNode);
|
|
8817
9509
|
specializedReturnType = adjustCallableReturnType(errorNode, specializedReturnType, liveTypeVarScopes);
|
|
8818
9510
|
if (specializedInitSelfType) {
|
|
8819
9511
|
specializedInitSelfType = solveAndApplyConstraints(specializedInitSelfType, constraints);
|
|
@@ -8876,7 +9568,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
8876
9568
|
// Create a new scope ID based on the caller's position. This
|
|
8877
9569
|
// will guarantee uniqueness. If another caller uses the same
|
|
8878
9570
|
// call and arguments, the type vars will not conflict.
|
|
8879
|
-
const newScopeId =
|
|
9571
|
+
const newScopeId = getScopeIdForNode(callNode);
|
|
8880
9572
|
const solution = new constraintSolution_1.ConstraintSolution();
|
|
8881
9573
|
const newTypeParams = typeParams.map((typeVar) => {
|
|
8882
9574
|
const newTypeParam = types_1.TypeVarType.cloneForScopeId(typeVar, newScopeId, typeVar.priv.scopeName, 1 /* TypeVarScopeType.Function */);
|
|
@@ -9148,7 +9840,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
9148
9840
|
if (!options?.skipReportError) {
|
|
9149
9841
|
// Mismatching parameter types are common in untyped code; don't bother spending time
|
|
9150
9842
|
// printing types if the diagnostic is disabled.
|
|
9151
|
-
const fileInfo =
|
|
9843
|
+
const fileInfo = nodeInfo.getFileInfo(argParam.errorNode);
|
|
9152
9844
|
if (fileInfo.diagnosticRuleSet.reportArgumentType !== 'none' &&
|
|
9153
9845
|
!canSkipDiagnosticForNode(argParam.errorNode) &&
|
|
9154
9846
|
!isTypeIncomplete) {
|
|
@@ -9200,7 +9892,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
9200
9892
|
}
|
|
9201
9893
|
if (!options.skipUnknownArgCheck) {
|
|
9202
9894
|
const simplifiedType = makeTopLevelTypeVarsConcrete((0, types_1.removeUnbound)(argType));
|
|
9203
|
-
const fileInfo =
|
|
9895
|
+
const fileInfo = nodeInfo.getFileInfo(argParam.errorNode);
|
|
9204
9896
|
function getDiagAddendum() {
|
|
9205
9897
|
const diagAddendum = new diagnostic_1.DiagnosticAddendum();
|
|
9206
9898
|
if (argParam.paramName) {
|
|
@@ -9323,7 +10015,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
9323
10015
|
}).type;
|
|
9324
10016
|
typeVar.shared.defaultType = (0, typeUtils_1.convertToInstance)(argType);
|
|
9325
10017
|
typeVar.shared.isDefaultExplicit = true;
|
|
9326
|
-
const fileInfo =
|
|
10018
|
+
const fileInfo = nodeInfo.getFileInfo(errorNode);
|
|
9327
10019
|
if (!fileInfo.isStubFile &&
|
|
9328
10020
|
pythonVersion_1.PythonVersion.isLessThan(fileInfo.executionEnvironment.pythonVersion, pythonVersion_1.pythonVersion3_13) &&
|
|
9329
10021
|
classType.shared.moduleName !== 'typing_extensions') {
|
|
@@ -9429,7 +10121,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
9429
10121
|
typeVar.shared.isDefaultExplicit = true;
|
|
9430
10122
|
}
|
|
9431
10123
|
}
|
|
9432
|
-
const fileInfo =
|
|
10124
|
+
const fileInfo = nodeInfo.getFileInfo(errorNode);
|
|
9433
10125
|
if (!fileInfo.isStubFile &&
|
|
9434
10126
|
pythonVersion_1.PythonVersion.isLessThan(fileInfo.executionEnvironment.pythonVersion, pythonVersion_1.pythonVersion3_13) &&
|
|
9435
10127
|
classType.shared.moduleName !== 'typing_extensions') {
|
|
@@ -9490,7 +10182,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
9490
10182
|
paramSpec.shared.isDefaultExplicit = true;
|
|
9491
10183
|
}
|
|
9492
10184
|
}
|
|
9493
|
-
const fileInfo =
|
|
10185
|
+
const fileInfo = nodeInfo.getFileInfo(errorNode);
|
|
9494
10186
|
if (!fileInfo.isStubFile &&
|
|
9495
10187
|
pythonVersion_1.PythonVersion.isLessThan(fileInfo.executionEnvironment.pythonVersion, pythonVersion_1.pythonVersion3_13) &&
|
|
9496
10188
|
classType.shared.moduleName !== 'typing_extensions') {
|
|
@@ -9569,7 +10261,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
9569
10261
|
addDiagnostic(diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.LocMessage.typeAliasTypeMustBeAssigned(), errorNode);
|
|
9570
10262
|
return undefined;
|
|
9571
10263
|
}
|
|
9572
|
-
const scope =
|
|
10264
|
+
const scope = getScopeForNode(errorNode);
|
|
9573
10265
|
if (scope) {
|
|
9574
10266
|
if (scope.type !== 3 /* ScopeType.Class */ && scope.type !== 4 /* ScopeType.Module */ && scope.type !== 5 /* ScopeType.Builtin */) {
|
|
9575
10267
|
addDiagnostic(diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.LocMessage.typeAliasTypeBadScope(), errorNode.parent.d.leftExpr);
|
|
@@ -9630,7 +10322,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
9630
10322
|
isTypeParamListValid = false;
|
|
9631
10323
|
}
|
|
9632
10324
|
else {
|
|
9633
|
-
entryType = types_1.TypeVarType.cloneForScopeId(entryType,
|
|
10325
|
+
entryType = types_1.TypeVarType.cloneForScopeId(entryType, getScopeIdForNode(nameNode), nameNode.d.value, 2 /* TypeVarScopeType.TypeAlias */);
|
|
9634
10326
|
}
|
|
9635
10327
|
typeParams.push(entryType);
|
|
9636
10328
|
}
|
|
@@ -9676,7 +10368,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
9676
10368
|
// in the Python specification: The static type checker will treat
|
|
9677
10369
|
// the new type as if it were a subclass of the original type.
|
|
9678
10370
|
function createNewType(errorNode, argList) {
|
|
9679
|
-
const fileInfo =
|
|
10371
|
+
const fileInfo = nodeInfo.getFileInfo(errorNode);
|
|
9680
10372
|
let className = '';
|
|
9681
10373
|
if (argList.length !== 2) {
|
|
9682
10374
|
addDiagnostic(diagnosticRules_1.DiagnosticRule.reportCallIssue, localize_1.LocMessage.newTypeParamCount(), errorNode);
|
|
@@ -9745,7 +10437,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
9745
10437
|
}
|
|
9746
10438
|
// Implements the semantics of the multi-parameter variant of the "type" call.
|
|
9747
10439
|
function createClassFromMetaclass(errorNode, argList, metaclass) {
|
|
9748
|
-
const fileInfo =
|
|
10440
|
+
const fileInfo = nodeInfo.getFileInfo(errorNode);
|
|
9749
10441
|
const arg0Type = getTypeOfArg(argList[0], /* inferenceContext */ undefined).type;
|
|
9750
10442
|
if (!(0, types_1.isClassInstance)(arg0Type) || !types_1.ClassType.isBuiltIn(arg0Type, 'str')) {
|
|
9751
10443
|
return undefined;
|
|
@@ -9993,7 +10685,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
9993
10685
|
return undefined;
|
|
9994
10686
|
}
|
|
9995
10687
|
const dictConstraints = new constraintTracker_1.ConstraintTracker();
|
|
9996
|
-
if (!(0, constraintSolver_1.addConstraintsForExpectedType)(evaluatorInterface, builtInDict, inferenceContext.expectedType, dictConstraints,
|
|
10688
|
+
if (!(0, constraintSolver_1.addConstraintsForExpectedType)(evaluatorInterface, builtInDict, inferenceContext.expectedType, dictConstraints, getTypeVarScopesForNode(node), node.start)) {
|
|
9997
10689
|
return undefined;
|
|
9998
10690
|
}
|
|
9999
10691
|
const specializedDict = solveAndApplyConstraints(types_1.ClassType.cloneAsInstantiable(builtInDict), dictConstraints);
|
|
@@ -10058,7 +10750,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
10058
10750
|
const keyTypes = keyTypeResults.map((t) => (0, typeUtils_1.stripTypeForm)(convertSpecialFormToRuntimeValue(stripLiteralValue(t.type), flags, !hasExpectedType)));
|
|
10059
10751
|
const valueTypes = valueTypeResults.map((t) => (0, typeUtils_1.stripTypeForm)(convertSpecialFormToRuntimeValue(stripLiteralValue(t.type), flags, !hasExpectedType)));
|
|
10060
10752
|
if (keyTypes.length > 0) {
|
|
10061
|
-
if (
|
|
10753
|
+
if (nodeInfo.getFileInfo(node).diagnosticRuleSet.strictDictionaryInference || hasExpectedType) {
|
|
10062
10754
|
keyType = (0, types_1.combineTypes)(keyTypes);
|
|
10063
10755
|
}
|
|
10064
10756
|
else {
|
|
@@ -10074,7 +10766,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
10074
10766
|
// are the same type, we'll assume that all values in this dictionary should
|
|
10075
10767
|
// be the same.
|
|
10076
10768
|
if (valueTypes.length > 0) {
|
|
10077
|
-
if (
|
|
10769
|
+
if (nodeInfo.getFileInfo(node).diagnosticRuleSet.strictDictionaryInference || hasExpectedType) {
|
|
10078
10770
|
valueType = (0, types_1.combineTypes)(valueTypes);
|
|
10079
10771
|
}
|
|
10080
10772
|
else {
|
|
@@ -10134,7 +10826,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
10134
10826
|
let effectiveValueType = expectedTypedDictEntries.knownItems.get(keyType.priv.literalValue)?.valueType ??
|
|
10135
10827
|
expectedTypedDictEntries.extraItems?.valueType;
|
|
10136
10828
|
if (effectiveValueType) {
|
|
10137
|
-
const liveTypeVarScopes =
|
|
10829
|
+
const liveTypeVarScopes = getTypeVarScopesForNode(node);
|
|
10138
10830
|
effectiveValueType = (0, typeUtils_1.transformExpectedType)(effectiveValueType, liveTypeVarScopes, node.start);
|
|
10139
10831
|
}
|
|
10140
10832
|
entryInferenceContext = (0, typeUtils_1.makeInferenceContext)(effectiveValueType);
|
|
@@ -10143,7 +10835,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
10143
10835
|
else {
|
|
10144
10836
|
let effectiveValueType = expectedValueType ?? (forceStrictInference ? types_1.NeverType.createNever() : undefined);
|
|
10145
10837
|
if (effectiveValueType) {
|
|
10146
|
-
const liveTypeVarScopes =
|
|
10838
|
+
const liveTypeVarScopes = getTypeVarScopesForNode(node);
|
|
10147
10839
|
effectiveValueType = (0, typeUtils_1.transformExpectedType)(effectiveValueType, liveTypeVarScopes, node.start);
|
|
10148
10840
|
}
|
|
10149
10841
|
entryInferenceContext = (0, typeUtils_1.makeInferenceContext)(effectiveValueType);
|
|
@@ -10400,7 +11092,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
10400
11092
|
return undefined;
|
|
10401
11093
|
}
|
|
10402
11094
|
const constraints = new constraintTracker_1.ConstraintTracker();
|
|
10403
|
-
if (!(0, constraintSolver_1.addConstraintsForExpectedType)(evaluatorInterface, types_1.ClassType.cloneAsInstance(expectedClassType), inferenceContext.expectedType, constraints,
|
|
11095
|
+
if (!(0, constraintSolver_1.addConstraintsForExpectedType)(evaluatorInterface, types_1.ClassType.cloneAsInstance(expectedClassType), inferenceContext.expectedType, constraints, getTypeVarScopesForNode(node), node.start)) {
|
|
10404
11096
|
return undefined;
|
|
10405
11097
|
}
|
|
10406
11098
|
const specializedListOrSet = solveAndApplyConstraints(expectedClassType, constraints);
|
|
@@ -10442,7 +11134,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
10442
11134
|
entryTypes = entryTypes.map((t) => stripLiteralValue(t));
|
|
10443
11135
|
let inferredEntryType = hasExpectedType ? types_1.AnyType.create() : types_1.UnknownType.create();
|
|
10444
11136
|
if (entryTypes.length > 0) {
|
|
10445
|
-
const fileInfo =
|
|
11137
|
+
const fileInfo = nodeInfo.getFileInfo(node);
|
|
10446
11138
|
// If there was an expected type or we're using strict list inference,
|
|
10447
11139
|
// combine the types into a union.
|
|
10448
11140
|
if ((builtInClassName === 'list' && fileInfo.diagnosticRuleSet.strictListInference) ||
|
|
@@ -10535,7 +11227,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
10535
11227
|
if (functionTypeInfo) {
|
|
10536
11228
|
let returnType = types_1.FunctionType.getEffectiveReturnType(functionTypeInfo.functionType);
|
|
10537
11229
|
if (returnType) {
|
|
10538
|
-
const liveScopeIds =
|
|
11230
|
+
const liveScopeIds = getTypeVarScopesForNode(node);
|
|
10539
11231
|
returnType = (0, typeUtils_1.makeTypeVarsBound)(returnType, liveScopeIds);
|
|
10540
11232
|
expectedYieldType = (0, typeUtils_1.getGeneratorYieldType)(returnType, !!enclosingFunction.d.isAsync);
|
|
10541
11233
|
const generatorTypeArgs = (0, typeUtils_1.getGeneratorTypeArgs)(returnType);
|
|
@@ -10617,13 +11309,13 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
10617
11309
|
let expectedReturnType;
|
|
10618
11310
|
let expectedParamDetails;
|
|
10619
11311
|
if (expectedType) {
|
|
10620
|
-
const liveTypeVarScopes =
|
|
11312
|
+
const liveTypeVarScopes = getTypeVarScopesForNode(node);
|
|
10621
11313
|
expectedType = (0, typeUtils_1.transformExpectedType)(expectedType, liveTypeVarScopes, node.start);
|
|
10622
11314
|
expectedParamDetails = (0, parameterUtils_1.getParamListDetails)(expectedType);
|
|
10623
11315
|
expectedReturnType = getEffectiveReturnType(expectedType);
|
|
10624
11316
|
}
|
|
10625
11317
|
let functionType = types_1.FunctionType.createInstance('', '', '', 131072 /* FunctionTypeFlags.PartiallyEvaluated */);
|
|
10626
|
-
functionType.shared.typeVarScopeId =
|
|
11318
|
+
functionType.shared.typeVarScopeId = getScopeIdForNode(node);
|
|
10627
11319
|
return (0, cancellationUtils_1.invalidateTypeCacheIfCanceled)(() => {
|
|
10628
11320
|
// Pre-cache the incomplete function type in case the evaluation of the
|
|
10629
11321
|
// lambda depends on itself.
|
|
@@ -10985,7 +11677,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
10985
11677
|
let isValidTypeForm = true;
|
|
10986
11678
|
types_1.TypeBase.setSpecialForm(functionType, types_1.ClassType.cloneAsInstance(classType));
|
|
10987
11679
|
functionType.shared.declaredReturnType = types_1.UnknownType.create();
|
|
10988
|
-
functionType.shared.typeVarScopeId =
|
|
11680
|
+
functionType.shared.typeVarScopeId = getScopeIdForNode(errorNode);
|
|
10989
11681
|
if (typeArgs && typeArgs.length > 0) {
|
|
10990
11682
|
functionType.priv.isCallableWithTypeArgs = true;
|
|
10991
11683
|
if (typeArgs[0].typeList) {
|
|
@@ -11100,7 +11792,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
11100
11792
|
// If no type arguments are provided, the resulting type
|
|
11101
11793
|
// depends on whether we're evaluating a type annotation or
|
|
11102
11794
|
// we're in some other context.
|
|
11103
|
-
if ((flags & 256 /* EvalFlags.TypeExpression */) !== 0) {
|
|
11795
|
+
if ((flags & (256 /* EvalFlags.TypeExpression */ | 1073741824 /* EvalFlags.TypeFormArg */)) !== 0) {
|
|
11104
11796
|
addDiagnostic(diagnosticRules_1.DiagnosticRule.reportInvalidTypeForm, localize_1.LocMessage.optionalExtraArgs(), errorNode);
|
|
11105
11797
|
return types_1.UnknownType.create();
|
|
11106
11798
|
}
|
|
@@ -11170,7 +11862,8 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
11170
11862
|
isValidTypeForm = false;
|
|
11171
11863
|
}
|
|
11172
11864
|
}
|
|
11173
|
-
else if (itemExpr.nodeType === 48 /* ParseNodeType.StringList */
|
|
11865
|
+
else if (itemExpr.nodeType === 48 /* ParseNodeType.StringList */ &&
|
|
11866
|
+
itemExpr.d.strings.every((stringNode) => stringNode.nodeType === 49 /* ParseNodeType.String */)) {
|
|
11174
11867
|
const isBytes = (itemExpr.d.strings[0].d.token.flags & 32 /* StringTokenFlags.Bytes */) !== 0;
|
|
11175
11868
|
const value = itemExpr.d.strings.map((s) => s.d.value).join('');
|
|
11176
11869
|
if (isBytes) {
|
|
@@ -11261,9 +11954,9 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
11261
11954
|
}
|
|
11262
11955
|
// Creates a ClassVar type.
|
|
11263
11956
|
function createClassVarType(classType, errorNode, typeArgs, flags) {
|
|
11264
|
-
if (flags & 131072 /* EvalFlags.NoClassVar */) {
|
|
11957
|
+
if (flags & (131072 /* EvalFlags.NoClassVar */ | 1073741824 /* EvalFlags.TypeFormArg */)) {
|
|
11265
11958
|
addDiagnostic(diagnosticRules_1.DiagnosticRule.reportInvalidTypeForm, localize_1.LocMessage.classVarNotAllowed(), errorNode);
|
|
11266
|
-
return types_1.AnyType.create();
|
|
11959
|
+
return (flags & 1073741824 /* EvalFlags.TypeFormArg */) !== 0 ? types_1.UnknownType.create() : types_1.AnyType.create();
|
|
11267
11960
|
}
|
|
11268
11961
|
if (!typeArgs) {
|
|
11269
11962
|
return classType;
|
|
@@ -11285,8 +11978,17 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
11285
11978
|
return type;
|
|
11286
11979
|
}
|
|
11287
11980
|
function createTypeFormType(classType, errorNode, typeArgs) {
|
|
11288
|
-
if (!typeArgs
|
|
11289
|
-
|
|
11981
|
+
if (!typeArgs) {
|
|
11982
|
+
const specializedType = types_1.ClassType.specialize(classType, [types_1.AnyType.create()]);
|
|
11983
|
+
return types_1.TypeBase.cloneWithTypeForm(specializedType, types_1.ClassType.cloneAsInstance(specializedType));
|
|
11984
|
+
}
|
|
11985
|
+
if (typeArgs.length === 0) {
|
|
11986
|
+
addDiagnostic(diagnosticRules_1.DiagnosticRule.reportInvalidTypeForm, localize_1.LocMessage.typeArgsTooFew().format({
|
|
11987
|
+
name: classType.priv.aliasName || classType.shared.name,
|
|
11988
|
+
expected: 1,
|
|
11989
|
+
received: 0,
|
|
11990
|
+
}), errorNode);
|
|
11991
|
+
return types_1.UnknownType.create();
|
|
11290
11992
|
}
|
|
11291
11993
|
if (typeArgs.length > 1) {
|
|
11292
11994
|
addDiagnostic(diagnosticRules_1.DiagnosticRule.reportInvalidTypeForm, localize_1.LocMessage.typeArgsTooMany().format({
|
|
@@ -11309,10 +12011,10 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
11309
12011
|
// depends on whether we're evaluating a type annotation or
|
|
11310
12012
|
// we're in some other context.
|
|
11311
12013
|
if (!typeArgs) {
|
|
11312
|
-
if ((flags & 256 /* EvalFlags.TypeExpression */) !== 0) {
|
|
12014
|
+
if ((flags & (256 /* EvalFlags.TypeExpression */ | 1073741824 /* EvalFlags.TypeFormArg */)) !== 0) {
|
|
11313
12015
|
addDiagnostic(diagnosticRules_1.DiagnosticRule.reportInvalidTypeForm, localize_1.LocMessage.typeGuardArgCount(), errorNode);
|
|
11314
12016
|
}
|
|
11315
|
-
return classType;
|
|
12017
|
+
return (flags & 1073741824 /* EvalFlags.TypeFormArg */) !== 0 ? types_1.UnknownType.create() : classType;
|
|
11316
12018
|
}
|
|
11317
12019
|
else if (typeArgs.length !== 1) {
|
|
11318
12020
|
addDiagnostic(diagnosticRules_1.DiagnosticRule.reportInvalidTypeForm, localize_1.LocMessage.typeGuardArgCount(), errorNode);
|
|
@@ -11341,7 +12043,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
11341
12043
|
}
|
|
11342
12044
|
const enclosingClassTypeResult = enclosingClass ? getTypeOfClass(enclosingClass) : undefined;
|
|
11343
12045
|
if (!enclosingClassTypeResult) {
|
|
11344
|
-
if ((flags & (256 /* EvalFlags.TypeExpression */ | 128 /* EvalFlags.InstantiableType */)) !== 0) {
|
|
12046
|
+
if ((flags & (256 /* EvalFlags.TypeExpression */ | 128 /* EvalFlags.InstantiableType */ | 1073741824 /* EvalFlags.TypeFormArg */)) !== 0) {
|
|
11345
12047
|
addDiagnostic(diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.LocMessage.selfTypeContext(), errorNode);
|
|
11346
12048
|
}
|
|
11347
12049
|
return types_1.UnknownType.create();
|
|
@@ -11354,7 +12056,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
11354
12056
|
const enclosingFunction = ParseTreeUtils.getEnclosingFunction(errorNode);
|
|
11355
12057
|
if (enclosingFunction) {
|
|
11356
12058
|
const functionInfo = (0, decorators_1.getFunctionInfoFromDecorators)(evaluatorInterface, enclosingFunction,
|
|
11357
|
-
/* isInClass */ true);
|
|
12059
|
+
/* isInClass */ true, nodeInfo);
|
|
11358
12060
|
const isInnerFunction = !!ParseTreeUtils.getEnclosingFunction(enclosingFunction);
|
|
11359
12061
|
if (!isInnerFunction) {
|
|
11360
12062
|
// Check for static methods.
|
|
@@ -11393,18 +12095,19 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
11393
12095
|
// If no type arguments are provided, the resulting type
|
|
11394
12096
|
// depends on whether we're evaluating a type annotation or
|
|
11395
12097
|
// we're in some other context.
|
|
11396
|
-
|
|
12098
|
+
const typeExpressionFlags = 256 /* EvalFlags.TypeExpression */ | 1073741824 /* EvalFlags.TypeFormArg */;
|
|
12099
|
+
if (!typeArgs && (flags & typeExpressionFlags) === 0) {
|
|
11397
12100
|
return { type: classType };
|
|
11398
12101
|
}
|
|
11399
12102
|
if (!typeArgs || typeArgs.length !== 1) {
|
|
11400
|
-
if ((flags &
|
|
12103
|
+
if ((flags & typeExpressionFlags) !== 0) {
|
|
11401
12104
|
addDiagnostic(diagnosticRules_1.DiagnosticRule.reportInvalidTypeForm, classType.shared.name === 'ReadOnly'
|
|
11402
12105
|
? localize_1.LocMessage.readOnlyArgCount()
|
|
11403
12106
|
: classType.shared.name === 'Required'
|
|
11404
12107
|
? localize_1.LocMessage.requiredArgCount()
|
|
11405
12108
|
: localize_1.LocMessage.notRequiredArgCount(), errorNode);
|
|
11406
12109
|
}
|
|
11407
|
-
return { type: classType };
|
|
12110
|
+
return { type: (flags & 1073741824 /* EvalFlags.TypeFormArg */) !== 0 ? types_1.UnknownType.create() : classType };
|
|
11408
12111
|
}
|
|
11409
12112
|
const typeArgType = typeArgs[0].type;
|
|
11410
12113
|
// Make sure this is used only in a dataclass.
|
|
@@ -11444,23 +12147,23 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
11444
12147
|
isNotRequired = classType.shared.name === 'NotRequired';
|
|
11445
12148
|
}
|
|
11446
12149
|
if (!isUsageLegal) {
|
|
11447
|
-
if ((flags &
|
|
12150
|
+
if ((flags & typeExpressionFlags) !== 0) {
|
|
11448
12151
|
addDiagnostic(diagnosticRules_1.DiagnosticRule.reportInvalidTypeForm, classType.shared.name === 'ReadOnly'
|
|
11449
12152
|
? localize_1.LocMessage.readOnlyNotInTypedDict()
|
|
11450
12153
|
: classType.shared.name === 'Required'
|
|
11451
12154
|
? localize_1.LocMessage.requiredNotInTypedDict()
|
|
11452
12155
|
: localize_1.LocMessage.notRequiredNotInTypedDict(), errorNode);
|
|
11453
12156
|
}
|
|
11454
|
-
return { type: classType };
|
|
12157
|
+
return { type: (flags & 1073741824 /* EvalFlags.TypeFormArg */) !== 0 ? types_1.UnknownType.create() : classType };
|
|
11455
12158
|
}
|
|
11456
12159
|
return { type: typeArgType, isReadOnly, isRequired, isNotRequired };
|
|
11457
12160
|
}
|
|
11458
12161
|
function createUnpackType(classType, errorNode, typeArgs, flags) {
|
|
11459
12162
|
if (!typeArgs || typeArgs.length !== 1) {
|
|
11460
|
-
if ((flags & 256 /* EvalFlags.TypeExpression */) !== 0) {
|
|
12163
|
+
if ((flags & (256 /* EvalFlags.TypeExpression */ | 1073741824 /* EvalFlags.TypeFormArg */)) !== 0) {
|
|
11461
12164
|
addDiagnostic(diagnosticRules_1.DiagnosticRule.reportInvalidTypeForm, localize_1.LocMessage.unpackArgCount(), errorNode);
|
|
11462
12165
|
}
|
|
11463
|
-
return classType;
|
|
12166
|
+
return (flags & 1073741824 /* EvalFlags.TypeFormArg */) !== 0 ? types_1.UnknownType.create() : classType;
|
|
11464
12167
|
}
|
|
11465
12168
|
const typeArgType = typeArgs[0].type;
|
|
11466
12169
|
if ((flags & 4194304 /* EvalFlags.AllowUnpackedTuple */) !== 0) {
|
|
@@ -11468,7 +12171,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
11468
12171
|
if (unpackedType) {
|
|
11469
12172
|
return unpackedType;
|
|
11470
12173
|
}
|
|
11471
|
-
if ((flags & 256 /* EvalFlags.TypeExpression */) === 0) {
|
|
12174
|
+
if ((flags & (256 /* EvalFlags.TypeExpression */ | 1073741824 /* EvalFlags.TypeFormArg */)) === 0) {
|
|
11472
12175
|
return classType;
|
|
11473
12176
|
}
|
|
11474
12177
|
addDiagnostic(diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.LocMessage.unpackExpectedTypeVarTuple(), errorNode);
|
|
@@ -11484,19 +12187,27 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
11484
12187
|
addDiagnostic(diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.LocMessage.unpackExpectedTypedDict(), errorNode);
|
|
11485
12188
|
return types_1.UnknownType.create();
|
|
11486
12189
|
}
|
|
11487
|
-
if ((flags & 256 /* EvalFlags.TypeExpression */) === 0) {
|
|
12190
|
+
if ((flags & (256 /* EvalFlags.TypeExpression */ | 1073741824 /* EvalFlags.TypeFormArg */)) === 0) {
|
|
11488
12191
|
return classType;
|
|
11489
12192
|
}
|
|
12193
|
+
if ((flags & 1073741824 /* EvalFlags.TypeFormArg */) !== 0) {
|
|
12194
|
+
if ((0, types_1.isUnknown)(typeArgType)) {
|
|
12195
|
+
return typeArgType;
|
|
12196
|
+
}
|
|
12197
|
+
if ((0, types_1.isTypeVar)(typeArgType) && !typeArgType.priv.scopeId) {
|
|
12198
|
+
return types_1.UnknownType.create();
|
|
12199
|
+
}
|
|
12200
|
+
}
|
|
11490
12201
|
addDiagnostic(diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.LocMessage.unpackNotAllowed(), errorNode);
|
|
11491
12202
|
return types_1.UnknownType.create();
|
|
11492
12203
|
}
|
|
11493
12204
|
// Creates a "Final" type.
|
|
11494
12205
|
function createFinalType(classType, errorNode, typeArgs, flags) {
|
|
11495
|
-
if (flags & 16 /* EvalFlags.NoFinal */) {
|
|
11496
|
-
if ((flags & 256 /* EvalFlags.TypeExpression */) !== 0) {
|
|
12206
|
+
if (flags & (16 /* EvalFlags.NoFinal */ | 1073741824 /* EvalFlags.TypeFormArg */)) {
|
|
12207
|
+
if ((flags & (256 /* EvalFlags.TypeExpression */ | 1073741824 /* EvalFlags.TypeFormArg */)) !== 0) {
|
|
11497
12208
|
addDiagnostic(diagnosticRules_1.DiagnosticRule.reportInvalidTypeForm, localize_1.LocMessage.finalContext(), errorNode);
|
|
11498
12209
|
}
|
|
11499
|
-
return classType;
|
|
12210
|
+
return (flags & 1073741824 /* EvalFlags.TypeFormArg */) !== 0 ? types_1.UnknownType.create() : classType;
|
|
11500
12211
|
}
|
|
11501
12212
|
if ((flags & 256 /* EvalFlags.TypeExpression */) === 0 || !typeArgs || typeArgs.length === 0) {
|
|
11502
12213
|
return classType;
|
|
@@ -11508,10 +12219,10 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
11508
12219
|
}
|
|
11509
12220
|
function createConcatenateType(classType, errorNode, typeArgs, flags) {
|
|
11510
12221
|
if ((flags & 134217728 /* EvalFlags.AllowConcatenate */) === 0) {
|
|
11511
|
-
if ((flags & 256 /* EvalFlags.TypeExpression */) !== 0) {
|
|
12222
|
+
if ((flags & (256 /* EvalFlags.TypeExpression */ | 1073741824 /* EvalFlags.TypeFormArg */)) !== 0) {
|
|
11512
12223
|
addDiagnostic(diagnosticRules_1.DiagnosticRule.reportInvalidTypeForm, localize_1.LocMessage.concatenateContext(), errorNode);
|
|
11513
12224
|
}
|
|
11514
|
-
return classType;
|
|
12225
|
+
return (flags & 1073741824 /* EvalFlags.TypeFormArg */) !== 0 ? types_1.UnknownType.create() : classType;
|
|
11515
12226
|
}
|
|
11516
12227
|
if (!typeArgs || typeArgs.length === 0) {
|
|
11517
12228
|
addDiagnostic(diagnosticRules_1.DiagnosticRule.reportInvalidTypeForm, localize_1.LocMessage.concatenateTypeArgsMissing(), errorNode);
|
|
@@ -11699,7 +12410,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
11699
12410
|
}
|
|
11700
12411
|
// Unpacks the index expression for a "Union[X, Y, Z]" type annotation.
|
|
11701
12412
|
function createUnionType(classType, errorNode, typeArgs, flags) {
|
|
11702
|
-
const fileInfo =
|
|
12413
|
+
const fileInfo = nodeInfo.getFileInfo(errorNode);
|
|
11703
12414
|
const types = [];
|
|
11704
12415
|
let allowSingleTypeArg = false;
|
|
11705
12416
|
let isValidTypeForm = true;
|
|
@@ -11707,7 +12418,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
11707
12418
|
// If no type arguments are provided, the resulting type
|
|
11708
12419
|
// depends on whether we're evaluating a type annotation or
|
|
11709
12420
|
// we're in some other context.
|
|
11710
|
-
if ((flags & 256 /* EvalFlags.TypeExpression */) !== 0) {
|
|
12421
|
+
if ((flags & (256 /* EvalFlags.TypeExpression */ | 1073741824 /* EvalFlags.TypeFormArg */)) !== 0) {
|
|
11711
12422
|
addDiagnostic(diagnosticRules_1.DiagnosticRule.reportInvalidTypeForm, localize_1.LocMessage.unionTypeArgCount(), errorNode);
|
|
11712
12423
|
return types_1.NeverType.createNever();
|
|
11713
12424
|
}
|
|
@@ -11741,7 +12452,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
11741
12452
|
// is allowed if it's an unpacked TypeVarTuple or tuple. None is also allowed
|
|
11742
12453
|
// since it is used to define NoReturn in typeshed stubs).
|
|
11743
12454
|
if (types.length === 1 && !allowSingleTypeArg && !(0, typeUtils_1.isNoneInstance)(types[0])) {
|
|
11744
|
-
if ((flags & 256 /* EvalFlags.TypeExpression */) !== 0) {
|
|
12455
|
+
if ((flags & (256 /* EvalFlags.TypeExpression */ | 1073741824 /* EvalFlags.TypeFormArg */)) !== 0) {
|
|
11745
12456
|
addDiagnostic(diagnosticRules_1.DiagnosticRule.reportInvalidTypeArguments, localize_1.LocMessage.unionTypeArgCount(), errorNode);
|
|
11746
12457
|
}
|
|
11747
12458
|
isValidTypeForm = false;
|
|
@@ -11768,10 +12479,14 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
11768
12479
|
// If no type arguments are provided, the resulting type
|
|
11769
12480
|
// depends on whether we're evaluating a type annotation or
|
|
11770
12481
|
// we're in some other context.
|
|
11771
|
-
if ((flags & (256 /* EvalFlags.TypeExpression */ | 262144 /* EvalFlags.NoNakedGeneric */)) !== 0) {
|
|
12482
|
+
if ((flags & (256 /* EvalFlags.TypeExpression */ | 262144 /* EvalFlags.NoNakedGeneric */ | 1073741824 /* EvalFlags.TypeFormArg */)) !== 0) {
|
|
11772
12483
|
addDiagnostic(diagnosticRules_1.DiagnosticRule.reportInvalidTypeForm, localize_1.LocMessage.genericTypeArgMissing(), errorNode);
|
|
11773
12484
|
}
|
|
11774
|
-
return classType;
|
|
12485
|
+
return (flags & 1073741824 /* EvalFlags.TypeFormArg */) !== 0 ? types_1.UnknownType.create() : classType;
|
|
12486
|
+
}
|
|
12487
|
+
if ((flags & 1073741824 /* EvalFlags.TypeFormArg */) !== 0) {
|
|
12488
|
+
addDiagnostic(diagnosticRules_1.DiagnosticRule.reportInvalidTypeForm, localize_1.LocMessage.genericNotAllowed(), errorNode);
|
|
12489
|
+
return types_1.UnknownType.create();
|
|
11775
12490
|
}
|
|
11776
12491
|
const uniqueTypeVars = [];
|
|
11777
12492
|
if (typeArgs) {
|
|
@@ -11878,7 +12593,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
11878
12593
|
return typeAlias;
|
|
11879
12594
|
}
|
|
11880
12595
|
function createSpecialBuiltInClass(node, assignedName, aliasMapEntry) {
|
|
11881
|
-
const fileInfo =
|
|
12596
|
+
const fileInfo = nodeInfo.getFileInfo(node);
|
|
11882
12597
|
let specialClassType = types_1.ClassType.createInstantiable(assignedName, ParseTreeUtils.getClassFullName(node, fileInfo.moduleName, assignedName), fileInfo.moduleName, fileInfo.fileUri, 1 /* ClassTypeFlags.BuiltIn */ | 2 /* ClassTypeFlags.SpecialBuiltIn */,
|
|
11883
12598
|
/* typeSourceId */ 0,
|
|
11884
12599
|
/* declaredMetaclass */ undefined,
|
|
@@ -11893,12 +12608,12 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
11893
12608
|
// specified in the alias map entry.
|
|
11894
12609
|
if (aliasMapEntry.typeParamVariance !== undefined) {
|
|
11895
12610
|
let typeParam = types_1.TypeVarType.createInstance('T');
|
|
11896
|
-
typeParam = types_1.TypeVarType.cloneForScopeId(typeParam,
|
|
12611
|
+
typeParam = types_1.TypeVarType.cloneForScopeId(typeParam, getScopeIdForNode(node), assignedName, 0 /* TypeVarScopeType.Class */);
|
|
11897
12612
|
typeParam.shared.declaredVariance = aliasMapEntry.typeParamVariance;
|
|
11898
12613
|
specialClassType.shared.typeParams.push(typeParam);
|
|
11899
12614
|
}
|
|
11900
|
-
const specialBuiltInClassDeclaration = (
|
|
11901
|
-
(node.parent ?
|
|
12615
|
+
const specialBuiltInClassDeclaration = (nodeInfo.getDeclaration(node) ??
|
|
12616
|
+
(node.parent ? nodeInfo.getDeclaration(node.parent) : undefined));
|
|
11902
12617
|
specialClassType.shared.declaration = specialBuiltInClassDeclaration;
|
|
11903
12618
|
if (fileInfo.isTypingExtensionsStubFile) {
|
|
11904
12619
|
specialClassType.shared.flags |= 4096 /* ClassTypeFlags.TypingExtensionClass */;
|
|
@@ -12069,8 +12784,27 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
12069
12784
|
}
|
|
12070
12785
|
return undefined;
|
|
12071
12786
|
}
|
|
12787
|
+
function cachedAssignmentTargetMayHaveDeclaredType(expression) {
|
|
12788
|
+
switch (expression.nodeType) {
|
|
12789
|
+
case 38 /* ParseNodeType.Name */: {
|
|
12790
|
+
const symbolWithScope = lookUpSymbolRecursive(expression, expression.d.value, /* honorCodeFlow */ true);
|
|
12791
|
+
return (!!symbolWithScope &&
|
|
12792
|
+
(symbolWithScope.symbol.hasTypedDeclarations() || symbolWithScope.scope.type === 3 /* ScopeType.Class */));
|
|
12793
|
+
}
|
|
12794
|
+
case 54 /* ParseNodeType.TypeAnnotation */:
|
|
12795
|
+
case 35 /* ParseNodeType.MemberAccess */:
|
|
12796
|
+
case 27 /* ParseNodeType.Index */:
|
|
12797
|
+
return true;
|
|
12798
|
+
case 52 /* ParseNodeType.Tuple */:
|
|
12799
|
+
return (expression.d.items.length > 0 &&
|
|
12800
|
+
!expression.d.items.some((item) => item.nodeType === 56 /* ParseNodeType.Unpack */) &&
|
|
12801
|
+
expression.d.items.every((item) => cachedAssignmentTargetMayHaveDeclaredType(item)));
|
|
12802
|
+
default:
|
|
12803
|
+
return false;
|
|
12804
|
+
}
|
|
12805
|
+
}
|
|
12072
12806
|
function evaluateTypesForAssignmentStatement(node) {
|
|
12073
|
-
const fileInfo =
|
|
12807
|
+
const fileInfo = nodeInfo.getFileInfo(node);
|
|
12074
12808
|
// If the entire statement has already been evaluated, don't
|
|
12075
12809
|
// re-evaluate it.
|
|
12076
12810
|
if (isTypeCached(node)) {
|
|
@@ -12092,6 +12826,18 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
12092
12826
|
let rightHandType = readTypeCache(node.d.rightExpr, /* flags */ undefined);
|
|
12093
12827
|
let isIncomplete = false;
|
|
12094
12828
|
let expectedTypeDiagAddendum;
|
|
12829
|
+
let declaredType;
|
|
12830
|
+
let declaredTypeResolved = false;
|
|
12831
|
+
// A runtime-first query may have cached the RHS without its assignment
|
|
12832
|
+
// context. Re-evaluate it when the annotation expects a TypeForm so the
|
|
12833
|
+
// ordinary cache cannot suppress contextual validation and conversion.
|
|
12834
|
+
if (rightHandType && cachedAssignmentTargetMayHaveDeclaredType(node.d.leftExpr)) {
|
|
12835
|
+
declaredType = getDeclaredTypeForExpression(node.d.leftExpr, { method: 'set' });
|
|
12836
|
+
declaredTypeResolved = true;
|
|
12837
|
+
if (declaredType && expectedTypeWantsTypeForm(declaredType)) {
|
|
12838
|
+
rightHandType = undefined;
|
|
12839
|
+
}
|
|
12840
|
+
}
|
|
12095
12841
|
if (!rightHandType) {
|
|
12096
12842
|
// Special-case the typing.pyi file, which contains some special
|
|
12097
12843
|
// types that the type analyzer needs to interpret differently.
|
|
@@ -12146,9 +12892,11 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
12146
12892
|
writeTypeCache(node.d.leftExpr.d.valueExpr, { type: typeAliasPlaceholder }, /* flags */ undefined);
|
|
12147
12893
|
}
|
|
12148
12894
|
}
|
|
12149
|
-
|
|
12895
|
+
if (!declaredTypeResolved) {
|
|
12896
|
+
declaredType = getDeclaredTypeForExpression(node.d.leftExpr, { method: 'set' });
|
|
12897
|
+
}
|
|
12150
12898
|
if (declaredType) {
|
|
12151
|
-
const liveTypeVarScopes =
|
|
12899
|
+
const liveTypeVarScopes = getTypeVarScopesForNode(node);
|
|
12152
12900
|
declaredType = (0, typeUtils_1.makeTypeVarsBound)(declaredType, liveTypeVarScopes);
|
|
12153
12901
|
}
|
|
12154
12902
|
const srcTypeResult = getTypeOfExpression(node.d.rightExpr, flags, (0, typeUtils_1.makeInferenceContext)(declaredType));
|
|
@@ -12202,8 +12950,8 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
12202
12950
|
function synthesizeTypeAliasPlaceholder(nameNode, isTypeAliasType = false) {
|
|
12203
12951
|
const placeholder = types_1.TypeVarType.createInstantiable(`__type_alias_${nameNode.d.value}`);
|
|
12204
12952
|
placeholder.shared.isSynthesized = true;
|
|
12205
|
-
const typeVarScopeId =
|
|
12206
|
-
const fileInfo =
|
|
12953
|
+
const typeVarScopeId = getScopeIdForNode(nameNode);
|
|
12954
|
+
const fileInfo = nodeInfo.getFileInfo(nameNode);
|
|
12207
12955
|
placeholder.shared.recursiveAlias = {
|
|
12208
12956
|
name: nameNode.d.value,
|
|
12209
12957
|
fullName: ParseTreeUtils.getClassFullName(nameNode, fileInfo.moduleName, nameNode.d.value),
|
|
@@ -12242,9 +12990,9 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
12242
12990
|
// Write the type to the type cache to support recursive type alias definitions.
|
|
12243
12991
|
writeTypeCache(nameNode, { type: typeAliasTypeVar }, /* flags */ undefined);
|
|
12244
12992
|
// Set a partial type to handle recursive (self-referential) type aliases.
|
|
12245
|
-
const scope =
|
|
12993
|
+
const scope = getScopeForNode(declNode);
|
|
12246
12994
|
const typeAliasSymbol = scope?.lookUpSymbolRecursive(nameNode.d.value);
|
|
12247
|
-
const typeAliasDecl =
|
|
12995
|
+
const typeAliasDecl = nodeInfo.getDeclaration(declNode);
|
|
12248
12996
|
if (typeAliasDecl && typeAliasSymbol) {
|
|
12249
12997
|
setSymbolResolutionPartialType(typeAliasSymbol.symbol, typeAliasDecl, typeAliasTypeVar);
|
|
12250
12998
|
}
|
|
@@ -12312,7 +13060,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
12312
13060
|
const className = `<subclass of ${printType((0, typeUtils_1.convertToInstance)(type1), {
|
|
12313
13061
|
omitTypeArgsIfUnknown: true,
|
|
12314
13062
|
})} and ${printType((0, typeUtils_1.convertToInstance)(type2), { omitTypeArgsIfUnknown: true })}>`;
|
|
12315
|
-
const fileInfo =
|
|
13063
|
+
const fileInfo = nodeInfo.getFileInfo(errorNode);
|
|
12316
13064
|
// The effective metaclass of the intersection is the narrower of the two metaclasses.
|
|
12317
13065
|
let effectiveMetaclass = type1.shared.effectiveMetaclass;
|
|
12318
13066
|
if (type2.shared.effectiveMetaclass) {
|
|
@@ -12347,8 +13095,8 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
12347
13095
|
};
|
|
12348
13096
|
}
|
|
12349
13097
|
// The type wasn't cached, so we need to create a new one.
|
|
12350
|
-
const scope =
|
|
12351
|
-
const fileInfo =
|
|
13098
|
+
const scope = getScopeForNode(node);
|
|
13099
|
+
const fileInfo = nodeInfo.getFileInfo(node);
|
|
12352
13100
|
let classFlags = 0 /* ClassTypeFlags.None */;
|
|
12353
13101
|
if (scope?.type === 5 /* ScopeType.Builtin */ ||
|
|
12354
13102
|
fileInfo.isTypingStubFile ||
|
|
@@ -12372,7 +13120,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
12372
13120
|
const classType = types_1.ClassType.createInstantiable(node.d.name.d.value, ParseTreeUtils.getClassFullName(node, fileInfo.moduleName, node.d.name.d.value), fileInfo.moduleName, fileInfo.fileUri, classFlags, ParseTreeUtils.getTypeSourceId(node),
|
|
12373
13121
|
/* declaredMetaclass */ undefined,
|
|
12374
13122
|
/* effectiveMetaclass */ undefined, ParseTreeUtils.getDocString(node.d.suite.d.statements));
|
|
12375
|
-
classType.shared.typeVarScopeId =
|
|
13123
|
+
classType.shared.typeVarScopeId = getScopeIdForNode(node);
|
|
12376
13124
|
// Is this a special type that supports type promotions according to PEP 484?
|
|
12377
13125
|
if (typePromotions.has(classType.shared.fullName)) {
|
|
12378
13126
|
classType.priv.includePromotions = true;
|
|
@@ -12382,7 +13130,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
12382
13130
|
// to allow these to be resolved.
|
|
12383
13131
|
const classSymbol = scope?.lookUpSymbol(node.d.name.d.value);
|
|
12384
13132
|
let classDecl;
|
|
12385
|
-
const decl =
|
|
13133
|
+
const decl = nodeInfo.getDeclaration(node);
|
|
12386
13134
|
if (decl) {
|
|
12387
13135
|
classDecl = decl;
|
|
12388
13136
|
}
|
|
@@ -12725,7 +13473,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
12725
13473
|
addDiagnostic(diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.LocMessage.methodOrdering(), node.d.name);
|
|
12726
13474
|
}
|
|
12727
13475
|
// The scope for this class becomes the "fields" for the corresponding type.
|
|
12728
|
-
const innerScope =
|
|
13476
|
+
const innerScope = getScopeForNode(node.d.suite);
|
|
12729
13477
|
classType.shared.fields = innerScope?.symbolTable
|
|
12730
13478
|
? new Map(innerScope.symbolTable)
|
|
12731
13479
|
: new Map();
|
|
@@ -12745,6 +13493,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
12745
13493
|
if (slotsNames) {
|
|
12746
13494
|
classType.shared.localSlotsNames = slotsNames;
|
|
12747
13495
|
}
|
|
13496
|
+
classType.shared.hasNonEmptySlots = innerScope?.hasNonEmptySlots;
|
|
12748
13497
|
// Determine if the class should be a "pseudo-generic" class, characterized
|
|
12749
13498
|
// by having an __init__ method with parameters that lack type annotations.
|
|
12750
13499
|
// For such classes, we'll treat them as generic, with the type arguments provided
|
|
@@ -12769,9 +13518,9 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
12769
13518
|
classType.shared.typeParams = genericParams.map((param) => {
|
|
12770
13519
|
const typeVar = types_1.TypeVarType.createInstance(getPseudoGenericTypeVarName(param.d.name.d.value));
|
|
12771
13520
|
typeVar.shared.isSynthesized = true;
|
|
12772
|
-
typeVar.priv.scopeId =
|
|
13521
|
+
typeVar.priv.scopeId = getScopeIdForNode(initDeclNode);
|
|
12773
13522
|
typeVar.shared.boundType = types_1.UnknownType.create();
|
|
12774
|
-
return types_1.TypeVarType.cloneForScopeId(typeVar,
|
|
13523
|
+
return types_1.TypeVarType.cloneForScopeId(typeVar, getScopeIdForNode(node), node.d.name.d.value, 0 /* TypeVarScopeType.Class */);
|
|
12775
13524
|
});
|
|
12776
13525
|
}
|
|
12777
13526
|
}
|
|
@@ -12814,6 +13563,23 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
12814
13563
|
}
|
|
12815
13564
|
}
|
|
12816
13565
|
const effectiveMetaclass = computeEffectiveMetaclass(classType, node.d.name);
|
|
13566
|
+
const enumMemberSetMayBeDynamicallyModified = types_1.ClassType.isEnumClass(classType) &&
|
|
13567
|
+
(nodeInfo.getScope(node)?.hasPotentiallyDynamicSymbolTable ||
|
|
13568
|
+
classType.shared.mro.some((mroClass) => (0, types_1.isClass)(mroClass) && types_1.ClassType.isEnumMemberSetMayBeDynamicallyModified(mroClass)));
|
|
13569
|
+
if (enumMemberSetMayBeDynamicallyModified) {
|
|
13570
|
+
classType.shared.flags |= 67108864 /* ClassTypeFlags.EnumMemberSetMayBeDynamicallyModified */;
|
|
13571
|
+
}
|
|
13572
|
+
if (types_1.ClassType.isEnumClass(classType) &&
|
|
13573
|
+
(node.d.decorators.length > 0 ||
|
|
13574
|
+
enumMemberSetMayBeDynamicallyModified ||
|
|
13575
|
+
!(0, types_1.isInstantiableClass)(effectiveMetaclass) ||
|
|
13576
|
+
!types_1.ClassType.isBuiltIn(effectiveMetaclass, ['EnumMeta', 'EnumType']) ||
|
|
13577
|
+
classType.shared.mro.some((mroClass) => (0, types_1.isClass)(mroClass) &&
|
|
13578
|
+
(types_1.ClassType.isEnumMemberSetMayBeIncomplete(mroClass) ||
|
|
13579
|
+
(!types_1.ClassType.isBuiltIn(mroClass, 'Enum') &&
|
|
13580
|
+
types_1.ClassType.getSymbolTable(mroClass).has('_missing_')))))) {
|
|
13581
|
+
classType.shared.flags |= 33554432 /* ClassTypeFlags.EnumMemberSetMayBeIncomplete */;
|
|
13582
|
+
}
|
|
12817
13583
|
// Clear the "partially constructed" flag.
|
|
12818
13584
|
classType.shared.flags &= ~8192 /* ClassTypeFlags.PartiallyEvaluated */;
|
|
12819
13585
|
// Now determine the decorated type of the class.
|
|
@@ -12821,7 +13587,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
12821
13587
|
let foundUnknown = false;
|
|
12822
13588
|
for (let i = node.d.decorators.length - 1; i >= 0; i--) {
|
|
12823
13589
|
const decorator = node.d.decorators[i];
|
|
12824
|
-
const newDecoratedType = useSignatureTracker(node.parent ?? node, () => (0, decorators_1.applyClassDecorator)(evaluatorInterface, decoratedType, classType, decorator));
|
|
13590
|
+
const newDecoratedType = useSignatureTracker(node.parent ?? node, () => (0, decorators_1.applyClassDecorator)(evaluatorInterface, decoratedType, classType, decorator, nodeInfo));
|
|
12825
13591
|
const unknownOrAny = (0, typeUtils_1.containsAnyOrUnknown)(newDecoratedType, /* recurse */ false);
|
|
12826
13592
|
if (unknownOrAny && (0, types_1.isUnknown)(unknownOrAny)) {
|
|
12827
13593
|
// Report this error only on the first unknown type.
|
|
@@ -12852,7 +13618,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
12852
13618
|
}
|
|
12853
13619
|
}
|
|
12854
13620
|
if (dataClassBehaviors) {
|
|
12855
|
-
(0, dataClasses_1.applyDataClassClassBehaviorOverrides)(evaluatorInterface, node.d.name, classType, initSubclassArgs, dataClassBehaviors);
|
|
13621
|
+
(0, dataClasses_1.applyDataClassClassBehaviorOverrides)(evaluatorInterface, node.d.name, classType, initSubclassArgs, dataClassBehaviors, nodeInfo);
|
|
12856
13622
|
}
|
|
12857
13623
|
// Run any deferred class completions that depend on this class.
|
|
12858
13624
|
runDeferredClassCompletions(classType);
|
|
@@ -12876,7 +13642,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
12876
13642
|
if (foundInvalidBaseClass) {
|
|
12877
13643
|
addDiagnostic(diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.LocMessage.typedDictBaseClass() + diag.getString(), node.d.name);
|
|
12878
13644
|
}
|
|
12879
|
-
(0, typedDicts_1.synthesizeTypedDictClassMethods)(evaluatorInterface, node, classType);
|
|
13645
|
+
(0, typedDicts_1.synthesizeTypedDictClassMethods)(evaluatorInterface, node, classType, nodeInfo);
|
|
12880
13646
|
}
|
|
12881
13647
|
// Synthesize dataclass methods.
|
|
12882
13648
|
if (types_1.ClassType.isDataClass(classType) || isNamedTupleSubclass) {
|
|
@@ -12897,7 +13663,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
12897
13663
|
if (hashSymbol && hashSymbol.isClassMember() && !hashSymbol.getSynthesizedType()) {
|
|
12898
13664
|
skipSynthesizeHash = true;
|
|
12899
13665
|
}
|
|
12900
|
-
const synthesizeMethods = () => (0, dataClasses_1.synthesizeDataClassMethods)(evaluatorInterface, node, classType, isNamedTupleSubclass, skipSynthesizedInit, hasExistingInitMethod, skipSynthesizeHash);
|
|
13666
|
+
const synthesizeMethods = () => (0, dataClasses_1.synthesizeDataClassMethods)(evaluatorInterface, node, classType, isNamedTupleSubclass, skipSynthesizedInit, hasExistingInitMethod, skipSynthesizeHash, nodeInfo);
|
|
12901
13667
|
// If this is a NamedTuple subclass, immediately synthesize dataclass methods
|
|
12902
13668
|
// because we also need to update the MRO classes in this case. For regular
|
|
12903
13669
|
// dataclasses, we'll defer the method synthesis to avoid circular dependencies.
|
|
@@ -12905,6 +13671,9 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
12905
13671
|
synthesizeMethods();
|
|
12906
13672
|
}
|
|
12907
13673
|
else {
|
|
13674
|
+
if (types_1.ClassType.isDataClassGenerateSlots(classType)) {
|
|
13675
|
+
classType.shared.synthesizeDataClassSlotsDeferred = () => (0, dataClasses_1.synthesizeDataClassSlots)(evaluatorInterface, classType);
|
|
13676
|
+
}
|
|
12908
13677
|
classType.shared.synthesizeMethodsDeferred = () => {
|
|
12909
13678
|
delete classType.shared.synthesizeMethodsDeferred;
|
|
12910
13679
|
synthesizeMethods();
|
|
@@ -13058,7 +13827,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
13058
13827
|
}
|
|
13059
13828
|
function evaluateTypeParamList(node) {
|
|
13060
13829
|
const paramTypes = [];
|
|
13061
|
-
const typeParamScope =
|
|
13830
|
+
const typeParamScope = nodeInfo.getScope(node);
|
|
13062
13831
|
node.d.params.forEach((param) => {
|
|
13063
13832
|
const paramSymbol = typeParamScope?.symbolTable.get(param.d.name.d.value);
|
|
13064
13833
|
if (!paramSymbol) {
|
|
@@ -13344,7 +14113,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
13344
14113
|
const decorator = node.d.decorators[i];
|
|
13345
14114
|
const newDecoratedType = useSignatureTracker(node.parent ?? node, () => {
|
|
13346
14115
|
(0, debug_1.assert)(decoratedType !== undefined);
|
|
13347
|
-
return (0, decorators_1.applyFunctionDecorator)(evaluatorInterface, decoratedType, functionType, decorator, node);
|
|
14116
|
+
return (0, decorators_1.applyFunctionDecorator)(evaluatorInterface, decoratedType, functionType, decorator, node, nodeInfo);
|
|
13348
14117
|
});
|
|
13349
14118
|
const unknownOrAny = (0, typeUtils_1.containsAnyOrUnknown)(newDecoratedType, /* recurse */ false);
|
|
13350
14119
|
if (unknownOrAny && (0, types_1.isUnknown)(unknownOrAny)) {
|
|
@@ -13369,7 +14138,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
13369
14138
|
});
|
|
13370
14139
|
}
|
|
13371
14140
|
}
|
|
13372
|
-
decoratedType = (0, decorators_1.addOverloadsToFunctionType)(evaluatorInterface, node, decoratedType);
|
|
14141
|
+
decoratedType = (0, decorators_1.addOverloadsToFunctionType)(evaluatorInterface, node, decoratedType, nodeInfo);
|
|
13373
14142
|
writeTypeCache(node, { type: decoratedType }, 0 /* EvalFlags.None */);
|
|
13374
14143
|
// Now that the decorator has been applied, we can clear the
|
|
13375
14144
|
// "partially evaluated" flag.
|
|
@@ -13379,14 +14148,14 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
13379
14148
|
// Evaluates the type of a "def" statement without applying an async
|
|
13380
14149
|
// modifier or any decorators.
|
|
13381
14150
|
function getTypeOfFunctionPredecorated(node) {
|
|
13382
|
-
const fileInfo =
|
|
14151
|
+
const fileInfo = nodeInfo.getFileInfo(node);
|
|
13383
14152
|
// Is this type already cached?
|
|
13384
14153
|
const cachedFunctionType = readTypeCache(node.d.name, 0 /* EvalFlags.None */);
|
|
13385
14154
|
if (cachedFunctionType && (0, types_1.isFunction)(cachedFunctionType)) {
|
|
13386
14155
|
return cachedFunctionType;
|
|
13387
14156
|
}
|
|
13388
14157
|
let functionDecl;
|
|
13389
|
-
const decl =
|
|
14158
|
+
const decl = nodeInfo.getDeclaration(node);
|
|
13390
14159
|
if (decl) {
|
|
13391
14160
|
functionDecl = decl;
|
|
13392
14161
|
}
|
|
@@ -13397,7 +14166,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
13397
14166
|
if (containingClassNode) {
|
|
13398
14167
|
containingClassType = getTypeOfClass(containingClassNode)?.classType;
|
|
13399
14168
|
}
|
|
13400
|
-
const functionInfo = (0, decorators_1.getFunctionInfoFromDecorators)(evaluatorInterface, node, !!containingClassNode);
|
|
14169
|
+
const functionInfo = (0, decorators_1.getFunctionInfoFromDecorators)(evaluatorInterface, node, !!containingClassNode, nodeInfo);
|
|
13401
14170
|
let functionFlags = functionInfo.flags;
|
|
13402
14171
|
if (functionDecl?.isGenerator) {
|
|
13403
14172
|
functionFlags |= 16 /* FunctionTypeFlags.Generator */;
|
|
@@ -13412,12 +14181,12 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
13412
14181
|
functionFlags |= 512 /* FunctionTypeFlags.Async */;
|
|
13413
14182
|
}
|
|
13414
14183
|
const functionType = types_1.FunctionType.createInstance(node.d.name.d.value, getFunctionFullName(node, fileInfo.moduleName, node.d.name.d.value), fileInfo.moduleName, functionFlags | 131072 /* FunctionTypeFlags.PartiallyEvaluated */, ParseTreeUtils.getDocString(node.d.suite.d.statements));
|
|
13415
|
-
functionType.shared.typeVarScopeId =
|
|
14184
|
+
functionType.shared.typeVarScopeId = getScopeIdForNode(node);
|
|
13416
14185
|
functionType.shared.deprecatedMessage = functionInfo.deprecationMessage;
|
|
13417
14186
|
functionType.shared.methodClass = containingClassType;
|
|
13418
14187
|
if (node.d.name.d.value === '__init__' || node.d.name.d.value === '__new__') {
|
|
13419
14188
|
if (containingClassNode) {
|
|
13420
|
-
functionType.priv.constructorTypeVarScopeId =
|
|
14189
|
+
functionType.priv.constructorTypeVarScopeId = getScopeIdForNode(containingClassNode);
|
|
13421
14190
|
}
|
|
13422
14191
|
}
|
|
13423
14192
|
if (fileInfo.isBuiltInStubFile || fileInfo.isTypingStubFile || fileInfo.isTypingExtensionsStubFile) {
|
|
@@ -13426,7 +14195,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
13426
14195
|
}
|
|
13427
14196
|
functionType.shared.declaration = functionDecl;
|
|
13428
14197
|
// Allow recursion by caching and registering the partially-constructed function type.
|
|
13429
|
-
const scope =
|
|
14198
|
+
const scope = getScopeForNode(node);
|
|
13430
14199
|
const functionSymbol = scope?.lookUpSymbolRecursive(node.d.name.d.value);
|
|
13431
14200
|
if (functionDecl && functionSymbol) {
|
|
13432
14201
|
setSymbolResolutionPartialType(functionSymbol.symbol, functionDecl, functionType);
|
|
@@ -13625,7 +14394,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
13625
14394
|
types_1.FunctionType.addPositionOnlyParamSeparator(functionType);
|
|
13626
14395
|
}
|
|
13627
14396
|
// Update the types for the nodes associated with the parameters.
|
|
13628
|
-
const scopeIds =
|
|
14397
|
+
const scopeIds = getTypeVarScopesForNode(node);
|
|
13629
14398
|
paramTypes.forEach((paramType, index) => {
|
|
13630
14399
|
const paramNameNode = node.d.params[index].d.name;
|
|
13631
14400
|
if (paramNameNode) {
|
|
@@ -13709,7 +14478,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
13709
14478
|
const symbolWithScope = lookUpSymbolRecursive(param.d.name, param.d.name.d.value,
|
|
13710
14479
|
/* honorCodeFlow */ false);
|
|
13711
14480
|
if (symbolWithScope) {
|
|
13712
|
-
setSymbolAccessed(
|
|
14481
|
+
setSymbolAccessed(nodeInfo.getFileInfo(param), symbolWithScope.symbol, param.d.name);
|
|
13713
14482
|
}
|
|
13714
14483
|
}
|
|
13715
14484
|
}
|
|
@@ -13721,7 +14490,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
13721
14490
|
if (param.d.defaultValue?.nodeType === 14 /* ParseNodeType.Constant */ &&
|
|
13722
14491
|
param.d.defaultValue.d.constType === 27 /* KeywordType.None */ &&
|
|
13723
14492
|
!(0, typeUtils_1.isOptionalType)(type) &&
|
|
13724
|
-
!
|
|
14493
|
+
!nodeInfo.getFileInfo(param).diagnosticRuleSet.strictParameterNoneValue) {
|
|
13725
14494
|
return (0, types_1.combineTypes)([type, getNoneType()]);
|
|
13726
14495
|
}
|
|
13727
14496
|
return type;
|
|
@@ -13759,7 +14528,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
13759
14528
|
if ((0, typeUtils_1.requiresSpecialization)(inferredParamType) && (0, types_1.isClass)(baseClassMemberInfo.classType)) {
|
|
13760
14529
|
const scopeIds = (0, typeUtils_1.getTypeVarScopeIds)(baseClassMemberInfo.classType);
|
|
13761
14530
|
const solution = (0, typeUtils_1.buildSolutionFromSpecializedClass)(baseClassMemberInfo.classType);
|
|
13762
|
-
scopeIds.push(
|
|
14531
|
+
scopeIds.push(getScopeIdForNode(baseClassMethodNode));
|
|
13763
14532
|
// Replace any unsolved TypeVars with Unknown (including all function-scoped TypeVars).
|
|
13764
14533
|
inferredParamType = (0, typeUtils_1.applySolvedTypeVars)(inferredParamType, solution, {
|
|
13765
14534
|
replaceUnsolved: {
|
|
@@ -13768,7 +14537,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
13768
14537
|
},
|
|
13769
14538
|
});
|
|
13770
14539
|
}
|
|
13771
|
-
const fileInfo =
|
|
14540
|
+
const fileInfo = nodeInfo.getFileInfo(functionNode);
|
|
13772
14541
|
if (fileInfo.isInPyTypedPackage && !fileInfo.isStubFile) {
|
|
13773
14542
|
inferredParamType = types_1.TypeBase.cloneForAmbiguousType(inferredParamType);
|
|
13774
14543
|
}
|
|
@@ -13820,7 +14589,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
13820
14589
|
}
|
|
13821
14590
|
}
|
|
13822
14591
|
if (inferredParamType) {
|
|
13823
|
-
const fileInfo =
|
|
14592
|
+
const fileInfo = nodeInfo.getFileInfo(paramValueExpr);
|
|
13824
14593
|
if (fileInfo.isInPyTypedPackage && !fileInfo.isStubFile) {
|
|
13825
14594
|
inferredParamType = types_1.TypeBase.cloneForAmbiguousType(inferredParamType);
|
|
13826
14595
|
}
|
|
@@ -13951,14 +14720,14 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
13951
14720
|
functionRecursionMap.set(node.id, recursionEntry);
|
|
13952
14721
|
try {
|
|
13953
14722
|
let functionDecl;
|
|
13954
|
-
const decl =
|
|
14723
|
+
const decl = nodeInfo.getDeclaration(node);
|
|
13955
14724
|
if (decl) {
|
|
13956
14725
|
functionDecl = decl;
|
|
13957
14726
|
}
|
|
13958
14727
|
const functionNeverReturns = !isAfterNodeReachable(node);
|
|
13959
14728
|
const implicitlyReturnsNone = isAfterNodeReachable(node.d.suite);
|
|
13960
14729
|
// Infer the return type based on all of the return statements in the function's body.
|
|
13961
|
-
if (
|
|
14730
|
+
if (nodeInfo.getFileInfo(node).isStubFile) {
|
|
13962
14731
|
// If a return type annotation is missing in a stub file, assume
|
|
13963
14732
|
// it's an "unknown" type. In normal source files, we can infer the
|
|
13964
14733
|
// type from the implementation.
|
|
@@ -14103,7 +14872,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
14103
14872
|
// cases, we can get very deep stacks when inferring return types
|
|
14104
14873
|
// within untyped code.
|
|
14105
14874
|
if (err?.message === 'Maximum call stack size exceeded') {
|
|
14106
|
-
const fileInfo =
|
|
14875
|
+
const fileInfo = nodeInfo.getFileInfo(node);
|
|
14107
14876
|
console.error(`Overflowed stack when inferring return type for function: ${node.d.name.d.value} in file ${fileInfo.fileUri.toUserVisibleString()}`);
|
|
14108
14877
|
return;
|
|
14109
14878
|
}
|
|
@@ -14334,7 +15103,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
14334
15103
|
return;
|
|
14335
15104
|
}
|
|
14336
15105
|
const aliasNode = node.d.alias || node.d.name;
|
|
14337
|
-
const fileInfo =
|
|
15106
|
+
const fileInfo = nodeInfo.getFileInfo(node);
|
|
14338
15107
|
// If this is a redundant form of an import, assume it is an intentional
|
|
14339
15108
|
// export and mark the symbol as accessed.
|
|
14340
15109
|
if (node.d.alias?.d.value === node.d.name.d.value) {
|
|
@@ -14356,7 +15125,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
14356
15125
|
const parentNode = node.parent;
|
|
14357
15126
|
(0, debug_1.assert)(parentNode && parentNode.nodeType === 25 /* ParseNodeType.ImportFrom */);
|
|
14358
15127
|
(0, debug_1.assert)(!parentNode.d.isWildcardImport);
|
|
14359
|
-
const importInfo =
|
|
15128
|
+
const importInfo = nodeInfo.getImportInfo(parentNode.d.module);
|
|
14360
15129
|
if (importInfo && importInfo.isImportFound && !importInfo.isNativeLib) {
|
|
14361
15130
|
const resolvedPath = importInfo.resolvedUris[importInfo.resolvedUris.length - 1];
|
|
14362
15131
|
const importLookupInfo = importLookup(resolvedPath);
|
|
@@ -14404,7 +15173,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
14404
15173
|
for (const caseStatement of node.d.cases) {
|
|
14405
15174
|
if (!caseStatement.d.guardExpr) {
|
|
14406
15175
|
subjectType = (0, patternMatching_1.narrowTypeBasedOnPattern)(evaluatorInterface, subjectType, caseStatement.d.pattern,
|
|
14407
|
-
/* isPositiveTest */ false);
|
|
15176
|
+
/* isPositiveTest */ false, nodeInfo);
|
|
14408
15177
|
}
|
|
14409
15178
|
}
|
|
14410
15179
|
writeTypeCache(node, { type: subjectType, isIncomplete: !!subjectTypeResult.isIncomplete }, 0 /* EvalFlags.None */);
|
|
@@ -14417,7 +15186,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
14417
15186
|
(0, debug_1.fail)('Expected parent of case statement to be match statement');
|
|
14418
15187
|
return;
|
|
14419
15188
|
}
|
|
14420
|
-
const fileInfo =
|
|
15189
|
+
const fileInfo = nodeInfo.getFileInfo(node);
|
|
14421
15190
|
const subjectTypeResult = getTypeOfExpression(node.parent.d.expr);
|
|
14422
15191
|
let subjectType = subjectTypeResult.type;
|
|
14423
15192
|
// Apply negative narrowing for each of the cases prior to the current one
|
|
@@ -14426,17 +15195,17 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
14426
15195
|
if (caseStatement === node) {
|
|
14427
15196
|
if (fileInfo.diagnosticRuleSet.reportUnnecessaryComparison !== 'none') {
|
|
14428
15197
|
if (!subjectTypeResult.isIncomplete) {
|
|
14429
|
-
(0, patternMatching_1.checkForUnusedPattern)(evaluatorInterface, node.d.pattern, subjectType);
|
|
15198
|
+
(0, patternMatching_1.checkForUnusedPattern)(evaluatorInterface, node.d.pattern, subjectType, nodeInfo);
|
|
14430
15199
|
}
|
|
14431
15200
|
}
|
|
14432
15201
|
break;
|
|
14433
15202
|
}
|
|
14434
15203
|
if (!caseStatement.d.guardExpr) {
|
|
14435
15204
|
subjectType = (0, patternMatching_1.narrowTypeBasedOnPattern)(evaluatorInterface, subjectType, caseStatement.d.pattern,
|
|
14436
|
-
/* isPositiveTest */ false);
|
|
15205
|
+
/* isPositiveTest */ false, nodeInfo);
|
|
14437
15206
|
}
|
|
14438
15207
|
}
|
|
14439
|
-
const narrowedSubjectType = (0, patternMatching_1.assignTypeToPatternTargets)(evaluatorInterface, subjectType, !!subjectTypeResult.isIncomplete, node.d.pattern);
|
|
15208
|
+
const narrowedSubjectType = (0, patternMatching_1.assignTypeToPatternTargets)(evaluatorInterface, subjectType, !!subjectTypeResult.isIncomplete, node.d.pattern, nodeInfo);
|
|
14440
15209
|
writeTypeCache(node, { type: narrowedSubjectType, isIncomplete: !!subjectTypeResult.isIncomplete }, 0 /* EvalFlags.None */);
|
|
14441
15210
|
}
|
|
14442
15211
|
function evaluateTypesForImportFrom(node) {
|
|
@@ -14446,7 +15215,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
14446
15215
|
if (node.d.isWildcardImport) {
|
|
14447
15216
|
// Write back a dummy type so we don't evaluate this node again.
|
|
14448
15217
|
writeTypeCache(node, { type: types_1.AnyType.create() }, 0 /* EvalFlags.None */);
|
|
14449
|
-
const flowNode =
|
|
15218
|
+
const flowNode = nodeInfo.getFlowNode(node);
|
|
14450
15219
|
if (flowNode && (flowNode.flags & codeFlowTypes_1.FlowFlags.WildcardImport) !== 0) {
|
|
14451
15220
|
const wildcardFlowNode = flowNode;
|
|
14452
15221
|
wildcardFlowNode.names.forEach((name) => {
|
|
@@ -14531,7 +15300,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
14531
15300
|
return undefined;
|
|
14532
15301
|
}
|
|
14533
15302
|
(0, debug_1.assert)(aliasDecl.type === 8 /* DeclarationType.Alias */);
|
|
14534
|
-
const fileInfo =
|
|
15303
|
+
const fileInfo = nodeInfo.getFileInfo(node);
|
|
14535
15304
|
// Try to resolve the alias while honoring external visibility.
|
|
14536
15305
|
const resolvedAliasInfo = resolveAliasDeclarationWithInfo(aliasDecl, /* resolveLocalNames */ true, {
|
|
14537
15306
|
allowExternallyHiddenAccess: fileInfo.isStubFile,
|
|
@@ -14814,7 +15583,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
14814
15583
|
? getDeclaredReturnType(enclosingFunctionNode)
|
|
14815
15584
|
: undefined;
|
|
14816
15585
|
if (declaredReturnType) {
|
|
14817
|
-
const liveScopeIds =
|
|
15586
|
+
const liveScopeIds = getTypeVarScopesForNode(node);
|
|
14818
15587
|
declaredReturnType = (0, typeUtils_1.makeTypeVarsBound)(declaredReturnType, liveScopeIds);
|
|
14819
15588
|
}
|
|
14820
15589
|
getTypeOfExpression(parent.d.expr, 0 /* EvalFlags.None */, (0, typeUtils_1.makeInferenceContext)(declaredReturnType));
|
|
@@ -14862,7 +15631,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
14862
15631
|
if (typeAnnotation) {
|
|
14863
15632
|
const param = functionNode.d.params[paramIndex];
|
|
14864
15633
|
let annotatedType = getTypeOfParamAnnotation(typeAnnotation, functionNode.d.params[paramIndex].d.category);
|
|
14865
|
-
const liveTypeVarScopes =
|
|
15634
|
+
const liveTypeVarScopes = getTypeVarScopesForNode(param);
|
|
14866
15635
|
annotatedType = (0, typeUtils_1.makeTypeVarsBound)(annotatedType, liveTypeVarScopes);
|
|
14867
15636
|
const adjType = transformVariadicParamType(node, node.d.category, adjustParamAnnotatedType(param, annotatedType));
|
|
14868
15637
|
writeTypeCache(node.d.name, { type: adjType }, 0 /* EvalFlags.None */);
|
|
@@ -14884,9 +15653,9 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
14884
15653
|
// infer the type of the parameter from a method of the same name in
|
|
14885
15654
|
// a parent class if it has an annotated type.
|
|
14886
15655
|
const functionFlags = (0, decorators_1.getFunctionInfoFromDecorators)(evaluatorInterface, functionNode,
|
|
14887
|
-
/* isInClass */ true).flags;
|
|
15656
|
+
/* isInClass */ true, nodeInfo).flags;
|
|
14888
15657
|
let inferredParamType = inferParamType(functionNode, functionFlags, paramIndex, classInfo?.classType) ?? types_1.UnknownType.create();
|
|
14889
|
-
const liveTypeVarScopes =
|
|
15658
|
+
const liveTypeVarScopes = getTypeVarScopesForNode(node);
|
|
14890
15659
|
inferredParamType = (0, typeUtils_1.makeTypeVarsBound)(inferredParamType, liveTypeVarScopes);
|
|
14891
15660
|
writeTypeCache(node.d.name, { type: transformVariadicParamType(node, node.d.category, inferredParamType) }, 0 /* EvalFlags.None */);
|
|
14892
15661
|
}
|
|
@@ -14998,9 +15767,15 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
14998
15767
|
// within that tree. If the type cannot be determined (because it's part
|
|
14999
15768
|
// of a cyclical dependency), the function returns undefined.
|
|
15000
15769
|
function evaluateTypeForSubnode(subnode, callback) {
|
|
15770
|
+
return evaluateTypeForSubnodeWithCache(subnode, callback, readTypeCacheEntry);
|
|
15771
|
+
}
|
|
15772
|
+
function evaluateContextualTypeForSubnode(subnode, callback) {
|
|
15773
|
+
return evaluateTypeForSubnodeWithCache(subnode, callback, readContextualTypeCacheEntryForNode);
|
|
15774
|
+
}
|
|
15775
|
+
function evaluateTypeForSubnodeWithCache(subnode, callback, readCacheEntry) {
|
|
15001
15776
|
// If the type cache is already populated with a complete type,
|
|
15002
15777
|
// don't bother doing additional work.
|
|
15003
|
-
let cacheEntry =
|
|
15778
|
+
let cacheEntry = readCacheEntry(subnode);
|
|
15004
15779
|
if (cacheEntry && !cacheEntry.typeResult.isIncomplete) {
|
|
15005
15780
|
const typeResult = cacheEntry.typeResult;
|
|
15006
15781
|
// Handle the special case where a function or class is partially evaluated.
|
|
@@ -15014,7 +15789,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
15014
15789
|
return typeResult;
|
|
15015
15790
|
}
|
|
15016
15791
|
callback();
|
|
15017
|
-
cacheEntry =
|
|
15792
|
+
cacheEntry = readCacheEntry(subnode);
|
|
15018
15793
|
if (cacheEntry) {
|
|
15019
15794
|
return cacheEntry.typeResult;
|
|
15020
15795
|
}
|
|
@@ -15056,8 +15831,8 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
15056
15831
|
function getFlowTypeOfReference(reference, startNode, options) {
|
|
15057
15832
|
// See if this execution scope requires code flow for this reference expression.
|
|
15058
15833
|
const referenceKey = (0, codeFlowTypes_1.createKeyForReference)(reference);
|
|
15059
|
-
const executionNode = ParseTreeUtils.getExecutionScopeNode(startNode?.parent ?? reference);
|
|
15060
|
-
const codeFlowExpressions =
|
|
15834
|
+
const executionNode = ParseTreeUtils.getExecutionScopeNode(startNode?.parent ?? reference, nodeInfo);
|
|
15835
|
+
const codeFlowExpressions = nodeInfo.getCodeFlowExpressions(executionNode);
|
|
15061
15836
|
if (!codeFlowExpressions ||
|
|
15062
15837
|
(!codeFlowExpressions.has(referenceKey) && !codeFlowExpressions.has(codeFlowTypes_1.wildcardImportReferenceKey))) {
|
|
15063
15838
|
return codeFlowEngine_1.FlowNodeTypeResult.create(/* type */ undefined, /* isIncomplete */ false);
|
|
@@ -15081,7 +15856,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
15081
15856
|
else {
|
|
15082
15857
|
analyzer = getCodeFlowAnalyzerForNode(executionNode, options?.typeAtStart);
|
|
15083
15858
|
}
|
|
15084
|
-
const flowNode =
|
|
15859
|
+
const flowNode = nodeInfo.getFlowNode(startNode ?? reference);
|
|
15085
15860
|
if (flowNode === undefined) {
|
|
15086
15861
|
return codeFlowEngine_1.FlowNodeTypeResult.create(/* type */ undefined, /* isIncomplete */ false);
|
|
15087
15862
|
}
|
|
@@ -15128,7 +15903,9 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
15128
15903
|
return { type: createClassVarType(classType, errorNode, typeArgs, flags) };
|
|
15129
15904
|
}
|
|
15130
15905
|
case 'Protocol': {
|
|
15131
|
-
if ((flags &
|
|
15906
|
+
if ((flags &
|
|
15907
|
+
(67108864 /* EvalFlags.NoNonTypeSpecialForms */ | 256 /* EvalFlags.TypeExpression */ | 1073741824 /* EvalFlags.TypeFormArg */)) !==
|
|
15908
|
+
0) {
|
|
15132
15909
|
addDiagnostic(diagnosticRules_1.DiagnosticRule.reportInvalidTypeForm, localize_1.LocMessage.protocolNotAllowed(), errorNode);
|
|
15133
15910
|
}
|
|
15134
15911
|
typeArgs?.forEach((typeArg) => {
|
|
@@ -15143,9 +15920,10 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
15143
15920
|
};
|
|
15144
15921
|
}
|
|
15145
15922
|
case 'TypedDict': {
|
|
15146
|
-
if ((flags &
|
|
15147
|
-
|
|
15148
|
-
|
|
15923
|
+
if ((flags &
|
|
15924
|
+
(67108864 /* EvalFlags.NoNonTypeSpecialForms */ | 256 /* EvalFlags.TypeExpression */ | 1073741824 /* EvalFlags.TypeFormArg */)) !==
|
|
15925
|
+
0) {
|
|
15926
|
+
const isInlinedTypedDict = nodeInfo.getFileInfo(errorNode).diagnosticRuleSet.enableExperimentalFeatures && !!typeArgs;
|
|
15149
15927
|
if (!isInlinedTypedDict) {
|
|
15150
15928
|
addDiagnostic(diagnosticRules_1.DiagnosticRule.reportInvalidTypeForm, localize_1.LocMessage.typedDictNotAllowed(), errorNode);
|
|
15151
15929
|
}
|
|
@@ -15154,12 +15932,21 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
15154
15932
|
break;
|
|
15155
15933
|
}
|
|
15156
15934
|
case 'Literal': {
|
|
15157
|
-
if ((flags &
|
|
15935
|
+
if ((flags &
|
|
15936
|
+
(67108864 /* EvalFlags.NoNonTypeSpecialForms */ | 256 /* EvalFlags.TypeExpression */ | 1073741824 /* EvalFlags.TypeFormArg */)) !==
|
|
15937
|
+
0) {
|
|
15158
15938
|
addDiagnostic(diagnosticRules_1.DiagnosticRule.reportInvalidTypeForm, localize_1.LocMessage.literalNotAllowed(), errorNode);
|
|
15159
15939
|
}
|
|
15160
15940
|
isValidTypeForm = false;
|
|
15161
15941
|
break;
|
|
15162
15942
|
}
|
|
15943
|
+
case 'TypeAlias': {
|
|
15944
|
+
if ((flags & 1073741824 /* EvalFlags.TypeFormArg */) !== 0) {
|
|
15945
|
+
addDiagnostic(diagnosticRules_1.DiagnosticRule.reportInvalidTypeForm, localize_1.LocMessage.typeAnnotationVariable(), errorNode);
|
|
15946
|
+
}
|
|
15947
|
+
isValidTypeForm = false;
|
|
15948
|
+
break;
|
|
15949
|
+
}
|
|
15163
15950
|
case 'Tuple': {
|
|
15164
15951
|
return {
|
|
15165
15952
|
type: createSpecialType(classType, typeArgs,
|
|
@@ -15208,10 +15995,10 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
15208
15995
|
}
|
|
15209
15996
|
}
|
|
15210
15997
|
}
|
|
15211
|
-
const fileInfo =
|
|
15998
|
+
const fileInfo = nodeInfo.getFileInfo(errorNode);
|
|
15212
15999
|
if (fileInfo.isStubFile ||
|
|
15213
16000
|
pythonVersion_1.PythonVersion.isGreaterOrEqualTo(fileInfo.executionEnvironment.pythonVersion, pythonVersion_1.pythonVersion3_9) ||
|
|
15214
|
-
(0, analyzerFileInfo_1.isAnnotationEvaluationPostponed)(
|
|
16001
|
+
(0, analyzerFileInfo_1.isAnnotationEvaluationPostponed)(nodeInfo.getFileInfo(errorNode)) ||
|
|
15215
16002
|
(flags & 4 /* EvalFlags.ForwardRefs */) !== 0) {
|
|
15216
16003
|
// Handle "type" specially, since it needs to act like "Type"
|
|
15217
16004
|
// in Python 3.9 and newer.
|
|
@@ -15269,7 +16056,11 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
15269
16056
|
received: typeArgCount,
|
|
15270
16057
|
}), typeArgs[1].node);
|
|
15271
16058
|
}
|
|
15272
|
-
|
|
16059
|
+
let inlinedTypeDict = typeArgs[0].inlinedTypeDict;
|
|
16060
|
+
if ((flags & 1073741824 /* EvalFlags.TypeFormArg */) !== 0) {
|
|
16061
|
+
inlinedTypeDict = types_1.TypeBase.cloneWithTypeForm(inlinedTypeDict, (0, typeUtils_1.convertToInstance)(inlinedTypeDict));
|
|
16062
|
+
}
|
|
16063
|
+
return { type: inlinedTypeDict };
|
|
15273
16064
|
}
|
|
15274
16065
|
else if (typeArgCount > typeParams.length) {
|
|
15275
16066
|
if (!types_1.ClassType.isPartiallyEvaluated(classType) && !types_1.ClassType.isTupleClass(classType)) {
|
|
@@ -15379,7 +16170,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
15379
16170
|
return;
|
|
15380
16171
|
}
|
|
15381
16172
|
}
|
|
15382
|
-
const typeArgType = (
|
|
16173
|
+
const typeArgType = convertTypeArgToInstance(typeArgs[index].type, flags);
|
|
15383
16174
|
typeArgTypes.push(typeArgType);
|
|
15384
16175
|
constraints.setBounds(typeParam, typeArgType);
|
|
15385
16176
|
return;
|
|
@@ -15524,7 +16315,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
15524
16315
|
if (options?.enforceClassTypeVarScope) {
|
|
15525
16316
|
flags |= -2147483648 /* EvalFlags.EnforceClassTypeVarScope */;
|
|
15526
16317
|
}
|
|
15527
|
-
const fileInfo =
|
|
16318
|
+
const fileInfo = nodeInfo.getFileInfo(node);
|
|
15528
16319
|
if (((0, analyzerFileInfo_1.isAnnotationEvaluationPostponed)(fileInfo) || options?.forwardRefs) && !options?.runtimeTypeExpression) {
|
|
15529
16320
|
flags |= 4 /* EvalFlags.ForwardRefs */;
|
|
15530
16321
|
}
|
|
@@ -15579,7 +16370,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
15579
16370
|
return getTypeOfExpression(node, flags);
|
|
15580
16371
|
}
|
|
15581
16372
|
function getBuiltInType(node, name) {
|
|
15582
|
-
const scope =
|
|
16373
|
+
const scope = getScopeForNode(node);
|
|
15583
16374
|
if (scope) {
|
|
15584
16375
|
const builtInScope = ScopeUtils.getBuiltInScope(scope);
|
|
15585
16376
|
const nameType = builtInScope.lookUpSymbol(name);
|
|
@@ -15601,8 +16392,8 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
15601
16392
|
return nameType;
|
|
15602
16393
|
}
|
|
15603
16394
|
function lookUpSymbolRecursive(node, name, honorCodeFlow, preferGlobalScope = false) {
|
|
15604
|
-
const scopeNodeInfo = ParseTreeUtils.getEvaluationScopeNode(node);
|
|
15605
|
-
const scope =
|
|
16395
|
+
const scopeNodeInfo = ParseTreeUtils.getEvaluationScopeNode(node, nodeInfo);
|
|
16396
|
+
const scope = nodeInfo.getScope(scopeNodeInfo.node);
|
|
15606
16397
|
let symbolWithScope = scope?.lookUpSymbolRecursive(name, {
|
|
15607
16398
|
useProxyScope: !!scopeNodeInfo.useProxyScope,
|
|
15608
16399
|
useChainedModuleLevelScopes: !!scopeNodeInfo.useChainedModuleLevelScopes,
|
|
@@ -15621,20 +16412,20 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
15621
16412
|
const reachableDecl = symbolWithScope.symbol.getDeclarations().find((decl) => {
|
|
15622
16413
|
if (decl.type !== 8 /* DeclarationType.Alias */ && decl.type !== 0 /* DeclarationType.Intrinsic */) {
|
|
15623
16414
|
// Determine if the declaration is in the same execution scope as the "usageNode" node.
|
|
15624
|
-
let usageScopeNode = ParseTreeUtils.getExecutionScopeNode(node);
|
|
16415
|
+
let usageScopeNode = ParseTreeUtils.getExecutionScopeNode(node, nodeInfo);
|
|
15625
16416
|
const declNode = decl.type === 6 /* DeclarationType.Class */ ||
|
|
15626
16417
|
decl.type === 5 /* DeclarationType.Function */ ||
|
|
15627
16418
|
decl.type === 4 /* DeclarationType.TypeAlias */
|
|
15628
16419
|
? decl.node.d.name
|
|
15629
16420
|
: decl.node;
|
|
15630
|
-
const declScopeNode = ParseTreeUtils.getExecutionScopeNode(declNode);
|
|
16421
|
+
const declScopeNode = ParseTreeUtils.getExecutionScopeNode(declNode, nodeInfo);
|
|
15631
16422
|
// If this is a type parameter scope, it will be a proxy for its
|
|
15632
16423
|
// containing scope, so we need to use that instead.
|
|
15633
|
-
const usageScope =
|
|
16424
|
+
const usageScope = nodeInfo.getScope(usageScopeNode);
|
|
15634
16425
|
if (usageScope?.proxy) {
|
|
15635
|
-
const typeParamScope =
|
|
16426
|
+
const typeParamScope = nodeInfo.getScope(usageScopeNode);
|
|
15636
16427
|
if (!typeParamScope?.symbolTable.has(name) && usageScopeNode.parent) {
|
|
15637
|
-
usageScopeNode = ParseTreeUtils.getExecutionScopeNode(usageScopeNode.parent);
|
|
16428
|
+
usageScopeNode = ParseTreeUtils.getExecutionScopeNode(usageScopeNode.parent, nodeInfo);
|
|
15638
16429
|
}
|
|
15639
16430
|
}
|
|
15640
16431
|
if (usageScopeNode === declScopeNode) {
|
|
@@ -15642,7 +16433,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
15642
16433
|
// If there was no control flow path from the usage back
|
|
15643
16434
|
// to the source, see if the usage node is reachable by
|
|
15644
16435
|
// any path.
|
|
15645
|
-
const flowNode =
|
|
16436
|
+
const flowNode = nodeInfo.getFlowNode(node);
|
|
15646
16437
|
const isReachable = flowNode &&
|
|
15647
16438
|
codeFlowEngine.getFlowNodeReachability(flowNode,
|
|
15648
16439
|
/* sourceFlowNode */ undefined,
|
|
@@ -15818,7 +16609,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
15818
16609
|
const functionDecl = type.shared.declaration;
|
|
15819
16610
|
if (functionDecl.type === 5 /* DeclarationType.Function */) {
|
|
15820
16611
|
const functionNode = functionDecl.node;
|
|
15821
|
-
const functionScope =
|
|
16612
|
+
const functionScope = nodeInfo.getScope(functionNode);
|
|
15822
16613
|
if (functionScope) {
|
|
15823
16614
|
const paramSymbol = functionScope.lookUpSymbol(paramName);
|
|
15824
16615
|
if (paramSymbol) {
|
|
@@ -15839,6 +16630,48 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
15839
16630
|
}
|
|
15840
16631
|
return undefined;
|
|
15841
16632
|
}
|
|
16633
|
+
// functools.partial(func, kw=value) forwards keyword arguments to the wrapped callable, but
|
|
16634
|
+
// partial's own signature absorbs them through **kwargs, so they don't resolve to a declaration.
|
|
16635
|
+
// Resolve the keyword against the wrapped callable (the first positional argument) instead so IDE
|
|
16636
|
+
// features like go-to-definition and rename bind to the underlying parameter. Returns true when
|
|
16637
|
+
// baseType is functools.partial, so the caller suppresses the default keyword-argument handling.
|
|
16638
|
+
function _tryAddPartialKeywordParamDecls(baseType, callNode, paramName, decls) {
|
|
16639
|
+
if (!(0, types_1.isInstantiableClass)(baseType) || baseType.shared.fullName !== 'functools.partial') {
|
|
16640
|
+
return false;
|
|
16641
|
+
}
|
|
16642
|
+
const wrappedArg = callNode.d.args.find((arg) => arg.d.argCategory === 0 /* ArgCategory.Simple */ && !arg.d.name);
|
|
16643
|
+
if (!wrappedArg) {
|
|
16644
|
+
return true;
|
|
16645
|
+
}
|
|
16646
|
+
const wrappedType = getType(wrappedArg.d.valueExpr);
|
|
16647
|
+
if (!wrappedType) {
|
|
16648
|
+
return true;
|
|
16649
|
+
}
|
|
16650
|
+
if ((0, types_1.isFunction)(wrappedType)) {
|
|
16651
|
+
const paramDecl = getDeclarationFromKeywordParam(wrappedType, paramName);
|
|
16652
|
+
if (paramDecl) {
|
|
16653
|
+
decls.push(paramDecl);
|
|
16654
|
+
}
|
|
16655
|
+
}
|
|
16656
|
+
else if ((0, types_1.isOverloaded)(wrappedType)) {
|
|
16657
|
+
types_1.OverloadedType.getOverloads(wrappedType).forEach((f) => {
|
|
16658
|
+
const paramDecl = getDeclarationFromKeywordParam(f, paramName);
|
|
16659
|
+
if (paramDecl) {
|
|
16660
|
+
decls.push(paramDecl);
|
|
16661
|
+
}
|
|
16662
|
+
});
|
|
16663
|
+
}
|
|
16664
|
+
else if ((0, types_1.isInstantiableClass)(wrappedType)) {
|
|
16665
|
+
const initMethodType = (0, constructors_1.getBoundInitMethod)(evaluatorInterface, wrappedArg.d.valueExpr, types_1.ClassType.cloneAsInstance(wrappedType))?.type;
|
|
16666
|
+
if (initMethodType && (0, types_1.isFunction)(initMethodType)) {
|
|
16667
|
+
const paramDecl = getDeclarationFromKeywordParam(initMethodType, paramName);
|
|
16668
|
+
if (paramDecl) {
|
|
16669
|
+
decls.push(paramDecl);
|
|
16670
|
+
}
|
|
16671
|
+
}
|
|
16672
|
+
}
|
|
16673
|
+
return true;
|
|
16674
|
+
}
|
|
15842
16675
|
function _shouldFallBackToClassEntryForKeywordArg(baseType, paramName) {
|
|
15843
16676
|
return (types_1.ClassType.isDataClass(baseType) ||
|
|
15844
16677
|
types_1.ClassType.isTypedDictClass(baseType) ||
|
|
@@ -15905,7 +16738,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
15905
16738
|
return undefined;
|
|
15906
16739
|
}
|
|
15907
16740
|
function getDeclInfoForNameNode(node, skipUnreachableCode = true) {
|
|
15908
|
-
if (skipUnreachableCode &&
|
|
16741
|
+
if (skipUnreachableCode && nodeInfo.isCodeUnreachable(node)) {
|
|
15909
16742
|
return undefined;
|
|
15910
16743
|
}
|
|
15911
16744
|
const decls = [];
|
|
@@ -15915,7 +16748,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
15915
16748
|
// since the non-aliased name is not in the symbol table.
|
|
15916
16749
|
const alias = getAliasFromImport(node);
|
|
15917
16750
|
if (alias) {
|
|
15918
|
-
const scope =
|
|
16751
|
+
const scope = getScopeForNode(node);
|
|
15919
16752
|
if (scope) {
|
|
15920
16753
|
// Look up the alias symbol.
|
|
15921
16754
|
const symbolInScope = scope.lookUpSymbolRecursive(alias.d.value);
|
|
@@ -15981,7 +16814,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
15981
16814
|
}
|
|
15982
16815
|
else if (node.parent && node.parent.nodeType === 37 /* ParseNodeType.ModuleName */) {
|
|
15983
16816
|
const namePartIndex = node.parent.d.nameParts.findIndex((part) => part === node);
|
|
15984
|
-
const importInfo =
|
|
16817
|
+
const importInfo = nodeInfo.getImportInfo(node.parent);
|
|
15985
16818
|
if (namePartIndex >= 0 &&
|
|
15986
16819
|
importInfo &&
|
|
15987
16820
|
!importInfo.isNativeLib &&
|
|
@@ -16003,7 +16836,10 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
16003
16836
|
if (argNode.parent?.nodeType === 9 /* ParseNodeType.Call */) {
|
|
16004
16837
|
const baseType = getType(argNode.parent.d.leftExpr);
|
|
16005
16838
|
if (baseType) {
|
|
16006
|
-
if ((
|
|
16839
|
+
if (_tryAddPartialKeywordParamDecls(baseType, argNode.parent, paramName, decls)) {
|
|
16840
|
+
// functools.partial keyword args are resolved against the wrapped callable.
|
|
16841
|
+
}
|
|
16842
|
+
else if ((0, types_1.isFunction)(baseType) && baseType.shared.declaration) {
|
|
16007
16843
|
const paramDecl = getDeclarationFromKeywordParam(baseType, paramName);
|
|
16008
16844
|
if (paramDecl) {
|
|
16009
16845
|
decls.push(paramDecl);
|
|
@@ -16047,10 +16883,45 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
16047
16883
|
}
|
|
16048
16884
|
}
|
|
16049
16885
|
}
|
|
16886
|
+
else if (node.parent &&
|
|
16887
|
+
node.parent.nodeType === 74 /* ParseNodeType.PatternClassArgument */ &&
|
|
16888
|
+
node === node.parent.d.name &&
|
|
16889
|
+
node.parent.parent?.nodeType === 68 /* ParseNodeType.PatternClass */) {
|
|
16890
|
+
// The target node is the keyword name in a class pattern argument
|
|
16891
|
+
// (e.g. `case Foo(prop=...)`). Map it to the corresponding class member
|
|
16892
|
+
// declaration so that find-all-references and rename bind to the attribute.
|
|
16893
|
+
// Only the keyword (left of `=`) is handled here; the capture target on the
|
|
16894
|
+
// right (e.g. the second `prop` in `case Foo(prop=prop)`) is a separate local
|
|
16895
|
+
// binding that is resolved through the normal name-lookup path.
|
|
16896
|
+
const memberName = node.d.value;
|
|
16897
|
+
let classType = getType(node.parent.parent.d.className);
|
|
16898
|
+
if (classType) {
|
|
16899
|
+
classType = makeTopLevelTypeVarsConcrete(classType);
|
|
16900
|
+
(0, typeUtils_1.doForEachSubtype)(classType, (subtype) => {
|
|
16901
|
+
subtype = makeTopLevelTypeVarsConcrete(subtype);
|
|
16902
|
+
// The class name in a class pattern usually evaluates to an instantiable class,
|
|
16903
|
+
// but analysis can still yield Unknown/Any (e.g. an unresolved class name), so
|
|
16904
|
+
// the isInstantiableClass gate skips those subtypes rather than assuming
|
|
16905
|
+
// every subtype is a class.
|
|
16906
|
+
if ((0, types_1.isInstantiableClass)(subtype)) {
|
|
16907
|
+
// Try to find a member that has a declared type. If so, that
|
|
16908
|
+
// overrides any inferred types.
|
|
16909
|
+
let member = (0, typeUtils_1.lookUpClassMember)(subtype, memberName, 64 /* MemberAccessFlags.DeclaredTypesOnly */);
|
|
16910
|
+
if (!member) {
|
|
16911
|
+
member = (0, typeUtils_1.lookUpClassMember)(subtype, memberName);
|
|
16912
|
+
}
|
|
16913
|
+
if (member) {
|
|
16914
|
+
_addSymbolDeclInfo(member.symbol, decls, synthesizedTypes,
|
|
16915
|
+
/* preferTypedDeclarations */ true);
|
|
16916
|
+
}
|
|
16917
|
+
}
|
|
16918
|
+
});
|
|
16919
|
+
}
|
|
16920
|
+
}
|
|
16050
16921
|
else {
|
|
16051
|
-
const fileInfo =
|
|
16922
|
+
const fileInfo = nodeInfo.getFileInfo(node);
|
|
16052
16923
|
// Determine if this node is within a quoted type annotation.
|
|
16053
|
-
const isWithinTypeAnnotation = ParseTreeUtils.isWithinTypeAnnotation(node, !(0, analyzerFileInfo_1.isAnnotationEvaluationPostponed)(
|
|
16924
|
+
const isWithinTypeAnnotation = ParseTreeUtils.isWithinTypeAnnotation(node, !(0, analyzerFileInfo_1.isAnnotationEvaluationPostponed)(nodeInfo.getFileInfo(node)), nodeInfo);
|
|
16054
16925
|
// Determine if this is part of a "type" statement.
|
|
16055
16926
|
const isWithinTypeAliasStatement = !!ParseTreeUtils.getParentNodeOfType(node, 77 /* ParseNodeType.TypeAlias */);
|
|
16056
16927
|
const allowForwardReferences = isWithinTypeAnnotation || isWithinTypeAliasStatement || fileInfo.isStubFile;
|
|
@@ -16138,7 +17009,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
16138
17009
|
}
|
|
16139
17010
|
if (typeAnnotationNode) {
|
|
16140
17011
|
let declaredType = getTypeOfParamAnnotation(typeAnnotationNode, declaration.node.d.category);
|
|
16141
|
-
const liveTypeVarScopes =
|
|
17012
|
+
const liveTypeVarScopes = getTypeVarScopesForNode(declaration.node);
|
|
16142
17013
|
declaredType = (0, typeUtils_1.makeTypeVarsBound)(declaredType, liveTypeVarScopes);
|
|
16143
17014
|
return {
|
|
16144
17015
|
type: transformVariadicParamType(declaration.node, declaration.node.d.category, adjustParamAnnotatedType(declaration.node, declaredType)),
|
|
@@ -16186,9 +17057,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
16186
17057
|
if (declaration.isDefinedByMemberAccess) {
|
|
16187
17058
|
const enclosingClass = ParseTreeUtils.getEnclosingClass(declaration.node);
|
|
16188
17059
|
if (enclosingClass) {
|
|
16189
|
-
declaredType = (0, typeUtils_1.makeTypeVarsFree)(declaredType, [
|
|
16190
|
-
ParseTreeUtils.getScopeIdForNode(enclosingClass),
|
|
16191
|
-
]);
|
|
17060
|
+
declaredType = (0, typeUtils_1.makeTypeVarsFree)(declaredType, [getScopeIdForNode(enclosingClass)]);
|
|
16192
17061
|
}
|
|
16193
17062
|
}
|
|
16194
17063
|
if ((0, types_1.isClassInstance)(declaredType) && types_1.ClassType.isBuiltIn(declaredType, 'TypeAlias')) {
|
|
@@ -16333,7 +17202,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
16333
17202
|
typeVar.shared.declaredVariance =
|
|
16334
17203
|
(0, types_1.isParamSpec)(typeVar) || (0, types_1.isTypeVarTuple)(typeVar) ? 2 /* Variance.Invariant */ : 0 /* Variance.Auto */;
|
|
16335
17204
|
}
|
|
16336
|
-
typeVar = types_1.TypeVarType.cloneForScopeId(typeVar,
|
|
17205
|
+
typeVar = types_1.TypeVarType.cloneForScopeId(typeVar, getScopeIdForNode(scopeNode.nodeType === 77 /* ParseNodeType.TypeAlias */ ? scopeNode.d.name : scopeNode), scopeNode.d.name.d.value, scopeType);
|
|
16337
17206
|
}
|
|
16338
17207
|
writeTypeCache(node, { type: typeVar }, /* flags */ undefined);
|
|
16339
17208
|
writeTypeCache(node.d.name, { type: typeVar }, /* flags */ undefined);
|
|
@@ -16341,7 +17210,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
16341
17210
|
}
|
|
16342
17211
|
function getInferredTypeOfDeclaration(symbol, decl) {
|
|
16343
17212
|
const resolvedDecl = resolveAliasDeclaration(decl, /* resolveLocalNames */ true, {
|
|
16344
|
-
allowExternallyHiddenAccess:
|
|
17213
|
+
allowExternallyHiddenAccess: nodeInfo.getFileInfo(decl.node).isStubFile,
|
|
16345
17214
|
});
|
|
16346
17215
|
// We couldn't resolve the alias. Substitute an unknown
|
|
16347
17216
|
// type in this case.
|
|
@@ -16427,7 +17296,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
16427
17296
|
}
|
|
16428
17297
|
// If this is part of a "py.typed" package, don't fall back on type inference
|
|
16429
17298
|
// unless it's marked Final, is a constant, or is a declared type alias.
|
|
16430
|
-
const fileInfo =
|
|
17299
|
+
const fileInfo = nodeInfo.getFileInfo(resolvedDecl.node);
|
|
16431
17300
|
let isUnambiguousType = !fileInfo.isInPyTypedPackage || fileInfo.isStubFile;
|
|
16432
17301
|
// If this is a py.typed package, determine if this is a case where an unannotated
|
|
16433
17302
|
// variable is considered "unambiguous" because all type checkers are almost
|
|
@@ -16639,7 +17508,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
16639
17508
|
if (decl.type === 1 /* DeclarationType.Variable */) {
|
|
16640
17509
|
// Exempt typing.pyi and typingExtensions.pyi, which use variables to
|
|
16641
17510
|
// define some special forms.
|
|
16642
|
-
const fileInfo =
|
|
17511
|
+
const fileInfo = nodeInfo.getFileInfo(decl.node);
|
|
16643
17512
|
if (!fileInfo.isTypingStubFile && !fileInfo.isTypingExtensionsStubFile) {
|
|
16644
17513
|
return true;
|
|
16645
17514
|
}
|
|
@@ -16703,7 +17572,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
16703
17572
|
let sawExplicitTypeAlias = false;
|
|
16704
17573
|
decls.forEach((decl, index) => {
|
|
16705
17574
|
const resolvedDecl = resolveAliasDeclaration(decl, /* resolveLocalNames */ true, {
|
|
16706
|
-
allowExternallyHiddenAccess:
|
|
17575
|
+
allowExternallyHiddenAccess: nodeInfo.getFileInfo(decl.node).isStubFile,
|
|
16707
17576
|
}) ?? decl;
|
|
16708
17577
|
if (!isPossibleTypeAliasDeclaration(resolvedDecl) && !isExplicitTypeAliasDeclaration(resolvedDecl)) {
|
|
16709
17578
|
includesIllegalTypeAliasDecl = true;
|
|
@@ -16734,8 +17603,8 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
16734
17603
|
// Is the declaration in the same execution scope as the "usageNode" node?
|
|
16735
17604
|
// If so, we can skip it because code flow analysis will allow us
|
|
16736
17605
|
// to determine the type in this context.
|
|
16737
|
-
const usageScope = ParseTreeUtils.getExecutionScopeNode(usageNode);
|
|
16738
|
-
const declScope = ParseTreeUtils.getExecutionScopeNode(decl.node);
|
|
17606
|
+
const usageScope = ParseTreeUtils.getExecutionScopeNode(usageNode, nodeInfo);
|
|
17607
|
+
const declScope = ParseTreeUtils.getExecutionScopeNode(decl.node, nodeInfo);
|
|
16739
17608
|
if (usageScope === declScope) {
|
|
16740
17609
|
// Skip declarations that appear after the usage in the source.
|
|
16741
17610
|
// Such declarations are typically only reached via loop back-edges,
|
|
@@ -16923,8 +17792,8 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
16923
17792
|
const filteredTypedDecls = typedDecls.filter((decl) => {
|
|
16924
17793
|
if (decl.type !== 8 /* DeclarationType.Alias */) {
|
|
16925
17794
|
// Is the declaration in the same execution scope as the "usageNode" node?
|
|
16926
|
-
const usageScope = ParseTreeUtils.getExecutionScopeNode(usageNode);
|
|
16927
|
-
const declScope = ParseTreeUtils.getExecutionScopeNode(decl.node);
|
|
17795
|
+
const usageScope = ParseTreeUtils.getExecutionScopeNode(usageNode, nodeInfo);
|
|
17796
|
+
const declScope = ParseTreeUtils.getExecutionScopeNode(decl.node, nodeInfo);
|
|
16928
17797
|
if (usageScope === declScope) {
|
|
16929
17798
|
// For typed declarations we use the precise flow-graph reachability
|
|
16930
17799
|
// check rather than a simple position comparison, because typed decls
|
|
@@ -17010,7 +17879,35 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
17010
17879
|
function getEffectiveReturnTypeResult(type, options) {
|
|
17011
17880
|
const specializedReturnType = types_1.FunctionType.getEffectiveReturnType(type, /* includeInferred */ false);
|
|
17012
17881
|
if (specializedReturnType && !(0, types_1.isUnknown)(specializedReturnType)) {
|
|
17013
|
-
return
|
|
17882
|
+
// A partially-unknown *inferred* return type (e.g. `Foo | Unknown`) can be
|
|
17883
|
+
// cached on a specialized/bound copy of an unannotated function. Because
|
|
17884
|
+
// `isUnknown` matches only a fully-unknown type, such a partial type would
|
|
17885
|
+
// otherwise short-circuit here and prevent call-site return-type inference
|
|
17886
|
+
// from ever running (e.g. an unannotated factory whose body narrows a
|
|
17887
|
+
// parameter-derived local with `isinstance`). When a call site is available,
|
|
17888
|
+
// fall through so the argument types can refine the inferred return type.
|
|
17889
|
+
//
|
|
17890
|
+
// NOTE: This gate intentionally mirrors a subset of the downstream call-site
|
|
17891
|
+
// refinement guard in `_getInferredReturnTypeResult` (search `isPartlyUnknown(returnType)`),
|
|
17892
|
+
// but tests the cached *specialized* return type here rather than the freshly-inferred
|
|
17893
|
+
// one, and omits the `!isStubDefinition`/`!isPyTypedDefinition`/`!isIncomplete`
|
|
17894
|
+
// conjuncts (not yet known at this point). Keep the two in sync if either is edited.
|
|
17895
|
+
const canRefineWithCallSite = options?.callSiteInfo !== undefined &&
|
|
17896
|
+
!type.shared.declaredReturnType &&
|
|
17897
|
+
types_1.FunctionType.hasUnannotatedParams(type) &&
|
|
17898
|
+
(0, typeUtils_1.isPartlyUnknown)(specializedReturnType);
|
|
17899
|
+
if (!canRefineWithCallSite) {
|
|
17900
|
+
return { type: specializedReturnType };
|
|
17901
|
+
}
|
|
17902
|
+
// Refine the cached partly-unknown return type using the call site. If the
|
|
17903
|
+
// refinement comes back incomplete -- e.g. a self- or mutually-recursive
|
|
17904
|
+
// factory whose base case returns the isinstance-narrowed local -- fall back
|
|
17905
|
+
// to the already-cached specialized return type rather than propagating the
|
|
17906
|
+
// incomplete result. The cached type is already correct in that case, and
|
|
17907
|
+
// propagating `isIncomplete` would suppress caller-side diagnostics that only
|
|
17908
|
+
// fire on a complete type (for example, `reveal_type`).
|
|
17909
|
+
const refinedResult = getInferredReturnTypeResult(type, options?.callSiteInfo);
|
|
17910
|
+
return refinedResult.isIncomplete ? { type: specializedReturnType } : refinedResult;
|
|
17014
17911
|
}
|
|
17015
17912
|
return getInferredReturnTypeResult(type, options?.callSiteInfo);
|
|
17016
17913
|
}
|
|
@@ -17049,11 +17946,11 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
17049
17946
|
}
|
|
17050
17947
|
else if (type.shared.declaration) {
|
|
17051
17948
|
const functionNode = type.shared.declaration.node;
|
|
17052
|
-
const skipUnannotatedFunction = !
|
|
17949
|
+
const skipUnannotatedFunction = !nodeInfo.getFileInfo(functionNode).diagnosticRuleSet.analyzeUnannotatedFunctions &&
|
|
17053
17950
|
ParseTreeUtils.isUnannotatedFunction(functionNode);
|
|
17054
17951
|
// Skip return type inference if we are in "skip unannotated function" mode.
|
|
17055
17952
|
if (!skipUnannotatedFunction && !checkCodeFlowTooComplex(functionNode.d.suite)) {
|
|
17056
|
-
const codeFlowComplexity =
|
|
17953
|
+
const codeFlowComplexity = nodeInfo.getCodeFlowComplexity(functionNode);
|
|
17057
17954
|
// For very complex functions that have no annotated parameter types,
|
|
17058
17955
|
// don't attempt to infer the return type because it can be extremely
|
|
17059
17956
|
// expensive.
|
|
@@ -17117,7 +18014,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
17117
18014
|
returnType = contextualReturnType;
|
|
17118
18015
|
if (type.shared.declaration?.node) {
|
|
17119
18016
|
// Externalize any TypeVars that appear in the type.
|
|
17120
|
-
const liveScopeIds =
|
|
18017
|
+
const liveScopeIds = getTypeVarScopesForNode(type.shared.declaration.node);
|
|
17121
18018
|
returnType = (0, typeUtils_1.makeTypeVarsFree)(returnType, liveScopeIds);
|
|
17122
18019
|
}
|
|
17123
18020
|
}
|
|
@@ -17132,7 +18029,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
17132
18029
|
return undefined;
|
|
17133
18030
|
}
|
|
17134
18031
|
const functionNode = type.shared.declaration.node;
|
|
17135
|
-
const codeFlowComplexity =
|
|
18032
|
+
const codeFlowComplexity = nodeInfo.getCodeFlowComplexity(functionNode);
|
|
17136
18033
|
if (codeFlowComplexity >= maxReturnCallSiteTypeInferenceCodeFlowComplexity) {
|
|
17137
18034
|
return undefined;
|
|
17138
18035
|
}
|
|
@@ -17173,12 +18070,14 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
17173
18070
|
// this function so we can analyze it separately without polluting
|
|
17174
18071
|
// the main type cache.
|
|
17175
18072
|
const prevTypeCache = returnTypeInferenceTypeCache;
|
|
18073
|
+
const prevTypeFormTypeCache = returnTypeInferenceTypeFormTypeCache;
|
|
17176
18074
|
returnTypeInferenceContextStack.push({
|
|
17177
18075
|
functionNode,
|
|
17178
18076
|
codeFlowAnalyzer: codeFlowEngine.createCodeFlowAnalyzer(),
|
|
17179
18077
|
});
|
|
17180
18078
|
try {
|
|
17181
18079
|
returnTypeInferenceTypeCache = new Map();
|
|
18080
|
+
returnTypeInferenceTypeFormTypeCache = new Map();
|
|
17182
18081
|
let allArgTypesAreUnknown = true;
|
|
17183
18082
|
functionNode.d.params.forEach((param, index) => {
|
|
17184
18083
|
if (param.d.name) {
|
|
@@ -17240,6 +18139,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
17240
18139
|
finally {
|
|
17241
18140
|
returnTypeInferenceContextStack.pop();
|
|
17242
18141
|
returnTypeInferenceTypeCache = prevTypeCache;
|
|
18142
|
+
returnTypeInferenceTypeFormTypeCache = prevTypeFormTypeCache;
|
|
17243
18143
|
}
|
|
17244
18144
|
});
|
|
17245
18145
|
if (contextualReturnType) {
|
|
@@ -17386,6 +18286,27 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
17386
18286
|
}
|
|
17387
18287
|
}
|
|
17388
18288
|
}
|
|
18289
|
+
// A class value normally remains unspecialized so it can be subscripted.
|
|
18290
|
+
// If every type parameter has an explicit default, apply those defaults
|
|
18291
|
+
// when comparing it against a type specialization. Classes with defaultless
|
|
18292
|
+
// parameters or defaults that resolve directly to Any or Unknown retain
|
|
18293
|
+
// their unspecialized behavior, so they don't degrade inference.
|
|
18294
|
+
if (types_1.TypeBase.isInstantiable(srcType) &&
|
|
18295
|
+
srcType.props?.typeForm &&
|
|
18296
|
+
!srcType.priv.typeArgs &&
|
|
18297
|
+
!srcType.priv.includeSubclasses &&
|
|
18298
|
+
srcType.shared.typeParams.length > 0 &&
|
|
18299
|
+
srcType.shared.typeParams.every((typeParam) => typeParam.shared.isDefaultExplicit)) {
|
|
18300
|
+
const specializedSrcType = (0, typeUtils_1.specializeWithDefaultTypeArgs)(srcType);
|
|
18301
|
+
const specializedTypeArgs = specializedSrcType.priv.typeArgs ??
|
|
18302
|
+
specializedSrcType.priv.tupleTypeArgs?.map((tupleTypeArg) => tupleTypeArg.type);
|
|
18303
|
+
const hasGradualTypeArg = specializedTypeArgs?.some((typeArg) => !!(0, typeUtils_1.containsAnyOrUnknown)(typeArg, /* recurse */ false) ||
|
|
18304
|
+
((0, types_1.isFunction)(typeArg) && types_1.FunctionType.isGradualCallableForm(typeArg)) ||
|
|
18305
|
+
((0, types_1.isUnpackedClass)(typeArg) && !!(0, typeUtils_1.containsAnyOrUnknown)(typeArg, /* recurse */ true)));
|
|
18306
|
+
if (hasGradualTypeArg === false) {
|
|
18307
|
+
srcType = specializedSrcType;
|
|
18308
|
+
}
|
|
18309
|
+
}
|
|
17389
18310
|
// Is it a structural type (i.e. a protocol)? If so, we need to
|
|
17390
18311
|
// perform a member-by-member check.
|
|
17391
18312
|
const inheritanceChain = [];
|
|
@@ -17778,6 +18699,19 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
17778
18699
|
}
|
|
17779
18700
|
}
|
|
17780
18701
|
}
|
|
18702
|
+
// A subscripted runtime built-in such as list[int] is represented as its
|
|
18703
|
+
// precise class type, but it is also a types.GenericAlias object at runtime.
|
|
18704
|
+
if ((0, types_1.isClassInstance)(destType) &&
|
|
18705
|
+
types_1.ClassType.isBuiltIn(destType, 'GenericAlias') &&
|
|
18706
|
+
(0, types_1.isInstantiableClass)(srcType) &&
|
|
18707
|
+
!types_1.ClassType.isSpecialBuiltIn(srcType) &&
|
|
18708
|
+
!srcType.priv.aliasName &&
|
|
18709
|
+
srcType.shared.moduleName === 'builtins' &&
|
|
18710
|
+
srcType.priv.typeArgs !== undefined &&
|
|
18711
|
+
srcType.props?.typeForm &&
|
|
18712
|
+
classGetItemReturnsGenericAlias(srcType)) {
|
|
18713
|
+
return true;
|
|
18714
|
+
}
|
|
17781
18715
|
// If the source is a class-like type created by a call to NewType, treat it
|
|
17782
18716
|
// as a FunctionClass instance rather than an instantiable class for
|
|
17783
18717
|
// purposes of assignability. This reflects its actual runtime type.
|
|
@@ -17986,6 +18920,11 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
17986
18920
|
}
|
|
17987
18921
|
return true;
|
|
17988
18922
|
}
|
|
18923
|
+
const isInvariant = (flags & 1 /* AssignTypeFlags.Invariant */) !== 0;
|
|
18924
|
+
srcType = expandEnumTypeForLiteralComparison(srcType, destType, /* concretizeTypeVars */ !isInvariant);
|
|
18925
|
+
if (isInvariant) {
|
|
18926
|
+
destType = expandEnumTypeForLiteralComparison(destType, srcType, /* concretizeTypeVars */ false);
|
|
18927
|
+
}
|
|
17989
18928
|
if ((0, types_1.isUnion)(destType)) {
|
|
17990
18929
|
// If both the source and dest are unions, use assignFromUnionType which has
|
|
17991
18930
|
// special-case logic to handle this case.
|
|
@@ -18094,7 +19033,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
18094
19033
|
if (types_1.ClassType.isBuiltIn(destType, 'TypeForm')) {
|
|
18095
19034
|
const destTypeArg = destType.priv.typeArgs && destType.priv.typeArgs.length > 0
|
|
18096
19035
|
? destType.priv.typeArgs[0]
|
|
18097
|
-
: types_1.
|
|
19036
|
+
: types_1.AnyType.create();
|
|
18098
19037
|
let srcTypeArg;
|
|
18099
19038
|
if ((0, types_1.isClassInstance)(concreteSrcType) && types_1.ClassType.isBuiltIn(concreteSrcType, 'type')) {
|
|
18100
19039
|
srcTypeArg = concreteSrcType;
|
|
@@ -18344,8 +19283,38 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
18344
19283
|
});
|
|
18345
19284
|
return isAssignable;
|
|
18346
19285
|
}
|
|
19286
|
+
function isTypeFormClass(type) {
|
|
19287
|
+
return (types_1.ClassType.isBuiltIn(type, 'TypeForm') ||
|
|
19288
|
+
(types_1.ClassType.isSpecialBuiltIn(type) &&
|
|
19289
|
+
(type.shared.name === 'TypeForm' || type.priv.aliasName === 'TypeForm')));
|
|
19290
|
+
}
|
|
19291
|
+
function isTypeFormType(type) {
|
|
19292
|
+
return (0, types_1.isClassInstance)(type) && isTypeFormClass(type);
|
|
19293
|
+
}
|
|
19294
|
+
function classGetItemReturnsGenericAlias(classType) {
|
|
19295
|
+
const member = (0, typeUtils_1.lookUpClassMember)(classType, '__class_getitem__', 16 /* MemberAccessFlags.SkipInstanceMembers */);
|
|
19296
|
+
if (!member) {
|
|
19297
|
+
return false;
|
|
19298
|
+
}
|
|
19299
|
+
const memberType = getTypeOfMember(member);
|
|
19300
|
+
const functionReturnsGenericAlias = (functionType) => {
|
|
19301
|
+
const returnType = types_1.FunctionType.getEffectiveReturnType(functionType);
|
|
19302
|
+
return !!returnType && (0, types_1.isClassInstance)(returnType) && types_1.ClassType.isBuiltIn(returnType, 'GenericAlias');
|
|
19303
|
+
};
|
|
19304
|
+
if ((0, types_1.isFunction)(memberType)) {
|
|
19305
|
+
return functionReturnsGenericAlias(memberType);
|
|
19306
|
+
}
|
|
19307
|
+
if ((0, types_1.isOverloaded)(memberType)) {
|
|
19308
|
+
return types_1.OverloadedType.getOverloads(memberType).every(functionReturnsGenericAlias);
|
|
19309
|
+
}
|
|
19310
|
+
return false;
|
|
19311
|
+
}
|
|
19312
|
+
function expectedTypeRequiresTypeForm(expectedType) {
|
|
19313
|
+
return ((0, typeUtils_1.someSubtypes)(expectedType, isTypeFormType) &&
|
|
19314
|
+
!(0, typeUtils_1.someSubtypes)(expectedType, (subtype) => !isTypeFormType(subtype)));
|
|
19315
|
+
}
|
|
18347
19316
|
function expectedTypeWantsTypeForm(expectedType) {
|
|
18348
|
-
return (0, typeUtils_1.someSubtypes)(expectedType,
|
|
19317
|
+
return (0, typeUtils_1.someSubtypes)(expectedType, isTypeFormType);
|
|
18349
19318
|
}
|
|
18350
19319
|
// If the expected type is an explicit TypeForm type, see if the source
|
|
18351
19320
|
// type has an implicit TypeForm type that can be assigned to it. If so,
|
|
@@ -18386,9 +19355,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
18386
19355
|
if (resultType || !(0, types_1.isClassInstance)(subtype) || !types_1.ClassType.isBuiltIn(subtype, 'TypeForm')) {
|
|
18387
19356
|
return;
|
|
18388
19357
|
}
|
|
18389
|
-
const destTypeFormType = subtype.priv.typeArgs && subtype.priv.typeArgs.length > 0
|
|
18390
|
-
? subtype.priv.typeArgs[0]
|
|
18391
|
-
: types_1.UnknownType.create();
|
|
19358
|
+
const destTypeFormType = subtype.priv.typeArgs && subtype.priv.typeArgs.length > 0 ? subtype.priv.typeArgs[0] : types_1.AnyType.create();
|
|
18392
19359
|
if (assignType(destTypeFormType, srcTypeFormType)) {
|
|
18393
19360
|
resultType = types_1.ClassType.specialize(subtype, [srcTypeFormType]);
|
|
18394
19361
|
}
|
|
@@ -19657,6 +20624,16 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
19657
20624
|
if ((0, types_1.isUnknown)(assignedSubtype)) {
|
|
19658
20625
|
return assignedSubtype;
|
|
19659
20626
|
}
|
|
20627
|
+
// Preserve assignment narrowing when an enum literal is assigned
|
|
20628
|
+
// to its non-literal enum class. A single-member enum is equivalent
|
|
20629
|
+
// to its only literal, but the assigned value is still more precise.
|
|
20630
|
+
if ((0, types_1.isClassInstance)(assignedSubtype) &&
|
|
20631
|
+
assignedSubtype.priv.literalValue instanceof types_1.EnumLiteral &&
|
|
20632
|
+
(0, types_1.isClassInstance)(declaredSubtype) &&
|
|
20633
|
+
declaredSubtype.priv.literalValue === undefined &&
|
|
20634
|
+
types_1.ClassType.isSameGenericClass(assignedSubtype, declaredSubtype)) {
|
|
20635
|
+
return assignedSubtype;
|
|
20636
|
+
}
|
|
19660
20637
|
// If the two types are bidirectionally assignable, they are
|
|
19661
20638
|
// either equivalent (in which case it doesn't matter which
|
|
19662
20639
|
// one we choose) or one or both include gradual types (Any, etc.),
|
|
@@ -20536,7 +21513,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
20536
21513
|
// expression tree because we don't want to mutate the latter; the
|
|
20537
21514
|
// expression tree created by this function is therefore used only temporarily.
|
|
20538
21515
|
function parseStringAsTypeAnnotation(node, reportErrors) {
|
|
20539
|
-
const fileInfo =
|
|
21516
|
+
const fileInfo = nodeInfo.getFileInfo(node);
|
|
20540
21517
|
const parser = new parser_1.Parser();
|
|
20541
21518
|
const textValue = node.d.strings[0].d.value;
|
|
20542
21519
|
// Determine the offset within the file where the string
|
|
@@ -20554,14 +21531,14 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
20554
21531
|
parseOptions.pythonVersion = fileInfo.executionEnvironment.pythonVersion;
|
|
20555
21532
|
parseOptions.reportErrorsForParsedStringContents = true;
|
|
20556
21533
|
const parseResults = parser.parseTextExpression(dummyFileContents, valueOffset, textValue.length, parseOptions, 0 /* ParseTextMode.Expression */,
|
|
20557
|
-
/* initialParenDepth */ undefined, fileInfo.typingSymbolAliases);
|
|
21534
|
+
/* initialParenDepth */ undefined, fileInfo.typingSymbolAliases, node.a);
|
|
20558
21535
|
if (parseResults.parseTree) {
|
|
20559
21536
|
// If there are errors but we are not reporting them, return
|
|
20560
21537
|
// undefined to indicate that the parse failed.
|
|
20561
21538
|
if (!reportErrors && parseResults.diagnostics.length > 0) {
|
|
20562
21539
|
return undefined;
|
|
20563
21540
|
}
|
|
20564
|
-
const fileInfo =
|
|
21541
|
+
const fileInfo = nodeInfo.getFileInfo(node);
|
|
20565
21542
|
parseResults.diagnostics.forEach((diag) => {
|
|
20566
21543
|
fileInfo.diagnosticSink.addDiagnosticWithTextRange('error', diag.message, node);
|
|
20567
21544
|
});
|
|
@@ -20569,7 +21546,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
20569
21546
|
// Optionally add the new subtree to the parse tree so it can
|
|
20570
21547
|
// participate in language server operations like find and replace.
|
|
20571
21548
|
if (reportErrors) {
|
|
20572
|
-
node.
|
|
21549
|
+
nodeInfo.setStringAnnotation(node, parseResults.parseTree, parseResults.stringAnnotations);
|
|
20573
21550
|
}
|
|
20574
21551
|
return parseResults.parseTree;
|
|
20575
21552
|
}
|
|
@@ -20579,7 +21556,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
20579
21556
|
// var can be "narrowed" to a single one of its constraints based on isinstance
|
|
20580
21557
|
// checks within the code flow.
|
|
20581
21558
|
function narrowConstrainedTypeVar(node, typeVar) {
|
|
20582
|
-
const flowNode =
|
|
21559
|
+
const flowNode = nodeInfo.getFlowNode(node);
|
|
20583
21560
|
if (!flowNode) {
|
|
20584
21561
|
return undefined;
|
|
20585
21562
|
}
|
|
@@ -20589,7 +21566,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
20589
21566
|
return ' '.repeat(printExpressionSpaceCount);
|
|
20590
21567
|
}
|
|
20591
21568
|
function getLineNum(node) {
|
|
20592
|
-
const fileInfo =
|
|
21569
|
+
const fileInfo = nodeInfo.getFileInfo(node);
|
|
20593
21570
|
const range = (0, positionUtils_1.convertOffsetsToRange)(node.start, node.start + node.length, fileInfo.lines);
|
|
20594
21571
|
return (range.start.line + 1).toString();
|
|
20595
21572
|
}
|
|
@@ -20600,6 +21577,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
20600
21577
|
const getInferredReturnTypeResult = wrapWithLogger(_getInferredReturnTypeResult);
|
|
20601
21578
|
const evaluatorInterface = {
|
|
20602
21579
|
runWithCancellationToken,
|
|
21580
|
+
getAnalyzerNodeInfoReader: () => nodeInfo,
|
|
20603
21581
|
getType,
|
|
20604
21582
|
getTypeResult,
|
|
20605
21583
|
getTypeResultForDecorator,
|
|
@@ -20710,7 +21688,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
|
|
|
20710
21688
|
checkForCancellation,
|
|
20711
21689
|
printControlFlowGraph,
|
|
20712
21690
|
};
|
|
20713
|
-
const codeFlowEngine = (0, codeFlowEngine_1.getCodeFlowEngine)(evaluatorInterface, speculativeTypeTracker);
|
|
21691
|
+
const codeFlowEngine = (0, codeFlowEngine_1.getCodeFlowEngine)(evaluatorInterface, speculativeTypeTracker, nodeInfo);
|
|
20714
21692
|
return evaluatorInterface;
|
|
20715
21693
|
}
|
|
20716
21694
|
//# sourceMappingURL=typeEvaluator.js.map
|