From 0902b66031dc13af23ad9666abc4d3fd94029aba Mon Sep 17 00:00:00 2001 From: Wizzerinus Date: Fri, 27 Dec 2024 10:25:54 +0300 Subject: [PATCH] feat: implemented allowed-untyped-libraries resolves #701 --- .../src/analyzer/typeEvaluator.ts | 8 ++++++ packages/pyright-internal/src/baseline.ts | 3 +- .../src/common/configOptions.ts | 28 +++++++++++++++++++ 3 files changed, 38 insertions(+), 1 deletion(-) diff --git a/packages/pyright-internal/src/analyzer/typeEvaluator.ts b/packages/pyright-internal/src/analyzer/typeEvaluator.ts index 9e0d3a3e6..8687cb918 100644 --- a/packages/pyright-internal/src/analyzer/typeEvaluator.ts +++ b/packages/pyright-internal/src/analyzer/typeEvaluator.ts @@ -15127,6 +15127,14 @@ export function createTypeEvaluator( return; } + // Or if the object is in an untyped library that was explicitly mentioned. + if (type.shared && "moduleName" in type.shared) { + const moduleName = type.shared.moduleName; + if (ruleset.allowedUntypedLibraries.indexOf(moduleName) > -1) { + return; + } + } + const nameValue = target.d.value; // Sometimes variables contain an "unbound" type if they're diff --git a/packages/pyright-internal/src/baseline.ts b/packages/pyright-internal/src/baseline.ts index 689ed1e61..77dfd6470 100644 --- a/packages/pyright-internal/src/baseline.ts +++ b/packages/pyright-internal/src/baseline.ts @@ -273,7 +273,8 @@ export class BaselineHandler { files: {}, }; for (const fileWithDiagnostics of filesWithDiagnostics) { - const filePath = this.configOptions.projectRoot.getRelativePath(fileWithDiagnostics.fileUri)!.toString(); + const filePath = this.configOptions.projectRoot.getRelativePath(fileWithDiagnostics.fileUri)?.toString(); + if (filePath === undefined) continue; const errorDiagnostics = fileWithDiagnostics.diagnostics.filter( (diagnostic) => diagnostic.category !== DiagnosticCategory.Hint || diagnostic.baselined ); diff --git a/packages/pyright-internal/src/common/configOptions.ts b/packages/pyright-internal/src/common/configOptions.ts index fb7795579..2903175fb 100644 --- a/packages/pyright-internal/src/common/configOptions.ts +++ b/packages/pyright-internal/src/common/configOptions.ts @@ -423,6 +423,9 @@ export interface DiagnosticRuleSet { reportUnusedParameter: DiagnosticLevel; reportImplicitAbstractClass: DiagnosticLevel; reportUnannotatedClassAttribute: DiagnosticLevel; + + // What libraries' functions can be called even if they aren't typed? + allowedUntypedLibraries: String[]; } export function cloneDiagnosticRuleSet(diagSettings: DiagnosticRuleSet): DiagnosticRuleSet { @@ -687,6 +690,7 @@ export function getOffDiagnosticRuleSet(): DiagnosticRuleSet { reportUnusedParameter: 'hint', reportImplicitAbstractClass: 'none', reportUnannotatedClassAttribute: 'none', + allowedUntypedLibraries: [], }; return diagSettings; @@ -803,6 +807,7 @@ export function getBasicDiagnosticRuleSet(): DiagnosticRuleSet { reportUnusedParameter: 'hint', reportImplicitAbstractClass: 'none', reportUnannotatedClassAttribute: 'none', + allowedUntypedLibraries: [], }; return diagSettings; @@ -919,6 +924,7 @@ export function getStandardDiagnosticRuleSet(): DiagnosticRuleSet { reportUnusedParameter: 'hint', reportImplicitAbstractClass: 'none', reportUnannotatedClassAttribute: 'none', + allowedUntypedLibraries: [], }; return diagSettings; @@ -1034,6 +1040,7 @@ export const getRecommendedDiagnosticRuleSet = (): DiagnosticRuleSet => ({ reportUnusedParameter: 'warning', reportImplicitAbstractClass: 'warning', reportUnannotatedClassAttribute: 'warning', + allowedUntypedLibraries: [], }); export const getAllDiagnosticRuleSet = (): DiagnosticRuleSet => ({ @@ -1146,6 +1153,7 @@ export const getAllDiagnosticRuleSet = (): DiagnosticRuleSet => ({ reportUnusedParameter: 'error', reportImplicitAbstractClass: 'error', reportUnannotatedClassAttribute: 'error', + allowedUntypedLibraries: [], }); export function getStrictDiagnosticRuleSet(): DiagnosticRuleSet { @@ -1259,6 +1267,7 @@ export function getStrictDiagnosticRuleSet(): DiagnosticRuleSet { reportUnusedParameter: 'hint', reportImplicitAbstractClass: 'none', reportUnannotatedClassAttribute: 'none', + allowedUntypedLibraries: [], }; return diagSettings; @@ -1601,6 +1610,25 @@ export class ConfigOptions { console ); }); + + // Read the config "allowedUntypedLibraries". + const allowedUntypedLibraries: String[] = []; + if (configObj.allowedUntypedLibraries !== undefined) { + if (!Array.isArray(configObj.allowedUntypedLibraries)) { + console.error(`Config "allowedUntypedLibraries" field must contain an array.`); + } else { + const pathList = configObj.allowedUntypedLibraries as string[]; + pathList.forEach((lib, libIndex) => { + if (typeof lib !== 'string') { + console.error(`Config "allowedUntypedLibraries" field ${libIndex} must be a string.`); + } else { + allowedUntypedLibraries!.push(lib); + } + }); + configRuleSet.allowedUntypedLibraries = allowedUntypedLibraries; + } + } + this.diagnosticRuleSet = { ...configRuleSet }; // Read the "venvPath".