diff --git a/packages/pyright-internal/src/analyzer/typeEvaluator.ts b/packages/pyright-internal/src/analyzer/typeEvaluator.ts index 0e5646f77..f1a066a57 100644 --- a/packages/pyright-internal/src/analyzer/typeEvaluator.ts +++ b/packages/pyright-internal/src/analyzer/typeEvaluator.ts @@ -5197,6 +5197,12 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions } } + // If the field was not found and the module type is marked + // such that all fields should be Any/Unknown, return that type. + if (!type && baseType.notPresentFieldType) { + type = baseType.notPresentFieldType; + } + if (!type) { if (!isIncomplete) { addDiagnostic( @@ -20836,8 +20842,13 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions if (lookupResults) { moduleType.fields = lookupResults.symbolTable; moduleType.docString = lookupResults.docString; - } else if (!loaderActions.implicitImports) { - return evaluatorOptions.evaluateUnknownImportsAsAny ? AnyType.create() : UnknownType.create(); + } else { + // Note that all module attributes that are not found in the + // symbol table should be treated as Any or Unknown rather than + // as an error. + moduleType.notPresentFieldType = evaluatorOptions.evaluateUnknownImportsAsAny + ? AnyType.create() + : UnknownType.create(); } } diff --git a/packages/pyright-internal/src/analyzer/types.ts b/packages/pyright-internal/src/analyzer/types.ts index d97d843c1..56a865ebd 100644 --- a/packages/pyright-internal/src/analyzer/types.ts +++ b/packages/pyright-internal/src/analyzer/types.ts @@ -332,6 +332,10 @@ export interface ModuleType extends TypeBase { fields: SymbolTable; docString?: string | undefined; + // If a field lookup isn't found, should the type of the + // resulting field be Any/Unknown or treated as an error? + notPresentFieldType?: AnyType | UnknownType; + // A "loader" module includes symbols that were injected by // the module loader. We keep these separate so we don't // pollute the symbols exported by the module itself.