@zzzen/pyright-internal 1.2.0-dev.20260222 → 1.2.0-dev.20260422

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.
Files changed (219) hide show
  1. package/dist/analyzer/backgroundAnalysisProgram.d.ts +1 -1
  2. package/dist/analyzer/backgroundAnalysisProgram.js +9 -6
  3. package/dist/analyzer/backgroundAnalysisProgram.js.map +1 -1
  4. package/dist/analyzer/binder.d.ts +10 -1
  5. package/dist/analyzer/binder.js +258 -41
  6. package/dist/analyzer/binder.js.map +1 -1
  7. package/dist/analyzer/cellChainIndex.d.ts +34 -0
  8. package/dist/analyzer/cellChainIndex.js +126 -0
  9. package/dist/analyzer/cellChainIndex.js.map +1 -0
  10. package/dist/analyzer/checker.js +0 -1
  11. package/dist/analyzer/checker.js.map +1 -1
  12. package/dist/analyzer/codeFlowEngine.js +16 -1
  13. package/dist/analyzer/codeFlowEngine.js.map +1 -1
  14. package/dist/analyzer/constructors.js +9 -2
  15. package/dist/analyzer/constructors.js.map +1 -1
  16. package/dist/analyzer/importResolver.d.ts +3 -21
  17. package/dist/analyzer/importResolver.js +42 -316
  18. package/dist/analyzer/importResolver.js.map +1 -1
  19. package/dist/analyzer/importResolverFileSystem.d.ts +3 -0
  20. package/dist/analyzer/importResolverFileSystem.js +160 -0
  21. package/dist/analyzer/importResolverFileSystem.js.map +1 -0
  22. package/dist/analyzer/importResolverTypes.d.ts +24 -0
  23. package/dist/analyzer/importResolverTypes.js +8 -0
  24. package/dist/analyzer/importResolverTypes.js.map +1 -0
  25. package/dist/analyzer/importStatementUtils.js +9 -0
  26. package/dist/analyzer/importStatementUtils.js.map +1 -1
  27. package/dist/analyzer/parseTreeUtils.d.ts +1 -0
  28. package/dist/analyzer/parseTreeUtils.js +24 -7
  29. package/dist/analyzer/parseTreeUtils.js.map +1 -1
  30. package/dist/analyzer/patternMatching.js +14 -2
  31. package/dist/analyzer/patternMatching.js.map +1 -1
  32. package/dist/analyzer/program.d.ts +5 -3
  33. package/dist/analyzer/program.js +40 -51
  34. package/dist/analyzer/program.js.map +1 -1
  35. package/dist/analyzer/pythonPathUtils.d.ts +1 -1
  36. package/dist/analyzer/pythonPathUtils.js +3 -1
  37. package/dist/analyzer/pythonPathUtils.js.map +1 -1
  38. package/dist/analyzer/scope.d.ts +10 -1
  39. package/dist/analyzer/scope.js +14 -1
  40. package/dist/analyzer/scope.js.map +1 -1
  41. package/dist/analyzer/service.d.ts +11 -6
  42. package/dist/analyzer/service.js +82 -83
  43. package/dist/analyzer/service.js.map +1 -1
  44. package/dist/analyzer/sourceEnumerator.d.ts +3 -0
  45. package/dist/analyzer/sourceEnumerator.js +27 -1
  46. package/dist/analyzer/sourceEnumerator.js.map +1 -1
  47. package/dist/analyzer/sourceFile.d.ts +2 -1
  48. package/dist/analyzer/sourceFile.js +2 -2
  49. package/dist/analyzer/sourceFile.js.map +1 -1
  50. package/dist/analyzer/sourceFileInfo.d.ts +4 -0
  51. package/dist/analyzer/sourceFileInfo.js +9 -0
  52. package/dist/analyzer/sourceFileInfo.js.map +1 -1
  53. package/dist/analyzer/sourceMapper.d.ts +1 -0
  54. package/dist/analyzer/sourceMapper.js +44 -0
  55. package/dist/analyzer/sourceMapper.js.map +1 -1
  56. package/dist/analyzer/tuples.js +3 -1
  57. package/dist/analyzer/tuples.js.map +1 -1
  58. package/dist/analyzer/typeEvaluator.js +102 -51
  59. package/dist/analyzer/typeEvaluator.js.map +1 -1
  60. package/dist/analyzer/typeEvaluatorTypes.d.ts +2 -0
  61. package/dist/analyzer/typeEvaluatorTypes.js +4 -0
  62. package/dist/analyzer/typeEvaluatorTypes.js.map +1 -1
  63. package/dist/analyzer/typeGuards.js +28 -6
  64. package/dist/analyzer/typeGuards.js.map +1 -1
  65. package/dist/analyzer/typeStubWriter.d.ts +15 -50
  66. package/dist/analyzer/typeStubWriter.js +91 -9
  67. package/dist/analyzer/typeStubWriter.js.map +1 -1
  68. package/dist/analyzer/typeUtils.d.ts +1 -0
  69. package/dist/analyzer/typeUtils.js +27 -3
  70. package/dist/analyzer/typeUtils.js.map +1 -1
  71. package/dist/analyzer/typeshedInfoProvider.d.ts +2 -0
  72. package/dist/analyzer/typeshedInfoProvider.js +232 -0
  73. package/dist/analyzer/typeshedInfoProvider.js.map +1 -0
  74. package/dist/backgroundAnalysisBase.d.ts +3 -3
  75. package/dist/backgroundAnalysisBase.js +12 -9
  76. package/dist/backgroundAnalysisBase.js.map +1 -1
  77. package/dist/commands/createTypeStub.d.ts +16 -8
  78. package/dist/commands/createTypeStub.js +58 -36
  79. package/dist/commands/createTypeStub.js.map +1 -1
  80. package/dist/common/cancellationUtils.d.ts +7 -0
  81. package/dist/common/cancellationUtils.js +34 -0
  82. package/dist/common/cancellationUtils.js.map +1 -1
  83. package/dist/common/collectionUtils.d.ts +3 -3
  84. package/dist/common/collectionUtils.js.map +1 -1
  85. package/dist/common/core.d.ts +1 -1
  86. package/dist/common/core.js.map +1 -1
  87. package/dist/common/crypto.js +11 -0
  88. package/dist/common/crypto.js.map +1 -1
  89. package/dist/common/extensibility.d.ts +7 -0
  90. package/dist/common/extensibility.js.map +1 -1
  91. package/dist/common/fullAccessHost.js +4 -2
  92. package/dist/common/fullAccessHost.js.map +1 -1
  93. package/dist/common/pathUtils.d.ts +4 -1
  94. package/dist/common/pathUtils.js.map +1 -1
  95. package/dist/common/realFileSystem.js +42 -3
  96. package/dist/common/realFileSystem.js.map +1 -1
  97. package/dist/common/serviceKeys.d.ts +3 -0
  98. package/dist/common/serviceKeys.js +2 -0
  99. package/dist/common/serviceKeys.js.map +1 -1
  100. package/dist/common/serviceProviderExtensions.js.map +1 -1
  101. package/dist/common/uri/uriUtils.d.ts +4 -0
  102. package/dist/common/uri/uriUtils.js +19 -3
  103. package/dist/common/uri/uriUtils.js.map +1 -1
  104. package/dist/common/workspaceEditUtils.js +0 -2
  105. package/dist/common/workspaceEditUtils.js.map +1 -1
  106. package/dist/languageServerBase.d.ts +1 -0
  107. package/dist/languageServerBase.js +6 -0
  108. package/dist/languageServerBase.js.map +1 -1
  109. package/dist/languageService/completionProvider.d.ts +6 -0
  110. package/dist/languageService/completionProvider.js +252 -75
  111. package/dist/languageService/completionProvider.js.map +1 -1
  112. package/dist/languageService/definitionProvider.js +1 -1
  113. package/dist/languageService/definitionProvider.js.map +1 -1
  114. package/dist/languageService/documentSymbolCollector.js +34 -4
  115. package/dist/languageService/documentSymbolCollector.js.map +1 -1
  116. package/dist/languageService/dynamicFeature.d.ts +3 -0
  117. package/dist/languageService/dynamicFeature.js +5 -0
  118. package/dist/languageService/dynamicFeature.js.map +1 -1
  119. package/dist/languageService/hoverProvider.d.ts +2 -1
  120. package/dist/languageService/hoverProvider.js +13 -5
  121. package/dist/languageService/hoverProvider.js.map +1 -1
  122. package/dist/languageService/pullDiagnosticsDynamicFeature.d.ts +1 -0
  123. package/dist/languageService/pullDiagnosticsDynamicFeature.js +4 -0
  124. package/dist/languageService/pullDiagnosticsDynamicFeature.js.map +1 -1
  125. package/dist/languageService/referencesProvider.js +5 -4
  126. package/dist/languageService/referencesProvider.js.map +1 -1
  127. package/dist/languageService/signatureHelpProvider.d.ts +1 -0
  128. package/dist/languageService/signatureHelpProvider.js +76 -2
  129. package/dist/languageService/signatureHelpProvider.js.map +1 -1
  130. package/dist/languageService/symbolIndexer.d.ts +1 -0
  131. package/dist/languageService/symbolIndexer.js.map +1 -1
  132. package/dist/languageService/tooltipUtils.d.ts +11 -4
  133. package/dist/languageService/tooltipUtils.js +195 -7
  134. package/dist/languageService/tooltipUtils.js.map +1 -1
  135. package/dist/parser/tokenizer.js +6 -2
  136. package/dist/parser/tokenizer.js.map +1 -1
  137. package/dist/partialStubService.d.ts +11 -0
  138. package/dist/partialStubService.js +23 -1
  139. package/dist/partialStubService.js.map +1 -1
  140. package/dist/pyright.js +13 -2
  141. package/dist/pyright.js.map +1 -1
  142. package/dist/tests/chainedSourceFiles.test.js +138 -0
  143. package/dist/tests/chainedSourceFiles.test.js.map +1 -1
  144. package/dist/tests/checker.test.js +12 -0
  145. package/dist/tests/checker.test.js.map +1 -1
  146. package/dist/tests/completions.test.js +328 -0
  147. package/dist/tests/completions.test.js.map +1 -1
  148. package/dist/tests/config.test.js +54 -0
  149. package/dist/tests/config.test.js.map +1 -1
  150. package/dist/tests/filesystem.test.js +44 -0
  151. package/dist/tests/filesystem.test.js.map +1 -1
  152. package/dist/tests/fourSlashRunner.test.js +1 -1
  153. package/dist/tests/fourSlashRunner.test.js.map +1 -1
  154. package/dist/tests/fourslash/findDefinitions.definitionFilter.preferSource.fourslash.js +25 -1
  155. package/dist/tests/fourslash/findDefinitions.definitionFilter.preferSource.fourslash.js.map +1 -1
  156. package/dist/tests/fourslash/import.multipart3.fourslash.d.ts +1 -0
  157. package/dist/tests/fourslash/import.multipart3.fourslash.js +46 -0
  158. package/dist/tests/fourslash/import.multipart3.fourslash.js.map +1 -0
  159. package/dist/tests/fourslash/import.pytyped.unsupportedDunderAll.fourslash.d.ts +1 -0
  160. package/dist/tests/fourslash/import.pytyped.unsupportedDunderAll.fourslash.js +33 -0
  161. package/dist/tests/fourslash/import.pytyped.unsupportedDunderAll.fourslash.js.map +1 -0
  162. package/dist/tests/harness/fourslash/runner.d.ts +4 -4
  163. package/dist/tests/harness/fourslash/runner.js +5 -5
  164. package/dist/tests/harness/fourslash/runner.js.map +1 -1
  165. package/dist/tests/harness/fourslash/testState.d.ts +20 -5
  166. package/dist/tests/harness/fourslash/testState.js +11 -26
  167. package/dist/tests/harness/fourslash/testState.js.map +1 -1
  168. package/dist/tests/harness/fourslash/testStateUtils.js +2 -0
  169. package/dist/tests/harness/fourslash/testStateUtils.js.map +1 -1
  170. package/dist/tests/harness/testAccessHost.d.ts +3 -1
  171. package/dist/tests/harness/testAccessHost.js +6 -2
  172. package/dist/tests/harness/testAccessHost.js.map +1 -1
  173. package/dist/tests/harness/testHost.js +20 -18
  174. package/dist/tests/harness/testHost.js.map +1 -1
  175. package/dist/tests/harness/vfs/factory.js +4 -1
  176. package/dist/tests/harness/vfs/factory.js.map +1 -1
  177. package/dist/tests/harness/vfs/filesystem.d.ts +8 -1
  178. package/dist/tests/harness/vfs/filesystem.js +84 -30
  179. package/dist/tests/harness/vfs/filesystem.js.map +1 -1
  180. package/dist/tests/hoverProvider.test.js +290 -0
  181. package/dist/tests/hoverProvider.test.js.map +1 -1
  182. package/dist/tests/importResolverSupport.test.d.ts +1 -0
  183. package/dist/tests/importResolverSupport.test.js +319 -0
  184. package/dist/tests/importResolverSupport.test.js.map +1 -0
  185. package/dist/tests/importStatementUtils.test.js +66 -0
  186. package/dist/tests/importStatementUtils.test.js.map +1 -1
  187. package/dist/tests/lsp/{webpack.testserver.config.d.ts → rspack.testserver.config.d.ts} +1 -1
  188. package/dist/tests/lsp/{webpack.testserver.config.js → rspack.testserver.config.js} +4 -11
  189. package/dist/tests/lsp/rspack.testserver.config.js.map +1 -0
  190. package/dist/tests/realTempFile.test.d.ts +1 -0
  191. package/dist/tests/realTempFile.test.js +144 -0
  192. package/dist/tests/realTempFile.test.js.map +1 -0
  193. package/dist/tests/service.test.js +182 -3
  194. package/dist/tests/service.test.js.map +1 -1
  195. package/dist/tests/signatureHelp.test.js +391 -6
  196. package/dist/tests/signatureHelp.test.js.map +1 -1
  197. package/dist/tests/testState.test.js +19 -0
  198. package/dist/tests/testState.test.js.map +1 -1
  199. package/dist/tests/tokenizer.test.js +42 -0
  200. package/dist/tests/tokenizer.test.js.map +1 -1
  201. package/dist/tests/typeEvaluator1.test.js +4 -0
  202. package/dist/tests/typeEvaluator1.test.js.map +1 -1
  203. package/dist/tests/typeEvaluator2.test.js +12 -0
  204. package/dist/tests/typeEvaluator2.test.js.map +1 -1
  205. package/dist/tests/typeEvaluator3.test.js +8 -1
  206. package/dist/tests/typeEvaluator3.test.js.map +1 -1
  207. package/dist/tests/typeEvaluator6.test.js +7 -0
  208. package/dist/tests/typeEvaluator6.test.js.map +1 -1
  209. package/dist/tests/typeEvaluator8.test.js +13 -1
  210. package/dist/tests/typeEvaluator8.test.js.map +1 -1
  211. package/dist/tests/uri.test.js +29 -0
  212. package/dist/tests/uri.test.js.map +1 -1
  213. package/dist/tests/wildcardImportPackageMerge.test.d.ts +1 -0
  214. package/dist/tests/wildcardImportPackageMerge.test.js +97 -0
  215. package/dist/tests/wildcardImportPackageMerge.test.js.map +1 -0
  216. package/dist/tests/workspaceEditUtils.test.js +0 -1
  217. package/dist/tests/workspaceEditUtils.test.js.map +1 -1
  218. package/package.json +12 -11
  219. package/dist/tests/lsp/webpack.testserver.config.js.map +0 -1
@@ -373,7 +373,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
373
373
  }
374
374
  function popSymbolResolution(symbol) {
375
375
  const poppedEntry = symbolResolutionStack.pop();
376
- (0, debug_1.assert)(poppedEntry.symbolId === symbol.id);
376
+ (0, debug_1.assert)(poppedEntry !== undefined && poppedEntry.symbolId === symbol.id, `Symbol resolution stack mismatch: expected symbol ${symbol.id}, got ${poppedEntry?.symbolId ?? 'empty stack'}`);
377
377
  return poppedEntry.isResultValid;
378
378
  }
379
379
  function setSymbolResolutionPartialType(symbol, declaration, type) {
@@ -471,8 +471,9 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
471
471
  const expectedType = expectedTypeCache.get(curNode.id);
472
472
  if (expectedType) {
473
473
  return {
474
- type: expectedType,
474
+ type: expectedType.type,
475
475
  node: curNode,
476
+ candidates: (0, typeEvaluatorTypes_1.ensureExpectedTypeCandidates)(expectedType.type, expectedType.candidates),
476
477
  };
477
478
  }
478
479
  if (curNode === topExpression) {
@@ -482,6 +483,20 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
482
483
  }
483
484
  return undefined;
484
485
  }
486
+ function addExpectedTypeCacheEntry(node, expectedType) {
487
+ const cached = expectedTypeCache.get(node.id);
488
+ if (!cached) {
489
+ expectedTypeCache.set(node.id, {
490
+ type: expectedType,
491
+ candidates: [expectedType],
492
+ });
493
+ return;
494
+ }
495
+ cached.type = expectedType;
496
+ if (!cached.candidates.some((candidate) => (0, types_1.isTypeSame)(candidate, expectedType))) {
497
+ cached.candidates.push(expectedType);
498
+ }
499
+ }
485
500
  function initializePrefetchedTypes(node) {
486
501
  if (!prefetched) {
487
502
  // Some of these types have cyclical dependencies on each other,
@@ -614,7 +629,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
614
629
  if (inferenceContext &&
615
630
  !(0, types_1.isAnyOrUnknown)(inferenceContext.expectedType) &&
616
631
  !(0, types_1.isNever)(inferenceContext.expectedType)) {
617
- expectedTypeCache.set(node.id, inferenceContext.expectedType);
632
+ addExpectedTypeCacheEntry(node, inferenceContext.expectedType);
618
633
  if (!typeResult.isIncomplete && !typeResult.expectedTypeDiagAddendum) {
619
634
  const diag = new diagnostic_1.DiagnosticAddendum();
620
635
  // Make sure the resulting type is assignable to the expected type.
@@ -9810,7 +9825,18 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
9810
9825
  return result;
9811
9826
  }
9812
9827
  }
9813
- const result = getTypeOfDictionaryInferred(node, flags, /* hasExpectedType */ !!inferenceContext?.expectedType);
9828
+ // Don't force strict inference when the expected type is a TypeVar that
9829
+ // couldn't constrain the dict's key/value structure. A TypeVar like _T
9830
+ // from sorted(Iterable[_T], key=...) doesn't provide useful type
9831
+ // information for dict inference, and forcing strict inference would
9832
+ // widen heterogeneous value types into a union that can cause false
9833
+ // positives (e.g., dict[str, Path | str | dict[Any, Any]] when the
9834
+ // user meant each key to have a specific type).
9835
+ // Note: bounded/constrained TypeVars with dict-like bounds are handled
9836
+ // by getTypeOfDictionaryWithContext above (via makeTopLevelTypeVarsConcrete),
9837
+ // so they don't reach this fallback.
9838
+ const hasUsefulExpectedType = !!inferenceContext?.expectedType && !(0, types_1.isTypeVar)(inferenceContext.expectedType);
9839
+ const result = getTypeOfDictionaryInferred(node, flags, /* hasExpectedType */ hasUsefulExpectedType);
9814
9840
  return { ...result, expectedTypeDiagAddendum };
9815
9841
  }
9816
9842
  function getTypeOfDictionaryWithContext(node, flags, inferenceContext, expectedDiagAddendum) {
@@ -13883,6 +13909,13 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
13883
13909
  });
13884
13910
  // Do not retain TypeForm types in inferred return types.
13885
13911
  returnType = (0, typeUtils_1.stripTypeForm)(returnType);
13912
+ // If we're returning a function value (or overload), force
13913
+ // lazy return-type inference before caching this function's
13914
+ // inferred return. Without this, a partially evaluated
13915
+ // function can leak a temporary Any return type (for example,
13916
+ // immediately after an edit), and that Any then gets cached
13917
+ // as though it were final for the enclosing function.
13918
+ inferReturnTypeIfNecessary(returnType);
13886
13919
  inferredReturnTypes.push(returnType);
13887
13920
  }
13888
13921
  else {
@@ -15482,7 +15515,10 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
15482
15515
  function lookUpSymbolRecursive(node, name, honorCodeFlow, preferGlobalScope = false) {
15483
15516
  const scopeNodeInfo = ParseTreeUtils.getEvaluationScopeNode(node);
15484
15517
  const scope = AnalyzerNodeInfo.getScope(scopeNodeInfo.node);
15485
- let symbolWithScope = scope?.lookUpSymbolRecursive(name, { useProxyScope: !!scopeNodeInfo.useProxyScope });
15518
+ let symbolWithScope = scope?.lookUpSymbolRecursive(name, {
15519
+ useProxyScope: !!scopeNodeInfo.useProxyScope,
15520
+ useChainedModuleLevelScopes: !!scopeNodeInfo.useChainedModuleLevelScopes,
15521
+ });
15486
15522
  const scopeType = scope?.type ?? 4 /* ScopeType.Module */;
15487
15523
  // Functions and list comprehensions don't allow access to implicitly
15488
15524
  // aliased symbols in outer scopes if they haven't yet been assigned
@@ -15715,6 +15751,36 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
15715
15751
  }
15716
15752
  return undefined;
15717
15753
  }
15754
+ function _shouldFallBackToClassEntryForKeywordArg(baseType, paramName) {
15755
+ return (types_1.ClassType.isDataClass(baseType) ||
15756
+ types_1.ClassType.isTypedDictClass(baseType) ||
15757
+ types_1.ClassType.hasNamedTupleEntry(baseType, paramName));
15758
+ }
15759
+ function _addSymbolDeclInfo(symbol, decls, synthesizedTypes, preferTypedDeclarations = false) {
15760
+ const declCountBeforeAdd = decls.length;
15761
+ const typedDecls = preferTypedDeclarations ? symbol.getTypedDeclarations() : undefined;
15762
+ (0, collectionUtils_1.appendArray)(decls, typedDecls?.length ? typedDecls : symbol.getDeclarations());
15763
+ const synthTypeInfo = symbol.getSynthesizedType();
15764
+ if (synthTypeInfo) {
15765
+ synthesizedTypes.push(synthTypeInfo);
15766
+ // Some module members are represented only by a synthesized module type,
15767
+ // with no concrete declaration node to navigate to. Synthesize a matching
15768
+ // alias declaration so definition/declaration/reference features can still
15769
+ // bind to the submodule's file.
15770
+ if (decls.length === declCountBeforeAdd &&
15771
+ (0, types_1.isModule)(synthTypeInfo.type) &&
15772
+ !synthTypeInfo.type.priv.fileUri.isEmpty()) {
15773
+ decls.push((0, declarationUtils_1.synthesizeAliasDeclaration)(synthTypeInfo.type.priv.fileUri));
15774
+ }
15775
+ }
15776
+ }
15777
+ function _addClassEntryDeclsForKeywordArgIfPresent(baseType, paramName, decls, synthesizedTypes) {
15778
+ const lookupResults = (0, typeUtils_1.lookUpClassMember)(baseType, paramName);
15779
+ if (!lookupResults) {
15780
+ return;
15781
+ }
15782
+ _addSymbolDeclInfo(lookupResults.symbol, decls, synthesizedTypes);
15783
+ }
15718
15784
  // In general, string nodes don't have any declarations associated with them, but
15719
15785
  // we need to handle the special case of string literals used as keys within a
15720
15786
  // dictionary expression where those keys are associated with a known TypedDict.
@@ -15733,11 +15799,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
15733
15799
  if (entry) {
15734
15800
  const symbol = (0, typeUtils_1.lookUpObjectMember)(subtype, node.d.value)?.symbol;
15735
15801
  if (symbol) {
15736
- (0, collectionUtils_1.appendArray)(decls, symbol.getDeclarations());
15737
- const synthTypeInfo = symbol.getSynthesizedType();
15738
- if (synthTypeInfo) {
15739
- synthesizedTypes.push(synthTypeInfo);
15740
- }
15802
+ _addSymbolDeclInfo(symbol, decls, synthesizedTypes);
15741
15803
  }
15742
15804
  }
15743
15805
  }
@@ -15824,17 +15886,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
15824
15886
  // By default, report only the declarations that have type annotations.
15825
15887
  // If there are none, then report all of the unannotated declarations,
15826
15888
  // which includes every assignment of that symbol.
15827
- const typedDecls = symbol.getTypedDeclarations();
15828
- if (typedDecls.length > 0) {
15829
- (0, collectionUtils_1.appendArray)(decls, typedDecls);
15830
- }
15831
- else {
15832
- (0, collectionUtils_1.appendArray)(decls, symbol.getDeclarations());
15833
- }
15834
- const synthTypeInfo = symbol.getSynthesizedType();
15835
- if (synthTypeInfo) {
15836
- synthesizedTypes.push(synthTypeInfo);
15837
- }
15889
+ _addSymbolDeclInfo(symbol, decls, synthesizedTypes, /* preferTypedDeclarations */ true);
15838
15890
  }
15839
15891
  });
15840
15892
  }
@@ -15884,34 +15936,16 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
15884
15936
  if (paramDecl) {
15885
15937
  decls.push(paramDecl);
15886
15938
  }
15887
- else if (types_1.ClassType.isDataClass(baseType) ||
15888
- types_1.ClassType.isTypedDictClass(baseType) ||
15889
- types_1.ClassType.hasNamedTupleEntry(baseType, paramName)) {
15890
- const lookupResults = (0, typeUtils_1.lookUpClassMember)(baseType, paramName);
15891
- if (lookupResults) {
15892
- (0, collectionUtils_1.appendArray)(decls, lookupResults.symbol.getDeclarations());
15893
- const synthTypeInfo = lookupResults.symbol.getSynthesizedType();
15894
- if (synthTypeInfo) {
15895
- synthesizedTypes.push(synthTypeInfo);
15896
- }
15897
- }
15939
+ else if (_shouldFallBackToClassEntryForKeywordArg(baseType, paramName)) {
15940
+ _addClassEntryDeclsForKeywordArgIfPresent(baseType, paramName, decls, synthesizedTypes);
15898
15941
  }
15899
15942
  }
15900
- else if (types_1.ClassType.isDataClass(baseType) ||
15901
- types_1.ClassType.isTypedDictClass(baseType) ||
15902
- types_1.ClassType.hasNamedTupleEntry(baseType, paramName)) {
15943
+ else if (_shouldFallBackToClassEntryForKeywordArg(baseType, paramName)) {
15903
15944
  // Some synthesized callables (notably TypedDict "constructors") don't have a
15904
15945
  // meaningful __init__ signature we can map keyword arguments to. In these cases,
15905
15946
  // treat the keyword as referring to the class entry so IDE features like
15906
15947
  // go-to-definition and rename can bind to the field declaration.
15907
- const lookupResults = (0, typeUtils_1.lookUpClassMember)(baseType, paramName);
15908
- if (lookupResults) {
15909
- (0, collectionUtils_1.appendArray)(decls, lookupResults.symbol.getDeclarations());
15910
- const synthTypeInfo = lookupResults.symbol.getSynthesizedType();
15911
- if (synthTypeInfo) {
15912
- synthesizedTypes.push(synthTypeInfo);
15913
- }
15914
- }
15948
+ _addClassEntryDeclsForKeywordArgIfPresent(baseType, paramName, decls, synthesizedTypes);
15915
15949
  }
15916
15950
  }
15917
15951
  }
@@ -15934,11 +15968,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
15934
15968
  const allowForwardReferences = isWithinTypeAnnotation || isWithinTypeAliasStatement || fileInfo.isStubFile;
15935
15969
  const symbolWithScope = lookUpSymbolRecursive(node, node.d.value, !allowForwardReferences, isWithinTypeAnnotation);
15936
15970
  if (symbolWithScope) {
15937
- (0, collectionUtils_1.appendArray)(decls, symbolWithScope.symbol.getDeclarations());
15938
- const synthTypeInfo = symbolWithScope.symbol.getSynthesizedType();
15939
- if (synthTypeInfo) {
15940
- synthesizedTypes.push(synthTypeInfo);
15941
- }
15971
+ _addSymbolDeclInfo(symbolWithScope.symbol, decls, synthesizedTypes);
15942
15972
  }
15943
15973
  }
15944
15974
  return { decls, synthesizedTypes };
@@ -16619,7 +16649,19 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
16619
16649
  const usageScope = ParseTreeUtils.getExecutionScopeNode(usageNode);
16620
16650
  const declScope = ParseTreeUtils.getExecutionScopeNode(decl.node);
16621
16651
  if (usageScope === declScope) {
16622
- if (!isFlowPathBetweenNodes(decl.node, usageNode)) {
16652
+ // Skip declarations that appear after the usage in the source.
16653
+ // Such declarations are typically only reached via loop back-edges,
16654
+ // and including them causes circular evaluation (producing Unknown).
16655
+ // Declarations that textually precede the usage are retained so
16656
+ // that order-independent type aliases resolve correctly; for
16657
+ // branching constructs (if/else, try/except), a retained
16658
+ // declaration may be flow-unreachable at the usage site, but the
16659
+ // code-flow engine overrides the effective type for local
16660
+ // variables, so the narrowed type at the usage site is correct.
16661
+ // Note: for the cases filtered out here (decl after usage in same
16662
+ // scope), the code-flow engine handles loop-carried narrowing when
16663
+ // it evaluates the type at the actual usage site.
16664
+ if (decl.node.start >= usageNode.start) {
16623
16665
  return;
16624
16666
  }
16625
16667
  }
@@ -16670,11 +16712,13 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
16670
16712
  let includesSpeculativeResult = false;
16671
16713
  decls.forEach((decl) => {
16672
16714
  if (pushSymbolResolution(symbol, decl)) {
16715
+ let symbolPopped = false;
16673
16716
  try {
16674
16717
  let type = getInferredTypeOfDeclaration(symbol, decl);
16675
16718
  if (!popSymbolResolution(symbol)) {
16676
16719
  isIncomplete = true;
16677
16720
  }
16721
+ symbolPopped = true;
16678
16722
  if (type) {
16679
16723
  if (decl.type === 1 /* DeclarationType.Variable */) {
16680
16724
  let isConstant = false;
@@ -16707,8 +16751,10 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
16707
16751
  }
16708
16752
  }
16709
16753
  catch (e) {
16710
- // Clean up the stack before rethrowing.
16711
- popSymbolResolution(symbol);
16754
+ // Clean up the stack before rethrowing, but only if we haven't already popped.
16755
+ if (!symbolPopped) {
16756
+ popSymbolResolution(symbol);
16757
+ }
16712
16758
  throw e;
16713
16759
  }
16714
16760
  }
@@ -16792,6 +16838,11 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
16792
16838
  const usageScope = ParseTreeUtils.getExecutionScopeNode(usageNode);
16793
16839
  const declScope = ParseTreeUtils.getExecutionScopeNode(decl.node);
16794
16840
  if (usageScope === declScope) {
16841
+ // For typed declarations we use the precise flow-graph reachability
16842
+ // check rather than a simple position comparison, because typed decls
16843
+ // (e.g. explicit annotations) can legitimately appear after the usage
16844
+ // in the source text (e.g. a class attribute annotated below a method
16845
+ // that references it) and must not be excluded by position alone.
16795
16846
  if (!isFlowPathBetweenNodes(decl.node, usageNode, /* allowSelf */ false)) {
16796
16847
  return false;
16797
16848
  }