@zzzen/pyright-internal 1.2.0-dev.20230423 → 1.2.0-dev.20230507

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 (260) hide show
  1. package/dist/analyzer/analyzerFileInfo.d.ts +4 -1
  2. package/dist/analyzer/analyzerFileInfo.js.map +1 -1
  3. package/dist/analyzer/backgroundAnalysisProgram.d.ts +7 -4
  4. package/dist/analyzer/backgroundAnalysisProgram.js +22 -7
  5. package/dist/analyzer/backgroundAnalysisProgram.js.map +1 -1
  6. package/dist/analyzer/binder.js +12 -7
  7. package/dist/analyzer/binder.js.map +1 -1
  8. package/dist/analyzer/checker.d.ts +1 -0
  9. package/dist/analyzer/checker.js +58 -7
  10. package/dist/analyzer/checker.js.map +1 -1
  11. package/dist/analyzer/constructors.d.ts +6 -0
  12. package/dist/analyzer/constructors.js +456 -0
  13. package/dist/analyzer/constructors.js.map +1 -0
  14. package/dist/analyzer/dataClasses.js +89 -2
  15. package/dist/analyzer/dataClasses.js.map +1 -1
  16. package/dist/analyzer/declarationUtils.d.ts +6 -1
  17. package/dist/analyzer/declarationUtils.js +10 -8
  18. package/dist/analyzer/declarationUtils.js.map +1 -1
  19. package/dist/analyzer/enums.js +54 -8
  20. package/dist/analyzer/enums.js.map +1 -1
  21. package/dist/analyzer/importResolver.d.ts +15 -15
  22. package/dist/analyzer/importResolver.js +477 -477
  23. package/dist/analyzer/importResolver.js.map +1 -1
  24. package/dist/analyzer/importStatementUtils.d.ts +2 -2
  25. package/dist/analyzer/importStatementUtils.js.map +1 -1
  26. package/dist/analyzer/namedTuples.d.ts +1 -1
  27. package/dist/analyzer/namedTuples.js +30 -42
  28. package/dist/analyzer/namedTuples.js.map +1 -1
  29. package/dist/analyzer/operations.d.ts +16 -0
  30. package/dist/analyzer/operations.js +749 -0
  31. package/dist/analyzer/operations.js.map +1 -0
  32. package/dist/analyzer/packageTypeReport.d.ts +2 -1
  33. package/dist/analyzer/packageTypeReport.js +2 -1
  34. package/dist/analyzer/packageTypeReport.js.map +1 -1
  35. package/dist/analyzer/packageTypeVerifier.d.ts +1 -1
  36. package/dist/analyzer/packageTypeVerifier.js +27 -13
  37. package/dist/analyzer/packageTypeVerifier.js.map +1 -1
  38. package/dist/analyzer/parseTreeUtils.d.ts +4 -2
  39. package/dist/analyzer/parseTreeUtils.js +32 -1
  40. package/dist/analyzer/parseTreeUtils.js.map +1 -1
  41. package/dist/analyzer/patternMatching.js +16 -0
  42. package/dist/analyzer/patternMatching.js.map +1 -1
  43. package/dist/analyzer/program.d.ts +29 -53
  44. package/dist/analyzer/program.js +1050 -1649
  45. package/dist/analyzer/program.js.map +1 -1
  46. package/dist/analyzer/protocols.js +1 -1
  47. package/dist/analyzer/protocols.js.map +1 -1
  48. package/dist/analyzer/service.d.ts +14 -35
  49. package/dist/analyzer/service.js +92 -121
  50. package/dist/analyzer/service.js.map +1 -1
  51. package/dist/analyzer/sourceFile.d.ts +14 -49
  52. package/dist/analyzer/sourceFile.js +271 -291
  53. package/dist/analyzer/sourceFile.js.map +1 -1
  54. package/dist/analyzer/sourceFileInfoUtils.d.ts +2 -2
  55. package/dist/analyzer/sourceFileInfoUtils.js.map +1 -1
  56. package/dist/analyzer/typeEvaluator.js +417 -1570
  57. package/dist/analyzer/typeEvaluator.js.map +1 -1
  58. package/dist/analyzer/typeEvaluatorTypes.d.ts +44 -9
  59. package/dist/analyzer/typeEvaluatorTypes.js +33 -1
  60. package/dist/analyzer/typeEvaluatorTypes.js.map +1 -1
  61. package/dist/analyzer/typeGuards.js +5 -9
  62. package/dist/analyzer/typeGuards.js.map +1 -1
  63. package/dist/analyzer/typeStubWriter.js.map +1 -1
  64. package/dist/analyzer/typeUtils.d.ts +3 -0
  65. package/dist/analyzer/typeUtils.js +66 -9
  66. package/dist/analyzer/typeUtils.js.map +1 -1
  67. package/dist/analyzer/typeVarContext.d.ts +5 -5
  68. package/dist/analyzer/typeVarContext.js +7 -0
  69. package/dist/analyzer/typeVarContext.js.map +1 -1
  70. package/dist/analyzer/typedDicts.js +2 -2
  71. package/dist/analyzer/typedDicts.js.map +1 -1
  72. package/dist/analyzer/types.d.ts +4 -2
  73. package/dist/analyzer/types.js +7 -0
  74. package/dist/analyzer/types.js.map +1 -1
  75. package/dist/backgroundAnalysisBase.d.ts +10 -11
  76. package/dist/backgroundAnalysisBase.js +87 -87
  77. package/dist/backgroundAnalysisBase.js.map +1 -1
  78. package/dist/commands/dumpFileDebugInfoCommand.js +8 -8
  79. package/dist/commands/dumpFileDebugInfoCommand.js.map +1 -1
  80. package/dist/commands/quickActionCommand.js +4 -1
  81. package/dist/commands/quickActionCommand.js.map +1 -1
  82. package/dist/common/cancellationUtils.d.ts +1 -1
  83. package/dist/common/cancellationUtils.js +9 -9
  84. package/dist/common/cancellationUtils.js.map +1 -1
  85. package/dist/common/commandLineOptions.d.ts +1 -2
  86. package/dist/common/commandLineOptions.js.map +1 -1
  87. package/dist/common/configOptions.d.ts +2 -2
  88. package/dist/common/configOptions.js.map +1 -1
  89. package/dist/common/console.d.ts +5 -9
  90. package/dist/common/console.js +46 -33
  91. package/dist/common/console.js.map +1 -1
  92. package/dist/common/deferred.js +10 -10
  93. package/dist/common/deferred.js.map +1 -1
  94. package/dist/common/extensibility.d.ts +27 -5
  95. package/dist/common/extensibility.js +1 -1
  96. package/dist/common/extensibility.js.map +1 -1
  97. package/dist/common/fileBasedCancellationUtils.js +5 -5
  98. package/dist/common/fileBasedCancellationUtils.js.map +1 -1
  99. package/dist/common/fileSystem.d.ts +12 -10
  100. package/dist/common/fileSystem.js.map +1 -1
  101. package/dist/common/fullAccessHost.d.ts +3 -3
  102. package/dist/common/fullAccessHost.js +6 -6
  103. package/dist/common/fullAccessHost.js.map +1 -1
  104. package/dist/common/pathUtils.d.ts +13 -13
  105. package/dist/common/pathUtils.js.map +1 -1
  106. package/dist/common/realFileSystem.js +12 -7
  107. package/dist/common/realFileSystem.js.map +1 -1
  108. package/dist/common/uriParser.d.ts +2 -2
  109. package/dist/common/uriParser.js +3 -3
  110. package/dist/common/uriParser.js.map +1 -1
  111. package/dist/common/workspaceEditUtils.d.ts +5 -5
  112. package/dist/common/workspaceEditUtils.js +7 -4
  113. package/dist/common/workspaceEditUtils.js.map +1 -1
  114. package/dist/languageServerBase.d.ts +32 -31
  115. package/dist/languageServerBase.js +278 -345
  116. package/dist/languageServerBase.js.map +1 -1
  117. package/dist/languageService/analyzerServiceExecutor.js +0 -1
  118. package/dist/languageService/analyzerServiceExecutor.js.map +1 -1
  119. package/dist/languageService/callHierarchyProvider.d.ts +16 -12
  120. package/dist/languageService/callHierarchyProvider.js +125 -41
  121. package/dist/languageService/callHierarchyProvider.js.map +1 -1
  122. package/dist/languageService/completionProvider.d.ts +10 -13
  123. package/dist/languageService/completionProvider.js +21 -10
  124. package/dist/languageService/completionProvider.js.map +1 -1
  125. package/dist/languageService/definitionProvider.d.ts +23 -9
  126. package/dist/languageService/definitionProvider.js +116 -91
  127. package/dist/languageService/definitionProvider.js.map +1 -1
  128. package/dist/languageService/documentHighlightProvider.d.ts +8 -3
  129. package/dist/languageService/documentHighlightProvider.js +17 -6
  130. package/dist/languageService/documentHighlightProvider.js.map +1 -1
  131. package/dist/languageService/documentSymbolCollector.d.ts +6 -7
  132. package/dist/languageService/documentSymbolCollector.js +21 -11
  133. package/dist/languageService/documentSymbolCollector.js.map +1 -1
  134. package/dist/languageService/documentSymbolProvider.js +5 -3
  135. package/dist/languageService/documentSymbolProvider.js.map +1 -1
  136. package/dist/languageService/hoverProvider.d.ts +4 -3
  137. package/dist/languageService/hoverProvider.js +30 -36
  138. package/dist/languageService/hoverProvider.js.map +1 -1
  139. package/dist/languageService/navigationUtils.d.ts +6 -0
  140. package/dist/languageService/navigationUtils.js +28 -0
  141. package/dist/languageService/navigationUtils.js.map +1 -0
  142. package/dist/languageService/quickActions.d.ts +2 -2
  143. package/dist/languageService/quickActions.js +12 -1
  144. package/dist/languageService/quickActions.js.map +1 -1
  145. package/dist/languageService/referencesProvider.d.ts +13 -12
  146. package/dist/languageService/referencesProvider.js +102 -16
  147. package/dist/languageService/referencesProvider.js.map +1 -1
  148. package/dist/languageService/renameProvider.d.ts +17 -0
  149. package/dist/languageService/renameProvider.js +143 -0
  150. package/dist/languageService/renameProvider.js.map +1 -0
  151. package/dist/languageService/signatureHelpProvider.d.ts +19 -23
  152. package/dist/languageService/signatureHelpProvider.js +111 -18
  153. package/dist/languageService/signatureHelpProvider.js.map +1 -1
  154. package/dist/localization/localize.d.ts +17 -14
  155. package/dist/localization/localize.js +4 -6
  156. package/dist/localization/localize.js.map +1 -1
  157. package/dist/localization/package.nls.en-us.json +5 -6
  158. package/dist/parser/characterStream.d.ts +3 -3
  159. package/dist/parser/characterStream.js +12 -12
  160. package/dist/parser/characterStream.js.map +1 -1
  161. package/dist/parser/parser.d.ts +1 -1
  162. package/dist/parser/parser.js.map +1 -1
  163. package/dist/pyright.js +57 -54
  164. package/dist/pyright.js.map +1 -1
  165. package/dist/pyrightFileSystem.d.ts +1 -1
  166. package/dist/pyrightFileSystem.js +21 -21
  167. package/dist/pyrightFileSystem.js.map +1 -1
  168. package/dist/readonlyAugmentedFileSystem.d.ts +6 -6
  169. package/dist/readonlyAugmentedFileSystem.js +28 -28
  170. package/dist/readonlyAugmentedFileSystem.js.map +1 -1
  171. package/dist/server.js +6 -6
  172. package/dist/server.js.map +1 -1
  173. package/dist/tests/chainedSourceFiles.test.js +1 -1
  174. package/dist/tests/chainedSourceFiles.test.js.map +1 -1
  175. package/dist/tests/checker.test.js +1 -1
  176. package/dist/tests/documentSymbolCollector.test.js +3 -3
  177. package/dist/tests/documentSymbolCollector.test.js.map +1 -1
  178. package/dist/tests/fourslash/fourslash.d.ts +4 -4
  179. package/dist/tests/fourslash/missingTypeStub.codeAction.fourslash.js +1 -1
  180. package/dist/tests/fourslash/missingTypeStub.codeAction.fourslash.js.map +1 -1
  181. package/dist/tests/harness/fourslash/testLanguageService.d.ts +3 -3
  182. package/dist/tests/harness/fourslash/testLanguageService.js.map +1 -1
  183. package/dist/tests/harness/fourslash/testState.d.ts +11 -11
  184. package/dist/tests/harness/fourslash/testState.js +123 -113
  185. package/dist/tests/harness/fourslash/testState.js.map +1 -1
  186. package/dist/tests/harness/vfs/filesystem.d.ts +8 -8
  187. package/dist/tests/harness/vfs/filesystem.js +68 -68
  188. package/dist/tests/harness/vfs/filesystem.js.map +1 -1
  189. package/dist/tests/importStatementUtils.test.js +34 -0
  190. package/dist/tests/importStatementUtils.test.js.map +1 -1
  191. package/dist/tests/signatureHelp.test.js +5 -1
  192. package/dist/tests/signatureHelp.test.js.map +1 -1
  193. package/dist/tests/sourceFile.test.js +2 -2
  194. package/dist/tests/sourceFile.test.js.map +1 -1
  195. package/dist/tests/testStateUtils.d.ts +2 -2
  196. package/dist/tests/testStateUtils.js +39 -9
  197. package/dist/tests/testStateUtils.js.map +1 -1
  198. package/dist/tests/typeEvaluator1.test.js +8 -0
  199. package/dist/tests/typeEvaluator1.test.js.map +1 -1
  200. package/dist/tests/typeEvaluator2.test.js +13 -1
  201. package/dist/tests/typeEvaluator2.test.js.map +1 -1
  202. package/dist/tests/typeEvaluator3.test.js +2 -2
  203. package/dist/tests/typeEvaluator4.test.js +9 -1
  204. package/dist/tests/typeEvaluator4.test.js.map +1 -1
  205. package/dist/tests/typeEvaluator5.test.js +4 -0
  206. package/dist/tests/typeEvaluator5.test.js.map +1 -1
  207. package/dist/tests/workspaceEditUtils.test.js +84 -0
  208. package/dist/tests/workspaceEditUtils.test.js.map +1 -1
  209. package/package.json +4 -4
  210. package/dist/languageService/indentationUtils.d.ts +0 -16
  211. package/dist/languageService/indentationUtils.js +0 -727
  212. package/dist/languageService/indentationUtils.js.map +0 -1
  213. package/dist/languageService/insertionPointUtils.d.ts +0 -9
  214. package/dist/languageService/insertionPointUtils.js +0 -132
  215. package/dist/languageService/insertionPointUtils.js.map +0 -1
  216. package/dist/languageService/renameModuleProvider.d.ts +0 -65
  217. package/dist/languageService/renameModuleProvider.js +0 -939
  218. package/dist/languageService/renameModuleProvider.js.map +0 -1
  219. package/dist/tests/indentationUtils.ptvs.test.d.ts +0 -1
  220. package/dist/tests/indentationUtils.ptvs.test.js +0 -324
  221. package/dist/tests/indentationUtils.ptvs.test.js.map +0 -1
  222. package/dist/tests/indentationUtils.reindent.test.d.ts +0 -1
  223. package/dist/tests/indentationUtils.reindent.test.js +0 -372
  224. package/dist/tests/indentationUtils.reindent.test.js.map +0 -1
  225. package/dist/tests/indentationUtils.test.d.ts +0 -1
  226. package/dist/tests/indentationUtils.test.js +0 -502
  227. package/dist/tests/indentationUtils.test.js.map +0 -1
  228. package/dist/tests/insertionPointUtils.test.d.ts +0 -1
  229. package/dist/tests/insertionPointUtils.test.js +0 -154
  230. package/dist/tests/insertionPointUtils.test.js.map +0 -1
  231. package/dist/tests/moveSymbol.importAdder.test.d.ts +0 -1
  232. package/dist/tests/moveSymbol.importAdder.test.js +0 -298
  233. package/dist/tests/moveSymbol.importAdder.test.js.map +0 -1
  234. package/dist/tests/moveSymbol.insertion.test.d.ts +0 -1
  235. package/dist/tests/moveSymbol.insertion.test.js +0 -537
  236. package/dist/tests/moveSymbol.insertion.test.js.map +0 -1
  237. package/dist/tests/moveSymbol.misc.test.d.ts +0 -1
  238. package/dist/tests/moveSymbol.misc.test.js +0 -169
  239. package/dist/tests/moveSymbol.misc.test.js.map +0 -1
  240. package/dist/tests/moveSymbol.updateReference.test.d.ts +0 -1
  241. package/dist/tests/moveSymbol.updateReference.test.js +0 -1057
  242. package/dist/tests/moveSymbol.updateReference.test.js.map +0 -1
  243. package/dist/tests/renameModule.folder.test.d.ts +0 -1
  244. package/dist/tests/renameModule.folder.test.js +0 -229
  245. package/dist/tests/renameModule.folder.test.js.map +0 -1
  246. package/dist/tests/renameModule.fromImports.test.d.ts +0 -1
  247. package/dist/tests/renameModule.fromImports.test.js +0 -790
  248. package/dist/tests/renameModule.fromImports.test.js.map +0 -1
  249. package/dist/tests/renameModule.imports.test.d.ts +0 -1
  250. package/dist/tests/renameModule.imports.test.js +0 -380
  251. package/dist/tests/renameModule.imports.test.js.map +0 -1
  252. package/dist/tests/renameModule.misc.test.d.ts +0 -1
  253. package/dist/tests/renameModule.misc.test.js +0 -615
  254. package/dist/tests/renameModule.misc.test.js.map +0 -1
  255. package/dist/tests/renameModule.relativePath.test.d.ts +0 -1
  256. package/dist/tests/renameModule.relativePath.test.js +0 -231
  257. package/dist/tests/renameModule.relativePath.test.js.map +0 -1
  258. package/dist/tests/renameModuleTestUtils.d.ts +0 -4
  259. package/dist/tests/renameModuleTestUtils.js +0 -76
  260. package/dist/tests/renameModuleTestUtils.js.map +0 -1
@@ -51,12 +51,13 @@ const AnalyzerNodeInfo = __importStar(require("./analyzerNodeInfo"));
51
51
  const codeFlowEngine_1 = require("./codeFlowEngine");
52
52
  const codeFlowTypes_1 = require("./codeFlowTypes");
53
53
  const constraintSolver_1 = require("./constraintSolver");
54
- const constructorTransform_1 = require("./constructorTransform");
54
+ const constructors_1 = require("./constructors");
55
55
  const dataClasses_1 = require("./dataClasses");
56
56
  const declarationUtils_1 = require("./declarationUtils");
57
57
  const enums_1 = require("./enums");
58
58
  const functionTransform_1 = require("./functionTransform");
59
59
  const namedTuples_1 = require("./namedTuples");
60
+ const operations_1 = require("./operations");
60
61
  const parameterUtils_1 = require("./parameterUtils");
61
62
  const ParseTreeUtils = __importStar(require("./parseTreeUtils"));
62
63
  const patternMatching_1 = require("./patternMatching");
@@ -68,75 +69,12 @@ const symbol_1 = require("./symbol");
68
69
  const symbolNameUtils_1 = require("./symbolNameUtils");
69
70
  const symbolUtils_1 = require("./symbolUtils");
70
71
  const typeCacheUtils_1 = require("./typeCacheUtils");
71
- const typedDicts_1 = require("./typedDicts");
72
72
  const typeEvaluatorTypes_1 = require("./typeEvaluatorTypes");
73
73
  const TypePrinter = __importStar(require("./typePrinter"));
74
- const types_1 = require("./types");
75
74
  const typeUtils_1 = require("./typeUtils");
76
75
  const typeVarContext_1 = require("./typeVarContext");
77
- var MemberAccessFlags;
78
- (function (MemberAccessFlags) {
79
- MemberAccessFlags[MemberAccessFlags["None"] = 0] = "None";
80
- // By default, member accesses are assumed to access the attributes
81
- // of a class instance. By setting this flag, only attributes of
82
- // the class are considered.
83
- MemberAccessFlags[MemberAccessFlags["AccessClassMembersOnly"] = 1] = "AccessClassMembersOnly";
84
- // By default, members of base classes are also searched.
85
- // Set this flag to consider only the specified class' members.
86
- MemberAccessFlags[MemberAccessFlags["SkipBaseClasses"] = 2] = "SkipBaseClasses";
87
- // Do not include the "object" base class in the search.
88
- MemberAccessFlags[MemberAccessFlags["SkipObjectBaseClass"] = 4] = "SkipObjectBaseClass";
89
- // Consider writes to symbols flagged as ClassVars as an error.
90
- MemberAccessFlags[MemberAccessFlags["DisallowClassVarWrites"] = 8] = "DisallowClassVarWrites";
91
- // Normally __new__ is treated as a static method, but when
92
- // it is invoked implicitly through a constructor call, it
93
- // acts like a class method instead.
94
- MemberAccessFlags[MemberAccessFlags["TreatConstructorAsClassMethod"] = 16] = "TreatConstructorAsClassMethod";
95
- // By default, class member lookups start with the class itself
96
- // and fall back on the metaclass if it's not found. This option
97
- // skips the first check.
98
- MemberAccessFlags[MemberAccessFlags["ConsiderMetaclassOnly"] = 32] = "ConsiderMetaclassOnly";
99
- // If an attribute cannot be found when looking for instance
100
- // members, normally an attribute access override method
101
- // (__getattr__, etc.) may provide the missing attribute type.
102
- // This disables this check.
103
- MemberAccessFlags[MemberAccessFlags["SkipAttributeAccessOverride"] = 64] = "SkipAttributeAccessOverride";
104
- // Do not include the class itself, only base classes.
105
- MemberAccessFlags[MemberAccessFlags["SkipOriginalClass"] = 128] = "SkipOriginalClass";
106
- // Do not include the "type" base class in the search.
107
- MemberAccessFlags[MemberAccessFlags["SkipTypeBaseClass"] = 256] = "SkipTypeBaseClass";
108
- })(MemberAccessFlags || (MemberAccessFlags = {}));
109
- // Maps binary operators to the magic methods that implement them.
110
- const binaryOperatorMap = {
111
- [0 /* Add */]: ['__add__', '__radd__'],
112
- [33 /* Subtract */]: ['__sub__', '__rsub__'],
113
- [26 /* Multiply */]: ['__mul__', '__rmul__'],
114
- [13 /* FloorDivide */]: ['__floordiv__', '__rfloordiv__'],
115
- [10 /* Divide */]: ['__truediv__', '__rtruediv__'],
116
- [24 /* Mod */]: ['__mod__', '__rmod__'],
117
- [29 /* Power */]: ['__pow__', '__rpow__'],
118
- [22 /* MatrixMultiply */]: ['__matmul__', '__rmatmul__'],
119
- [3 /* BitwiseAnd */]: ['__and__', '__rand__'],
120
- [6 /* BitwiseOr */]: ['__or__', '__ror__'],
121
- [8 /* BitwiseXor */]: ['__xor__', '__rxor__'],
122
- [17 /* LeftShift */]: ['__lshift__', '__rlshift__'],
123
- [31 /* RightShift */]: ['__rshift__', '__rrshift__'],
124
- [12 /* Equals */]: ['__eq__', '__eq__'],
125
- [28 /* NotEquals */]: ['__ne__', '__ne__'],
126
- [20 /* LessThan */]: ['__lt__', '__gt__'],
127
- [21 /* LessThanOrEqual */]: ['__le__', '__ge__'],
128
- [15 /* GreaterThan */]: ['__gt__', '__lt__'],
129
- [16 /* GreaterThanOrEqual */]: ['__ge__', '__le__'],
130
- };
131
- // Map of operators that always return a bool result.
132
- const booleanOperatorMap = {
133
- [36 /* And */]: true,
134
- [37 /* Or */]: true,
135
- [39 /* Is */]: true,
136
- [40 /* IsNot */]: true,
137
- [41 /* In */]: true,
138
- [42 /* NotIn */]: true,
139
- };
76
+ const typedDicts_1 = require("./typedDicts");
77
+ const types_1 = require("./types");
140
78
  // This table contains the names of several built-in types that
141
79
  // are not subscriptable at runtime on older versions of Python.
142
80
  // It lists the first version of Python where subscripting is
@@ -221,9 +159,6 @@ const maxRecursiveTypeAliasRecursionCount = 10;
221
159
  const verifyTypeCacheEvaluatorFlags = false;
222
160
  // This debugging option prints each expression and its evaluated type.
223
161
  const printExpressionTypes = false;
224
- // If the number of subtypes starts to explode when applying "literal math",
225
- // cut off the literal union and fall back to the non-literal supertype.
226
- const maxLiteralMathSubtypeCount = 64;
227
162
  // The following number is chosen somewhat arbitrarily. We need to cut
228
163
  // off code flow analysis at some point for code flow graphs that are too
229
164
  // complex. Otherwise we risk overflowing the stack or incurring extremely
@@ -243,7 +178,6 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
243
178
  let cancellationToken;
244
179
  let isBasicTypesInitialized = false;
245
180
  let noneType;
246
- let unionType;
247
181
  let objectType;
248
182
  let typeClassType;
249
183
  let functionObj;
@@ -352,7 +286,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
352
286
  // If the entry is located within a part of the parse tree that is currently being
353
287
  // "speculatively" evaluated, track it so we delete the cached entry when we leave
354
288
  // this speculative context.
355
- if (speculativeTypeTracker.isSpeculative(node)) {
289
+ if (isSpeculativeModeInUse(node)) {
356
290
  speculativeTypeTracker.trackEntry(typeCacheToUse, node.id);
357
291
  if (allowSpeculativeCaching) {
358
292
  speculativeTypeTracker.addSpeculativeType(node, typeResult, incompleteGenerationCount, inferenceContext === null || inferenceContext === void 0 ? void 0 : inferenceContext.expectedType);
@@ -363,7 +297,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
363
297
  writeTypeCache(node, { type }, flags);
364
298
  }
365
299
  function setAsymmetricDescriptorAssignment(node) {
366
- if (speculativeTypeTracker.isSpeculative(/* node */ undefined)) {
300
+ if (isSpeculativeModeInUse(/* node */ undefined)) {
367
301
  return;
368
302
  }
369
303
  asymmetricDescriptorAssignmentCache.add(node.id);
@@ -596,15 +530,15 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
596
530
  break;
597
531
  }
598
532
  case 55 /* UnaryOperation */: {
599
- typeResult = getTypeOfUnaryOperation(node, inferenceContext);
533
+ typeResult = (0, operations_1.getTypeOfUnaryOperation)(evaluatorInterface, node, inferenceContext);
600
534
  break;
601
535
  }
602
536
  case 7 /* BinaryOperation */: {
603
- typeResult = getTypeOfBinaryOperation(node, inferenceContext, flags);
537
+ typeResult = (0, operations_1.getTypeOfBinaryOperation)(evaluatorInterface, node, inferenceContext, flags);
604
538
  break;
605
539
  }
606
540
  case 5 /* AugmentedAssignment */: {
607
- typeResult = getTypeOfAugmentedAssignment(node, inferenceContext);
541
+ typeResult = (0, operations_1.getTypeOfAugmentedAssignment)(evaluatorInterface, node, inferenceContext);
608
542
  break;
609
543
  }
610
544
  case 31 /* List */:
@@ -621,7 +555,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
621
555
  break;
622
556
  }
623
557
  case 51 /* Ternary */: {
624
- typeResult = getTypeOfTernary(node, flags, inferenceContext);
558
+ typeResult = (0, operations_1.getTypeOfTernaryOperation)(evaluatorInterface, node, flags, inferenceContext);
625
559
  break;
626
560
  }
627
561
  case 32 /* ListComprehension */: {
@@ -1996,7 +1930,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
1996
1930
  }
1997
1931
  function isDiagnosticSuppressedForNode(node) {
1998
1932
  return (suppressedNodeStack.some((suppressedNode) => ParseTreeUtils.isNodeContainedWithin(node, suppressedNode)) ||
1999
- speculativeTypeTracker.isSpeculative(node));
1933
+ isSpeculativeModeInUse(node));
2000
1934
  }
2001
1935
  function addDiagnostic(diagLevel, rule, message, node, range) {
2002
1936
  if (diagLevel === 'none') {
@@ -2658,7 +2592,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
2658
2592
  else {
2659
2593
  let callResult;
2660
2594
  suppressDiagnostics(node.typeExpression, () => {
2661
- callResult = validateConstructorArguments(node.typeExpression, [], concreteSubtype,
2595
+ callResult = (0, constructors_1.validateConstructorArguments)(evaluatorInterface, node.typeExpression, [], concreteSubtype,
2662
2596
  /* skipUnknownArgCheck */ false,
2663
2597
  /* inferenceContext */ undefined);
2664
2598
  });
@@ -2736,7 +2670,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
2736
2670
  }
2737
2671
  }
2738
2672
  function setSymbolAccessed(fileInfo, symbol, node) {
2739
- if (!speculativeTypeTracker.isSpeculative(node)) {
2673
+ if (!isSpeculativeModeInUse(node)) {
2740
2674
  fileInfo.accessedSymbolSet.add(symbol.id);
2741
2675
  }
2742
2676
  }
@@ -3095,7 +3029,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
3095
3029
  container: enclosingScope.name.value,
3096
3030
  }), node);
3097
3031
  }
3098
- type = types_1.TypeVarType.cloneForScopeId(type, getScopeIdForNode(enclosingScope), enclosingScope.name.value, enclosingScope.nodeType === 28 /* Function */
3032
+ type = types_1.TypeVarType.cloneForScopeId(type, ParseTreeUtils.getScopeIdForNode(enclosingScope), enclosingScope.name.value, enclosingScope.nodeType === 28 /* Function */
3099
3033
  ? 1 /* Function */
3100
3034
  : 0 /* Class */);
3101
3035
  }
@@ -3186,35 +3120,6 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
3186
3120
  }
3187
3121
  return type;
3188
3122
  }
3189
- // Creates an ID that identifies this parse node in a way that will
3190
- // not change each time the file is parsed (unless, of course, the
3191
- // file contents change).
3192
- function getScopeIdForNode(node) {
3193
- let name = '';
3194
- if (node.nodeType === 10 /* Class */) {
3195
- name = node.name.value;
3196
- }
3197
- else if (node.nodeType === 28 /* Function */) {
3198
- name = node.name.value;
3199
- }
3200
- const fileInfo = AnalyzerNodeInfo.getFileInfo(node);
3201
- return `${fileInfo.filePath}.${node.start.toString()}-${name}`;
3202
- }
3203
- // Walks up the parse tree and finds all scopes that can provide
3204
- // a context for a TypeVar and returns the scope ID for each.
3205
- function getTypeVarScopesForNode(node) {
3206
- const scopeIds = [];
3207
- let curNode = node;
3208
- while (curNode) {
3209
- curNode = ParseTreeUtils.getTypeVarScopeNode(curNode);
3210
- if (!curNode) {
3211
- break;
3212
- }
3213
- scopeIds.push(getScopeIdForNode(curNode));
3214
- curNode = curNode.parent;
3215
- }
3216
- return scopeIds;
3217
- }
3218
3123
  // Walks up the parse tree to find a function, class, or type alias
3219
3124
  // declaration that provides the context for a type variable.
3220
3125
  function findScopedTypeVar(node, type) {
@@ -5205,7 +5110,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
5205
5110
  }
5206
5111
  else {
5207
5112
  const tupleTypeVarContext = new typeVarContext_1.TypeVarContext((0, typeUtils_1.getTypeVarScopeId)(tupleClassType));
5208
- if (!(0, constraintSolver_1.populateTypeVarContextBasedOnExpectedType)(evaluatorInterface, types_1.ClassType.cloneAsInstance(tupleClassType), inferenceContext.expectedType, tupleTypeVarContext, getTypeVarScopesForNode(node))) {
5113
+ if (!(0, constraintSolver_1.populateTypeVarContextBasedOnExpectedType)(evaluatorInterface, types_1.ClassType.cloneAsInstance(tupleClassType), inferenceContext.expectedType, tupleTypeVarContext, ParseTreeUtils.getTypeVarScopesForNode(node))) {
5209
5114
  return undefined;
5210
5115
  }
5211
5116
  const specializedTuple = (0, typeUtils_1.applySolvedTypeVars)(tupleClassType, tupleTypeVarContext);
@@ -5364,7 +5269,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
5364
5269
  }
5365
5270
  // Don't bother evaluating the arguments if we're speculatively evaluating the call
5366
5271
  // or the base type is incomplete.
5367
- if (!speculativeTypeTracker.isSpeculative(node) && !baseTypeResult.isIncomplete) {
5272
+ if (!isSpeculativeModeInUse(node) && !baseTypeResult.isIncomplete) {
5368
5273
  // Touch all of the args so they're marked accessed even if there were errors.
5369
5274
  // We skip this if it's a TypeVar() call in the typing.pyi module because
5370
5275
  // this results in a cyclical type resolution problem whereby we try to
@@ -5432,7 +5337,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
5432
5337
  // If one or more of the arguments are incomplete, use speculative mode
5433
5338
  // for the lambda evaluation because it may need to be reevaluated once
5434
5339
  // the arg types are complete.
5435
- let typeResult = isArgTypeIncomplete || speculativeTypeTracker.isSpeculative(node) || (inferenceContext === null || inferenceContext === void 0 ? void 0 : inferenceContext.isTypeIncomplete)
5340
+ let typeResult = isArgTypeIncomplete || isSpeculativeModeInUse(node) || (inferenceContext === null || inferenceContext === void 0 ? void 0 : inferenceContext.isTypeIncomplete)
5436
5341
  ? useSpeculativeMode(node.leftExpression, getLambdaType)
5437
5342
  : getLambdaType();
5438
5343
  // If bidirectional type inference failed, use normal type inference instead.
@@ -5740,15 +5645,12 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
5740
5645
  ? matchedOverloads[matchedOverloads.length - 1].typeVarContext.clone()
5741
5646
  : typeVarContext;
5742
5647
  const effectiveTypeVarContext = (_a = typeVarContextToClone === null || typeVarContextToClone === void 0 ? void 0 : typeVarContextToClone.clone()) !== null && _a !== void 0 ? _a : new typeVarContext_1.TypeVarContext((0, typeUtils_1.getTypeVarScopeId)(overload));
5743
- effectiveTypeVarContext.addSolveForScope((0, typeUtils_1.getTypeVarScopeId)(overload));
5744
- if (overload.details.constructorTypeVarScopeId) {
5745
- effectiveTypeVarContext.addSolveForScope(overload.details.constructorTypeVarScopeId);
5746
- }
5648
+ effectiveTypeVarContext.addSolveForScope((0, typeUtils_1.getTypeVarScopeIds)(overload));
5747
5649
  effectiveTypeVarContext.unlock();
5748
5650
  // Use speculative mode so we don't output any diagnostics or
5749
5651
  // record any final types in the type cache.
5750
5652
  const callResult = useSpeculativeMode(errorNode, () => {
5751
- return validateFunctionArgumentTypesWithExpectedType(errorNode, matchResults, effectiveTypeVarContext,
5653
+ return validateFunctionArgumentTypesWithContext(errorNode, matchResults, effectiveTypeVarContext,
5752
5654
  /* skipUnknownArgCheck */ true, inferenceContext);
5753
5655
  });
5754
5656
  if (callResult.isTypeIncomplete) {
@@ -5793,15 +5695,26 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
5793
5695
  else {
5794
5696
  // Eliminate any return types that are subsumed by other return types.
5795
5697
  let dedupedMatchResults = [];
5698
+ let dedupedResultsIncludeAny = false;
5796
5699
  possibleMatchResults.forEach((result) => {
5797
5700
  let isSubtypeSubsumed = false;
5798
5701
  for (let dedupedIndex = 0; dedupedIndex < dedupedMatchResults.length; dedupedIndex++) {
5799
5702
  if (assignType(dedupedMatchResults[dedupedIndex], result.returnType)) {
5800
- isSubtypeSubsumed = true;
5703
+ if (!(0, typeUtils_1.containsAnyOrUnknown)(dedupedMatchResults[dedupedIndex])) {
5704
+ isSubtypeSubsumed = true;
5705
+ }
5706
+ else if (!(0, typeUtils_1.containsUnknown)(dedupedMatchResults[dedupedIndex])) {
5707
+ dedupedResultsIncludeAny = true;
5708
+ }
5801
5709
  break;
5802
5710
  }
5803
5711
  else if (assignType(result.returnType, dedupedMatchResults[dedupedIndex])) {
5804
- dedupedMatchResults[dedupedIndex] = types_1.NeverType.createNever();
5712
+ if (!(0, typeUtils_1.containsAnyOrUnknown)(result.returnType)) {
5713
+ dedupedMatchResults[dedupedIndex] = types_1.NeverType.createNever();
5714
+ }
5715
+ else if (!(0, typeUtils_1.containsUnknown)(dedupedMatchResults[dedupedIndex])) {
5716
+ dedupedResultsIncludeAny = true;
5717
+ }
5805
5718
  break;
5806
5719
  }
5807
5720
  }
@@ -5811,9 +5724,21 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
5811
5724
  });
5812
5725
  dedupedMatchResults = dedupedMatchResults.filter((t) => !(0, types_1.isNever)(t));
5813
5726
  const combinedTypes = (0, types_1.combineTypes)(dedupedMatchResults);
5814
- returnTypes.push(dedupedMatchResults.length > 1
5815
- ? types_1.UnknownType.createPossibleType(combinedTypes, possibleMatchInvolvesIncompleteUnknown)
5816
- : combinedTypes);
5727
+ let effectiveReturnType = combinedTypes;
5728
+ if (dedupedMatchResults.length > 1) {
5729
+ // If one or more of the deduped types is Any or contains Any,
5730
+ // we will assume that the person who defined the overload really
5731
+ // wanted Any rather than Unknown. In cases where the deduped types
5732
+ // simply contains conflicting results without an Any, we'll use
5733
+ // an UnknownType.
5734
+ if (dedupedResultsIncludeAny) {
5735
+ effectiveReturnType = types_1.AnyType.create();
5736
+ }
5737
+ else {
5738
+ effectiveReturnType = types_1.UnknownType.createPossibleType(combinedTypes, possibleMatchInvolvesIncompleteUnknown);
5739
+ }
5740
+ }
5741
+ returnTypes.push(effectiveReturnType);
5817
5742
  }
5818
5743
  }
5819
5744
  if (!matchedOverload) {
@@ -5832,7 +5757,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
5832
5757
  const finalTypeVarContext = typeVarContext !== null && typeVarContext !== void 0 ? typeVarContext : matchedOverloads[0].typeVarContext;
5833
5758
  finalTypeVarContext.unlock();
5834
5759
  finalTypeVarContext.addSolveForScope((0, typeUtils_1.getTypeVarScopeId)(matchedOverloads[0].overload));
5835
- const finalCallResult = validateFunctionArgumentTypesWithExpectedType(errorNode, matchedOverloads[0].matchResults, finalTypeVarContext, skipUnknownArgCheck, inferenceContext);
5760
+ const finalCallResult = validateFunctionArgumentTypesWithContext(errorNode, matchedOverloads[0].matchResults, finalTypeVarContext, skipUnknownArgCheck, inferenceContext);
5836
5761
  if (finalCallResult.isTypeIncomplete) {
5837
5762
  isTypeIncomplete = true;
5838
5763
  }
@@ -5955,12 +5880,9 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
5955
5880
  return current.overloadIndex > previous.overloadIndex ? current : previous;
5956
5881
  });
5957
5882
  const effectiveTypeVarContext = typeVarContext !== null && typeVarContext !== void 0 ? typeVarContext : new typeVarContext_1.TypeVarContext();
5958
- effectiveTypeVarContext.addSolveForScope((0, typeUtils_1.getTypeVarScopeId)(lastMatch.overload));
5959
- if (lastMatch.overload.details.constructorTypeVarScopeId) {
5960
- effectiveTypeVarContext.addSolveForScope(lastMatch.overload.details.constructorTypeVarScopeId);
5961
- }
5883
+ effectiveTypeVarContext.addSolveForScope((0, typeUtils_1.getTypeVarScopeIds)(lastMatch.overload));
5962
5884
  effectiveTypeVarContext.unlock();
5963
- return validateFunctionArgumentTypesWithExpectedType(errorNode, lastMatch, effectiveTypeVarContext, skipUnknownArgCheck, inferenceContext);
5885
+ return validateFunctionArgumentTypesWithContext(errorNode, lastMatch, effectiveTypeVarContext, skipUnknownArgCheck, inferenceContext);
5964
5886
  };
5965
5887
  // If there is only one possible arg/param match among the overloads,
5966
5888
  // use the normal type matching mechanism because it is faster and
@@ -6063,325 +5985,6 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
6063
5985
  });
6064
5986
  return newExpandedArgTypes;
6065
5987
  }
6066
- // Tries to match the arguments of a call to the constructor for a class.
6067
- // If successful, it returns the resulting (specialized) object type that
6068
- // is allocated by the constructor. If unsuccessful, it records diagnostic
6069
- // information and returns undefined.
6070
- function validateConstructorArguments(errorNode, argList, type, skipUnknownArgCheck, inferenceContext) {
6071
- var _a;
6072
- let validatedTypes = false;
6073
- let returnType;
6074
- let reportedErrors = false;
6075
- let isTypeIncomplete = false;
6076
- let usedMetaclassCallMethod = false;
6077
- const overloadsUsedForCall = [];
6078
- // Create a helper function that determines whether we should skip argument
6079
- // validation for either __init__ or __new__. This is required for certain
6080
- // synthesized constructor types, namely NamedTuples.
6081
- const skipConstructorCheck = (type) => {
6082
- return (0, types_1.isFunction)(type) && types_1.FunctionType.isSkipConstructorCheck(type);
6083
- };
6084
- // Validate __init__
6085
- // We validate __init__ before __new__ because the former typically has
6086
- // more specific type annotations, and we want to evaluate the arguments
6087
- // in the context of these types. The __new__ method often uses generic
6088
- // vargs and kwargs.
6089
- const initMethodType = (_a = getTypeOfObjectMember(errorNode, types_1.ClassType.cloneAsInstance(type), '__init__', { method: 'get' },
6090
- /* diag */ undefined, 4 /* SkipObjectBaseClass */ | 64 /* SkipAttributeAccessOverride */)) === null || _a === void 0 ? void 0 : _a.type;
6091
- if (initMethodType && !skipConstructorCheck(initMethodType)) {
6092
- // If there is an expected type, analyze the constructor call
6093
- // for each of the subtypes that comprise the expected type. If
6094
- // one or more analyzes with no errors, use those results.
6095
- if (inferenceContext) {
6096
- const expectedCallResult = validateConstructorMethodWithExpectedType(errorNode, argList, type, skipUnknownArgCheck, inferenceContext, initMethodType);
6097
- if (expectedCallResult && !expectedCallResult.argumentErrors) {
6098
- returnType = expectedCallResult.returnType;
6099
- if (expectedCallResult.isTypeIncomplete) {
6100
- isTypeIncomplete = true;
6101
- }
6102
- }
6103
- }
6104
- if (!returnType) {
6105
- const typeVarContext = type.typeArguments
6106
- ? (0, typeUtils_1.buildTypeVarContextFromSpecializedClass)(type, /* makeConcrete */ false)
6107
- : new typeVarContext_1.TypeVarContext((0, typeUtils_1.getTypeVarScopeId)(type));
6108
- typeVarContext.addSolveForScope((0, typeUtils_1.getTypeVarScopeId)(initMethodType));
6109
- const callResult = validateCallArguments(errorNode, argList, { type: initMethodType }, typeVarContext, skipUnknownArgCheck);
6110
- if (!callResult.argumentErrors) {
6111
- let adjustedClassType = type;
6112
- if (callResult.specializedInitSelfType &&
6113
- (0, types_1.isClassInstance)(callResult.specializedInitSelfType) &&
6114
- types_1.ClassType.isSameGenericClass(callResult.specializedInitSelfType, type)) {
6115
- adjustedClassType = types_1.ClassType.cloneAsInstantiable(callResult.specializedInitSelfType);
6116
- }
6117
- returnType = applyExpectedTypeForConstructor(adjustedClassType,
6118
- /* inferenceContext */ undefined, typeVarContext);
6119
- if (callResult.isTypeIncomplete) {
6120
- isTypeIncomplete = true;
6121
- }
6122
- overloadsUsedForCall.push(...callResult.overloadsUsedForCall);
6123
- }
6124
- else {
6125
- reportedErrors = true;
6126
- }
6127
- }
6128
- validatedTypes = true;
6129
- skipUnknownArgCheck = true;
6130
- }
6131
- // Validate __new__
6132
- // Don't report errors for __new__ if __init__ already generated errors. They're
6133
- // probably going to be entirely redundant anyway.
6134
- if (!reportedErrors) {
6135
- const metaclass = type.details.effectiveMetaclass;
6136
- let constructorMethodInfo;
6137
- // See if there's a custom `__call__` method on the metaclass. If so, we'll
6138
- // use that rather than the `__new__` method on the class.
6139
- if (metaclass && (0, types_1.isInstantiableClass)(metaclass) && !types_1.ClassType.isSameGenericClass(metaclass, type)) {
6140
- constructorMethodInfo = getTypeOfClassMemberName(errorNode, metaclass,
6141
- /* isAccessedThroughObject */ true, '__call__', { method: 'get' },
6142
- /* diag */ undefined, 32 /* ConsiderMetaclassOnly */ |
6143
- 256 /* SkipTypeBaseClass */ |
6144
- 64 /* SkipAttributeAccessOverride */, type);
6145
- if (constructorMethodInfo) {
6146
- usedMetaclassCallMethod = true;
6147
- }
6148
- }
6149
- if (!constructorMethodInfo) {
6150
- constructorMethodInfo = getTypeOfClassMemberName(errorNode, type,
6151
- /* isAccessedThroughObject */ false, '__new__', { method: 'get' },
6152
- /* diag */ undefined, 1 /* AccessClassMembersOnly */ |
6153
- 4 /* SkipObjectBaseClass */ |
6154
- 16 /* TreatConstructorAsClassMethod */, type);
6155
- }
6156
- if (constructorMethodInfo && !skipConstructorCheck(constructorMethodInfo.type)) {
6157
- const constructorMethodType = constructorMethodInfo.type;
6158
- let newReturnType;
6159
- // If there is an expected type that was not applied above when
6160
- // handling the __init__ method, try to apply it with the __new__ method.
6161
- if (inferenceContext && !returnType) {
6162
- const expectedCallResult = validateConstructorMethodWithExpectedType(errorNode, argList, type, skipUnknownArgCheck, inferenceContext, constructorMethodType);
6163
- if (expectedCallResult && !expectedCallResult.argumentErrors) {
6164
- newReturnType = expectedCallResult.returnType;
6165
- returnType = newReturnType;
6166
- if (expectedCallResult.isTypeIncomplete) {
6167
- isTypeIncomplete = true;
6168
- }
6169
- }
6170
- }
6171
- const typeVarContext = new typeVarContext_1.TypeVarContext((0, typeUtils_1.getTypeVarScopeId)(type));
6172
- if (type.typeAliasInfo) {
6173
- typeVarContext.addSolveForScope(type.typeAliasInfo.typeVarScopeId);
6174
- }
6175
- typeVarContext.addSolveForScope((0, typeUtils_1.getTypeVarScopeId)(constructorMethodType));
6176
- // Skip the unknown argument check if we've already checked for __init__.
6177
- let callResult;
6178
- if ((0, constructorTransform_1.hasConstructorTransform)(type)) {
6179
- // Use speculative mode if we're going to later apply
6180
- // a constructor transform. This allows us to use bidirectional
6181
- // type inference for arguments in the transform.
6182
- callResult = useSpeculativeMode(errorNode, () => {
6183
- return validateCallArguments(errorNode, argList, constructorMethodInfo, typeVarContext, skipUnknownArgCheck);
6184
- });
6185
- }
6186
- else {
6187
- callResult = validateCallArguments(errorNode, argList, constructorMethodInfo, typeVarContext, skipUnknownArgCheck);
6188
- }
6189
- if (callResult.isTypeIncomplete) {
6190
- isTypeIncomplete = true;
6191
- }
6192
- if (callResult.argumentErrors) {
6193
- reportedErrors = true;
6194
- }
6195
- else if (!newReturnType) {
6196
- newReturnType = callResult.returnType;
6197
- if (overloadsUsedForCall.length === 0) {
6198
- overloadsUsedForCall.push(...callResult.overloadsUsedForCall);
6199
- }
6200
- // If the constructor returned an object whose type matches the class of
6201
- // the original type being constructed, use the return type in case it was
6202
- // specialized. If it doesn't match, we'll fall back on the assumption that
6203
- // the constructed type is an instance of the class type. We need to do this
6204
- // in cases where we're inferring the return type based on a call to
6205
- // super().__new__().
6206
- if (newReturnType) {
6207
- if ((0, types_1.isClassInstance)(newReturnType) && types_1.ClassType.isSameGenericClass(newReturnType, type)) {
6208
- // If the specialized return type derived from the __init__
6209
- // method is "better" than the return type provided by the
6210
- // __new__ method (where "better" means that the type arguments
6211
- // are all known), stick with the __init__ result.
6212
- if ((!(0, typeUtils_1.isPartlyUnknown)(newReturnType) && !(0, typeUtils_1.requiresSpecialization)(newReturnType)) ||
6213
- returnType === undefined) {
6214
- // Special-case the 'tuple' type specialization to use
6215
- // the homogenous arbitrary-length form.
6216
- if ((0, types_1.isClassInstance)(newReturnType) &&
6217
- types_1.ClassType.isTupleClass(newReturnType) &&
6218
- !newReturnType.tupleTypeArguments &&
6219
- newReturnType.typeArguments &&
6220
- newReturnType.typeArguments.length === 1) {
6221
- newReturnType = (0, typeUtils_1.specializeTupleClass)(newReturnType, [
6222
- { type: newReturnType.typeArguments[0], isUnbounded: true },
6223
- ]);
6224
- }
6225
- returnType = newReturnType;
6226
- }
6227
- }
6228
- else if (!returnType && !(0, types_1.isUnknown)(newReturnType)) {
6229
- returnType = newReturnType;
6230
- }
6231
- }
6232
- }
6233
- if (!returnType) {
6234
- returnType = applyExpectedTypeForConstructor(type, inferenceContext, typeVarContext);
6235
- }
6236
- else if ((0, types_1.isClassInstance)(returnType) && (0, typeUtils_1.isTupleClass)(returnType) && !returnType.tupleTypeArguments) {
6237
- returnType = applyExpectedTypeForTupleConstructor(returnType, inferenceContext);
6238
- }
6239
- validatedTypes = true;
6240
- }
6241
- }
6242
- // If we weren't able to validate the args, analyze the expressions
6243
- // here to mark symbols as referenced and report expression-level errors.
6244
- if (!validatedTypes) {
6245
- argList.forEach((arg) => {
6246
- if (arg.valueExpression && !speculativeTypeTracker.isSpeculative(arg.valueExpression)) {
6247
- getTypeOfExpression(arg.valueExpression);
6248
- }
6249
- });
6250
- }
6251
- if (!validatedTypes && argList.some((arg) => arg.argumentCategory === 0 /* Simple */)) {
6252
- // Suppress this error if the class was instantiated from a custom
6253
- // metaclass because it's likely that it's a false positive. Also
6254
- // suppress the error if the class's metaclass has a __call__ method.
6255
- const isCustomMetaclass = !!type.details.effectiveMetaclass &&
6256
- (0, types_1.isInstantiableClass)(type.details.effectiveMetaclass) &&
6257
- !types_1.ClassType.isBuiltIn(type.details.effectiveMetaclass);
6258
- if (!isCustomMetaclass && !usedMetaclassCallMethod) {
6259
- const fileInfo = AnalyzerNodeInfo.getFileInfo(errorNode);
6260
- addDiagnostic(fileInfo.diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.constructorNoArgs().format({ type: type.aliasName || type.details.name }), errorNode);
6261
- }
6262
- }
6263
- if (!returnType) {
6264
- // There was no __init__ or __new__ method or we couldn't match the provided
6265
- // arguments to them.
6266
- if (!inferenceContext && type.typeArguments) {
6267
- // If there was no expected type but the type was already specialized,
6268
- // assume that we're constructing an instance of the specialized type.
6269
- returnType = (0, typeUtils_1.convertToInstance)(type);
6270
- }
6271
- else {
6272
- // Do our best to specialize the instantiated class based on the expected
6273
- // type if provided.
6274
- const typeVarContext = new typeVarContext_1.TypeVarContext((0, typeUtils_1.getTypeVarScopeId)(type));
6275
- if (inferenceContext) {
6276
- (0, constraintSolver_1.populateTypeVarContextBasedOnExpectedType)(evaluatorInterface, types_1.ClassType.cloneAsInstance(type), inferenceContext.expectedType, typeVarContext, getTypeVarScopesForNode(errorNode));
6277
- }
6278
- returnType = applyExpectedTypeForConstructor(type, inferenceContext, typeVarContext);
6279
- }
6280
- }
6281
- if (!reportedErrors) {
6282
- const transformed = (0, constructorTransform_1.applyConstructorTransform)(evaluatorInterface, errorNode, argList, type, {
6283
- argumentErrors: reportedErrors,
6284
- returnType,
6285
- isTypeIncomplete,
6286
- });
6287
- returnType = transformed.returnType;
6288
- if (transformed.isTypeIncomplete) {
6289
- isTypeIncomplete = true;
6290
- }
6291
- if (transformed.argumentErrors) {
6292
- reportedErrors = true;
6293
- }
6294
- }
6295
- const result = {
6296
- argumentErrors: reportedErrors,
6297
- returnType,
6298
- isTypeIncomplete,
6299
- overloadsUsedForCall,
6300
- };
6301
- return result;
6302
- }
6303
- // For a constructor call that targets a generic class and an "expected type"
6304
- // (i.e. bidirectional inference), this function attempts to infer the correct
6305
- // specialized return type for the constructor.
6306
- function validateConstructorMethodWithExpectedType(errorNode, argList, type, skipUnknownArgCheck, inferenceContext, constructorMethodType) {
6307
- let isTypeIncomplete = false;
6308
- let argumentErrors = false;
6309
- const overloadsUsedForCall = [];
6310
- const returnType = (0, typeUtils_1.mapSubtypes)(inferenceContext.expectedType, (expectedSubType) => {
6311
- expectedSubType = (0, typeUtils_1.transformPossibleRecursiveTypeAlias)(expectedSubType);
6312
- const typeVarContext = new typeVarContext_1.TypeVarContext((0, typeUtils_1.getTypeVarScopeId)(type));
6313
- if ((0, constraintSolver_1.populateTypeVarContextBasedOnExpectedType)(evaluatorInterface, types_1.ClassType.cloneAsInstance(type), expectedSubType, typeVarContext, getTypeVarScopesForNode(errorNode))) {
6314
- let callResult;
6315
- useSpeculativeMode(errorNode, () => {
6316
- callResult = validateCallArguments(errorNode, argList, { type: constructorMethodType }, typeVarContext.clone(), skipUnknownArgCheck);
6317
- });
6318
- if (!callResult.argumentErrors) {
6319
- // Call validateCallArguments again, this time without speculative
6320
- // mode, so any errors are reported.
6321
- callResult = validateCallArguments(errorNode, argList, { type: constructorMethodType }, typeVarContext, skipUnknownArgCheck);
6322
- if (callResult.isTypeIncomplete) {
6323
- isTypeIncomplete = true;
6324
- }
6325
- if (callResult.argumentErrors) {
6326
- argumentErrors = true;
6327
- }
6328
- overloadsUsedForCall.push(...callResult.overloadsUsedForCall);
6329
- return applyExpectedSubtypeForConstructor(type, expectedSubType, typeVarContext);
6330
- }
6331
- }
6332
- return undefined;
6333
- });
6334
- if ((0, types_1.isNever)(returnType)) {
6335
- return undefined;
6336
- }
6337
- return { returnType, isTypeIncomplete, argumentErrors, overloadsUsedForCall };
6338
- }
6339
- function applyExpectedSubtypeForConstructor(type, expectedSubtype, typeVarContext) {
6340
- const specializedType = (0, typeUtils_1.applySolvedTypeVars)(types_1.ClassType.cloneAsInstance(type), typeVarContext);
6341
- if (!assignType(expectedSubtype, specializedType)) {
6342
- return undefined;
6343
- }
6344
- // If the expected type is "Any", transform it to an Any.
6345
- if ((0, types_1.isAny)(expectedSubtype)) {
6346
- return expectedSubtype;
6347
- }
6348
- return specializedType;
6349
- }
6350
- // Handles the case where a constructor is a generic type and the type
6351
- // arguments are not specified but can be provided by the expected type.
6352
- function applyExpectedTypeForConstructor(type, inferenceContext, typeVarContext) {
6353
- let unsolvedTypeVarsAreUnknown = true;
6354
- if (inferenceContext) {
6355
- const specializedExpectedType = (0, typeUtils_1.mapSubtypes)(inferenceContext.expectedType, (expectedSubtype) => {
6356
- return applyExpectedSubtypeForConstructor(type, expectedSubtype, typeVarContext);
6357
- });
6358
- if (!(0, types_1.isNever)(specializedExpectedType)) {
6359
- return specializedExpectedType;
6360
- }
6361
- // If the expected type didn't provide TypeVar values, remaining
6362
- // unsolved TypeVars should be considered Unknown unless they were
6363
- // provided explicitly in the constructor call.
6364
- if (type.typeArguments) {
6365
- unsolvedTypeVarsAreUnknown = false;
6366
- }
6367
- }
6368
- const specializedType = (0, typeUtils_1.applySolvedTypeVars)(type, typeVarContext, {
6369
- unknownIfNotFound: unsolvedTypeVarsAreUnknown,
6370
- });
6371
- return types_1.ClassType.cloneAsInstance(specializedType);
6372
- }
6373
- // Similar to applyExpectedTypeForConstructor, this function handles the
6374
- // special case of the tuple class.
6375
- function applyExpectedTypeForTupleConstructor(type, inferenceContext) {
6376
- let specializedType = type;
6377
- if (inferenceContext &&
6378
- (0, types_1.isClassInstance)(inferenceContext.expectedType) &&
6379
- (0, typeUtils_1.isTupleClass)(inferenceContext.expectedType) &&
6380
- inferenceContext.expectedType.tupleTypeArguments) {
6381
- specializedType = (0, typeUtils_1.specializeTupleClass)(type, inferenceContext.expectedType.tupleTypeArguments);
6382
- }
6383
- return specializedType;
6384
- }
6385
5988
  // Validates that the arguments can be assigned to the call's parameter
6386
5989
  // list, specializes the call based on arg types, and returns the
6387
5990
  // specialized type of the return value. If it detects an error along
@@ -6414,7 +6017,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
6414
6017
  // to be done again once it is complete.
6415
6018
  if (!callTypeResult.isIncomplete) {
6416
6019
  argList.forEach((arg) => {
6417
- if (arg.valueExpression && !speculativeTypeTracker.isSpeculative(arg.valueExpression)) {
6020
+ if (arg.valueExpression && !isSpeculativeModeInUse(arg.valueExpression)) {
6418
6021
  getTypeOfArgument(arg);
6419
6022
  }
6420
6023
  });
@@ -6443,7 +6046,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
6443
6046
  let effectiveTypeVarContext = typeVarContext;
6444
6047
  if (!effectiveTypeVarContext) {
6445
6048
  // If a typeVarContext wasn't provided by the caller, allocate one here.
6446
- effectiveTypeVarContext = new typeVarContext_1.TypeVarContext((0, typeUtils_1.getTypeVarScopeId)(expandedSubtype));
6049
+ effectiveTypeVarContext = new typeVarContext_1.TypeVarContext((0, typeUtils_1.getTypeVarScopeIds)(expandedSubtype));
6447
6050
  // There are certain cases, such as with super().__new__(cls) calls where
6448
6051
  // the call is a constructor but the proper TypeVar scope has been lost.
6449
6052
  // We'll add a wildcard TypeVar scope here. This is a bit of a hack and
@@ -6538,7 +6141,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
6538
6141
  const className = expandedSubtype.aliasName || expandedSubtype.details.name;
6539
6142
  if (className === 'type') {
6540
6143
  // Validate the constructor arguments.
6541
- validateConstructorArguments(errorNode, argList, expandedSubtype, skipUnknownArgCheck, inferenceContext);
6144
+ (0, constructors_1.validateConstructorArguments)(evaluatorInterface, errorNode, argList, expandedSubtype, skipUnknownArgCheck, inferenceContext);
6542
6145
  // Handle the 'type' call specially.
6543
6146
  if (argList.length === 1) {
6544
6147
  // The one-parameter form of "type" returns the class
@@ -6637,7 +6240,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
6637
6240
  }), errorNode);
6638
6241
  }
6639
6242
  // Assume this is a call to the constructor.
6640
- const constructorResult = validateConstructorArguments(errorNode, argList, expandedSubtype, skipUnknownArgCheck, inferenceContext);
6243
+ const constructorResult = (0, constructors_1.validateConstructorArguments)(evaluatorInterface, errorNode, argList, expandedSubtype, skipUnknownArgCheck, inferenceContext);
6641
6244
  overloadsUsedForCall.push(...constructorResult.overloadsUsedForCall);
6642
6245
  if (constructorResult.argumentErrors) {
6643
6246
  argumentErrors = true;
@@ -7479,7 +7082,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
7479
7082
  // If we're in speculative mode and an arg/param mismatch has already been reported, don't
7480
7083
  // bother doing the extra work here. This occurs frequently when attempting to find the
7481
7084
  // correct overload.
7482
- if (!reportedArgError || !speculativeTypeTracker.isSpeculative(undefined)) {
7085
+ if (!reportedArgError || !isSpeculativeModeInUse(undefined)) {
7483
7086
  // If there are arguments that map to a variadic *args parameter that hasn't
7484
7087
  // already been matched, see if the type of that *args parameter is a variadic
7485
7088
  // type variable. If so, we'll preprocess those arguments and combine them
@@ -7577,13 +7180,12 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
7577
7180
  // After having matched arguments with parameters, this function evaluates the
7578
7181
  // types of each argument expression and validates that the resulting type is
7579
7182
  // compatible with the declared type of the corresponding parameter.
7580
- function validateFunctionArgumentTypesWithExpectedType(errorNode, matchResults, typeVarContext, skipUnknownArgCheck = false, inferenceContext) {
7183
+ function validateFunctionArgumentTypesWithContext(errorNode, matchResults, typeVarContext, skipUnknownArgCheck = false, inferenceContext) {
7581
7184
  var _a;
7582
7185
  const type = matchResults.overload;
7583
7186
  if (!inferenceContext ||
7584
7187
  (0, types_1.isAnyOrUnknown)(inferenceContext.expectedType) ||
7585
7188
  (0, types_1.isNever)(inferenceContext.expectedType) ||
7586
- (0, typeUtils_1.requiresSpecialization)(inferenceContext.expectedType) ||
7587
7189
  !type.details.declaredReturnType ||
7588
7190
  !(0, typeUtils_1.requiresSpecialization)((_a = types_1.FunctionType.getSpecializedReturnType(type)) !== null && _a !== void 0 ? _a : types_1.UnknownType.create())) {
7589
7191
  return validateFunctionArgumentTypes(errorNode, matchResults, typeVarContext, skipUnknownArgCheck);
@@ -7598,17 +7200,16 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
7598
7200
  // We may or may not be able to make use of the expected type. We'll evaluate
7599
7201
  // speculatively to see if using the expected type works.
7600
7202
  if ((0, types_1.isUnion)(inferenceContext.expectedType)) {
7601
- let speculativeResults;
7602
7203
  useSpeculativeMode(errorNode, () => {
7603
7204
  const typeVarContextCopy = typeVarContext.clone();
7604
7205
  assignType(effectiveReturnType, effectiveExpectedType,
7605
7206
  /* diag */ undefined, typeVarContextCopy,
7606
7207
  /* srcTypeVarContext */ undefined, effectiveFlags | 1024 /* PopulatingExpectedType */);
7607
- speculativeResults = validateFunctionArgumentTypes(errorNode, matchResults, typeVarContextCopy, skipUnknownArgCheck);
7208
+ const speculativeResults = validateFunctionArgumentTypes(errorNode, matchResults, typeVarContextCopy, skipUnknownArgCheck);
7209
+ if (speculativeResults === null || speculativeResults === void 0 ? void 0 : speculativeResults.argumentErrors) {
7210
+ effectiveExpectedType = undefined;
7211
+ }
7608
7212
  });
7609
- if (speculativeResults && speculativeResults.argumentErrors) {
7610
- effectiveExpectedType = undefined;
7611
- }
7612
7213
  }
7613
7214
  if (effectiveExpectedType) {
7614
7215
  // Prepopulate the typeVarContext based on the specialized expected type if the
@@ -7621,12 +7222,21 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
7621
7222
  (0, types_1.isClassInstance)(effectiveExpectedType) &&
7622
7223
  !types_1.ClassType.isSameGenericClass(effectiveReturnType, effectiveExpectedType)) {
7623
7224
  const tempTypeVarContext = new typeVarContext_1.TypeVarContext((0, typeUtils_1.getTypeVarScopeId)(effectiveReturnType));
7624
- (0, constraintSolver_1.populateTypeVarContextBasedOnExpectedType)(evaluatorInterface, effectiveReturnType, effectiveExpectedType, tempTypeVarContext, getTypeVarScopesForNode(errorNode));
7225
+ (0, constraintSolver_1.populateTypeVarContextBasedOnExpectedType)(evaluatorInterface, effectiveReturnType, effectiveExpectedType, tempTypeVarContext, ParseTreeUtils.getTypeVarScopesForNode(errorNode));
7625
7226
  const genericReturnType = types_1.ClassType.cloneForSpecialization(effectiveReturnType,
7626
7227
  /* typeArguments */ undefined,
7627
7228
  /* isTypeArgumentExplicit */ false);
7628
7229
  effectiveExpectedType = (0, typeUtils_1.applySolvedTypeVars)(genericReturnType, tempTypeVarContext);
7629
7230
  }
7231
+ else if ((0, types_1.isFunction)(effectiveReturnType)) {
7232
+ // If the return type is a callable and the expected type is a union that
7233
+ // includes one or more non-callables, filter those out.
7234
+ if ((0, types_1.isUnion)(effectiveExpectedType)) {
7235
+ effectiveExpectedType = (0, typeUtils_1.mapSubtypes)(effectiveExpectedType, (subtype) => {
7236
+ return (0, typeUtils_1.isCallableType)(subtype) ? subtype : undefined;
7237
+ });
7238
+ }
7239
+ }
7630
7240
  assignType(effectiveReturnType, effectiveExpectedType,
7631
7241
  /* diag */ undefined, typeVarContext,
7632
7242
  /* srcTypeVarContext */ undefined, effectiveFlags | 1024 /* PopulatingExpectedType */);
@@ -7705,12 +7315,21 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
7705
7315
  // is an overload function, skip it during the first pass
7706
7316
  // because the selection of the proper overload may depend
7707
7317
  // on type arguments supplied by other function arguments.
7708
- // Set useNarrowBoundOnly to true the first time through
7709
- // the loop if we're going to go through the loop multiple
7710
- // times.
7711
- const argResult = validateArgType(argParam, typeVarContext, signatureTracker, { type, isIncomplete: matchResults.isTypeIncomplete }, skipUnknownArgCheck,
7712
- /* skipOverloadArg */ i === 0,
7713
- /* isFirstPass */ passCount > 1 && i === 0, typeCondition);
7318
+ // We set useNarrowBoundOnly to true if this is the first
7319
+ // (but not only) pass through the parameter list because a wide
7320
+ // bound on a TypeVar (if a narrow bound has not yet been
7321
+ // established) will unnecessarily constrain the expected type.
7322
+ // If the param type is a "bare" TypeVar, don't use it as an
7323
+ // expected type during the first pass. This causes problems for
7324
+ // cases where the the call expression result can influence the
7325
+ // type of the TypeVar, such as in the expression "min(1, max(2, 0.5))".
7326
+ const argResult = validateArgType(argParam, typeVarContext, signatureTracker, { type, isIncomplete: matchResults.isTypeIncomplete }, {
7327
+ skipUnknownArgCheck,
7328
+ skipOverloadArg: i === 0,
7329
+ skipBareTypeVarExpectedType: i === 0,
7330
+ useNarrowBoundOnly: passCount > 1 && i === 0,
7331
+ conditionFilter: typeCondition,
7332
+ });
7714
7333
  if (argResult.isTypeIncomplete) {
7715
7334
  isTypeIncomplete = true;
7716
7335
  }
@@ -7734,9 +7353,10 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
7734
7353
  const signatureTracker = new typeUtils_1.UniqueSignatureTracker();
7735
7354
  matchResults.argParams.forEach((argParam) => {
7736
7355
  var _a;
7737
- const argResult = validateArgType(argParam, typeVarContext, signatureTracker, { type, isIncomplete: matchResults.isTypeIncomplete }, skipUnknownArgCheck,
7738
- /* skipOverloadArg */ false,
7739
- /* isFirstPass */ false, typeCondition);
7356
+ const argResult = validateArgType(argParam, typeVarContext, signatureTracker, { type, isIncomplete: matchResults.isTypeIncomplete }, {
7357
+ skipUnknownArgCheck,
7358
+ conditionFilter: typeCondition,
7359
+ });
7740
7360
  argResults.push(argResult);
7741
7361
  if (!argResult.isCompatible) {
7742
7362
  argumentErrors = true;
@@ -7797,7 +7417,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
7797
7417
  if (!typeVarScopeNode) {
7798
7418
  break;
7799
7419
  }
7800
- const typeVarScopeId = getScopeIdForNode(typeVarScopeNode);
7420
+ const typeVarScopeId = ParseTreeUtils.getScopeIdForNode(typeVarScopeNode);
7801
7421
  if (typeVarContext.hasSolveForScope(typeVarScopeId)) {
7802
7422
  eliminateUnsolvedInUnions = false;
7803
7423
  }
@@ -7820,7 +7440,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
7820
7440
  let unknownIfNotFound = !(0, types_1.isFunction)(returnType);
7821
7441
  // We'll also leave TypeVars unsolved if the call is a recursive
7822
7442
  // call to a generic function.
7823
- const typeVarScopes = getTypeVarScopesForNode(errorNode);
7443
+ const typeVarScopes = ParseTreeUtils.getTypeVarScopesForNode(errorNode);
7824
7444
  if (typeVarScopes.some((typeVarScope) => typeVarContext.hasSolveForScope(typeVarScope))) {
7825
7445
  unknownIfNotFound = false;
7826
7446
  }
@@ -7896,7 +7516,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
7896
7516
  // Evaluate types of all args. This will ensure that referenced symbols are
7897
7517
  // not reported as unaccessed.
7898
7518
  argList.forEach((arg) => {
7899
- if (arg.valueExpression && !speculativeTypeTracker.isSpeculative(arg.valueExpression)) {
7519
+ if (arg.valueExpression && !isSpeculativeModeInUse(arg.valueExpression)) {
7900
7520
  getTypeOfExpression(arg.valueExpression);
7901
7521
  }
7902
7522
  });
@@ -7906,7 +7526,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
7906
7526
  overloadsUsedForCall: [],
7907
7527
  };
7908
7528
  }
7909
- return validateFunctionArgumentTypesWithExpectedType(errorNode, matchResults, typeVarContext, skipUnknownArgCheck, inferenceContext);
7529
+ return validateFunctionArgumentTypesWithContext(errorNode, matchResults, typeVarContext, skipUnknownArgCheck, inferenceContext);
7910
7530
  }
7911
7531
  // Determines whether the specified argument list satisfies the function
7912
7532
  // signature bound to the specified ParamSpec. Return value indicates success.
@@ -8006,10 +7626,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
8006
7626
  argument: arg,
8007
7627
  errorNode: arg.valueExpression || errorNode,
8008
7628
  }, srcTypeVarContext, signatureTracker,
8009
- /* functionType */ undefined,
8010
- /* skipUnknownArgCheck */ false,
8011
- /* skipOverloadArg */ false,
8012
- /* isFirstPass */ false, conditionFilter);
7629
+ /* functionType */ undefined, { conditionFilter });
8013
7630
  if (!argResult.isCompatible) {
8014
7631
  reportedArgError = true;
8015
7632
  }
@@ -8059,7 +7676,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
8059
7676
  }
8060
7677
  return !reportedArgError;
8061
7678
  }
8062
- function validateArgType(argParam, typeVarContext, signatureTracker, typeResult, skipUnknownCheck, skipOverloadArg, isFirstPass, conditionFilter) {
7679
+ function validateArgType(argParam, typeVarContext, signatureTracker, typeResult, options) {
8063
7680
  var _a;
8064
7681
  let argType;
8065
7682
  let expectedTypeDiag;
@@ -8067,19 +7684,12 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
8067
7684
  let isCompatible = true;
8068
7685
  const functionName = typeResult === null || typeResult === void 0 ? void 0 : typeResult.type.details.name;
8069
7686
  if (argParam.argument.valueExpression) {
8070
- // If the param type is a "bare" TypeVar, don't use it as an expected
8071
- // type during the first pass. This causes problems for cases where the the
8072
- // call expression result can influence the type of the TypeVar, such as in
8073
- // the expression "min(1, max(2, 0.5))". We set useNarrowBoundOnly
8074
- // to true if this is the first pass through the parameter list because
8075
- // a wide bound on a TypeVar (if a narrow bound has not yet been established)
8076
- // will unnecessarily constrain the expected type.
8077
7687
  let expectedType;
8078
- if (!isFirstPass ||
7688
+ if (!options.skipBareTypeVarExpectedType ||
8079
7689
  !(0, types_1.isTypeVar)(argParam.paramType) ||
8080
7690
  argParam.paramType.scopeId !== (typeResult === null || typeResult === void 0 ? void 0 : typeResult.type.details.typeVarScopeId)) {
8081
7691
  expectedType = (0, typeUtils_1.applySolvedTypeVars)(argParam.paramType, typeVarContext, {
8082
- useNarrowBoundOnly: isFirstPass,
7692
+ useNarrowBoundOnly: !!options.useNarrowBoundOnly,
8083
7693
  });
8084
7694
  }
8085
7695
  // If the expected type is unknown, don't use an expected type. Instead,
@@ -8107,9 +7717,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
8107
7717
  }
8108
7718
  expectedTypeDiag = exprTypeResult.expectedTypeDiagAddendum;
8109
7719
  }
8110
- if (argParam.argument &&
8111
- argParam.argument.name &&
8112
- !speculativeTypeTracker.isSpeculative(argParam.errorNode)) {
7720
+ if (argParam.argument && argParam.argument.name && !isSpeculativeModeInUse(argParam.errorNode)) {
8113
7721
  writeTypeCache(argParam.argument.name, { type: expectedType !== null && expectedType !== void 0 ? expectedType : argType, isIncomplete: isTypeIncomplete }, 0 /* None */);
8114
7722
  }
8115
7723
  }
@@ -8148,8 +7756,8 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
8148
7756
  // If there's a constraint filter, apply it to top-level type variables
8149
7757
  // if appropriate. This doesn't properly handle non-top-level constrained
8150
7758
  // type variables.
8151
- if (conditionFilter) {
8152
- argType = mapSubtypesExpandTypeVars(argType, conditionFilter, (expandedSubtype) => {
7759
+ if (options.conditionFilter) {
7760
+ argType = mapSubtypesExpandTypeVars(argType, options.conditionFilter, (expandedSubtype) => {
8153
7761
  return expandedSubtype;
8154
7762
  });
8155
7763
  }
@@ -8168,14 +7776,14 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
8168
7776
  // If we are asked to skip overload arguments, determine whether the argument
8169
7777
  // is an explicit overload type, an overloaded class constructor, or a
8170
7778
  // an overloaded callback protocol.
8171
- if (skipOverloadArg) {
7779
+ if (options.skipOverloadArg) {
8172
7780
  if ((0, types_1.isOverloadedFunction)(argType)) {
8173
7781
  return { isCompatible, argType, isTypeIncomplete, skippedOverloadArg: true, condition };
8174
7782
  }
8175
7783
  const concreteParamType = makeTopLevelTypeVarsConcrete(argParam.paramType);
8176
7784
  if ((0, types_1.isFunction)(concreteParamType) || (0, types_1.isOverloadedFunction)(concreteParamType)) {
8177
7785
  if ((0, types_1.isInstantiableClass)(argType)) {
8178
- const constructor = createFunctionFromConstructor(argType);
7786
+ const constructor = (0, constructors_1.createFunctionFromConstructor)(evaluatorInterface, argType);
8179
7787
  if (constructor && (0, types_1.isOverloadedFunction)(constructor)) {
8180
7788
  return { isCompatible, argType, isTypeIncomplete, skippedOverloadArg: true, condition };
8181
7789
  }
@@ -8244,7 +7852,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
8244
7852
  }
8245
7853
  return { isCompatible: false, argType, isTypeIncomplete, condition };
8246
7854
  }
8247
- if (!skipUnknownCheck) {
7855
+ if (!options.skipUnknownArgCheck) {
8248
7856
  const simplifiedType = (0, types_1.removeUnbound)(argType);
8249
7857
  const fileInfo = AnalyzerNodeInfo.getFileInfo(argParam.errorNode);
8250
7858
  const getDiagAddendum = () => {
@@ -8682,644 +8290,6 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
8682
8290
  }
8683
8291
  return { type };
8684
8292
  }
8685
- function getTypeOfUnaryOperation(node, inferenceContext) {
8686
- const exprTypeResult = getTypeOfExpression(node.expression);
8687
- let exprType = makeTopLevelTypeVarsConcrete(exprTypeResult.type);
8688
- const isIncomplete = exprTypeResult.isIncomplete;
8689
- if ((0, types_1.isNever)(exprType)) {
8690
- return { type: types_1.NeverType.createNever(), isIncomplete };
8691
- }
8692
- // Map unary operators to magic functions. Note that the bitwise
8693
- // invert has two magic functions that are aliases of each other.
8694
- const unaryOperatorMap = {
8695
- [0 /* Add */]: '__pos__',
8696
- [33 /* Subtract */]: '__neg__',
8697
- [5 /* BitwiseInvert */]: '__invert__',
8698
- };
8699
- let type;
8700
- if (node.operator !== 38 /* Not */) {
8701
- if ((0, typeUtils_1.isOptionalType)(exprType)) {
8702
- addDiagnostic(AnalyzerNodeInfo.getFileInfo(node).diagnosticRuleSet.reportOptionalOperand, diagnosticRules_1.DiagnosticRule.reportOptionalOperand, localize_1.Localizer.Diagnostic.noneOperator().format({
8703
- operator: ParseTreeUtils.printOperator(node.operator),
8704
- }), node.expression);
8705
- exprType = (0, types_1.removeNoneFromUnion)(exprType);
8706
- }
8707
- }
8708
- // Handle certain operations on certain literal types
8709
- // using special-case math. Do not apply this if the input type
8710
- // is incomplete because we may be evaluating an expression within
8711
- // a loop, so the literal value may change each time.
8712
- if (!exprTypeResult.isIncomplete) {
8713
- const literalClassName = (0, typeUtils_1.getLiteralTypeClassName)(exprType);
8714
- if (literalClassName === 'int') {
8715
- if (node.operator === 0 /* Add */) {
8716
- type = exprType;
8717
- }
8718
- else if (node.operator === 33 /* Subtract */) {
8719
- type = (0, typeUtils_1.mapSubtypes)(exprType, (subtype) => {
8720
- const classSubtype = subtype;
8721
- return types_1.ClassType.cloneWithLiteral(classSubtype, -classSubtype.literalValue);
8722
- });
8723
- }
8724
- }
8725
- else if (literalClassName === 'bool') {
8726
- if (node.operator === 38 /* Not */) {
8727
- type = (0, typeUtils_1.mapSubtypes)(exprType, (subtype) => {
8728
- const classSubtype = subtype;
8729
- return types_1.ClassType.cloneWithLiteral(classSubtype, !classSubtype.literalValue);
8730
- });
8731
- }
8732
- }
8733
- }
8734
- if (!type) {
8735
- // __not__ always returns a boolean.
8736
- if (node.operator === 38 /* Not */) {
8737
- type = getBuiltInObject(node, 'bool');
8738
- if (!type) {
8739
- type = types_1.UnknownType.create();
8740
- }
8741
- }
8742
- else {
8743
- if ((0, types_1.isAnyOrUnknown)(exprType)) {
8744
- type = exprType;
8745
- }
8746
- else {
8747
- const magicMethodName = unaryOperatorMap[node.operator];
8748
- type = getTypeOfMagicMethodReturn(exprType, [], magicMethodName, node, inferenceContext);
8749
- }
8750
- if (!type) {
8751
- const fileInfo = AnalyzerNodeInfo.getFileInfo(node);
8752
- if (inferenceContext) {
8753
- addDiagnostic(fileInfo.diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.typeNotSupportUnaryOperatorBidirectional().format({
8754
- operator: ParseTreeUtils.printOperator(node.operator),
8755
- type: printType(exprType),
8756
- expectedType: printType(inferenceContext.expectedType),
8757
- }), node);
8758
- }
8759
- else {
8760
- addDiagnostic(fileInfo.diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.typeNotSupportUnaryOperator().format({
8761
- operator: ParseTreeUtils.printOperator(node.operator),
8762
- type: printType(exprType),
8763
- }), node);
8764
- }
8765
- type = types_1.UnknownType.create();
8766
- }
8767
- }
8768
- }
8769
- return { type, isIncomplete };
8770
- }
8771
- function getTypeOfBinaryOperation(node, inferenceContext, flags) {
8772
- const leftExpression = node.leftExpression;
8773
- let rightExpression = node.rightExpression;
8774
- let isIncomplete = false;
8775
- let typeErrors = false;
8776
- // If this is a comparison and the left expression is also a comparison,
8777
- // we need to change the behavior to accommodate python's "chained
8778
- // comparisons" feature.
8779
- if (ParseTreeUtils.operatorSupportsChaining(node.operator)) {
8780
- if (rightExpression.nodeType === 7 /* BinaryOperation */ &&
8781
- !rightExpression.parenthesized &&
8782
- ParseTreeUtils.operatorSupportsChaining(rightExpression.operator)) {
8783
- // Evaluate the right expression so it is type checked.
8784
- getTypeOfBinaryOperation(rightExpression, inferenceContext, flags);
8785
- // Use the left side of the right expression for comparison purposes.
8786
- rightExpression = rightExpression.leftExpression;
8787
- }
8788
- }
8789
- // For most binary operations, the "expected type" is applied to the output
8790
- // of the magic method for that operation. However, the "or" and "and" operators
8791
- // have no magic method, so we apply the expected type directly to both operands.
8792
- let expectedOperandType = node.operator === 37 /* Or */ || node.operator === 36 /* And */
8793
- ? inferenceContext === null || inferenceContext === void 0 ? void 0 : inferenceContext.expectedType
8794
- : undefined;
8795
- // Handle the very special case where the expected type is a list
8796
- // and the operator is a multiply. This comes up in the common case
8797
- // of "x: List[Optional[X]] = [None] * y" where y is an integer literal.
8798
- let expectedLeftOperandType;
8799
- if (node.operator === 26 /* Multiply */ &&
8800
- inferenceContext &&
8801
- (0, types_1.isClassInstance)(inferenceContext.expectedType) &&
8802
- types_1.ClassType.isBuiltIn(inferenceContext.expectedType, 'list') &&
8803
- inferenceContext.expectedType.typeArguments &&
8804
- inferenceContext.expectedType.typeArguments.length >= 1 &&
8805
- node.leftExpression.nodeType === 31 /* List */) {
8806
- expectedLeftOperandType = inferenceContext.expectedType;
8807
- }
8808
- const effectiveExpectedType = expectedOperandType !== null && expectedOperandType !== void 0 ? expectedOperandType : expectedLeftOperandType;
8809
- const leftTypeResult = getTypeOfExpression(leftExpression, flags, (0, typeUtils_1.makeInferenceContext)(effectiveExpectedType));
8810
- let leftType = leftTypeResult.type;
8811
- if (!expectedOperandType) {
8812
- if (node.operator === 37 /* Or */ || node.operator === 36 /* And */) {
8813
- // For "or" and "and", use the type of the left operand. This allows us to
8814
- // infer a better type for expressions like `x or []`.
8815
- expectedOperandType = leftType;
8816
- }
8817
- else if (node.operator === 0 /* Add */ && node.rightExpression.nodeType === 31 /* List */) {
8818
- // For the "+" operator , use this technique only if the right operand is
8819
- // a list expression. This heuristic handles the common case of `my_list + [0]`.
8820
- expectedOperandType = leftType;
8821
- }
8822
- else if (node.operator === 6 /* BitwiseOr */) {
8823
- // If this is a bitwise or ("|"), use the type of the left operand. This allows
8824
- // us to support the case where a TypedDict is being updated with a dict expression.
8825
- if ((0, types_1.isClassInstance)(leftType) && types_1.ClassType.isTypedDictClass(leftType)) {
8826
- expectedOperandType = leftType;
8827
- }
8828
- }
8829
- }
8830
- const rightTypeResult = getTypeOfExpression(rightExpression, flags, (0, typeUtils_1.makeInferenceContext)(expectedOperandType));
8831
- let rightType = rightTypeResult.type;
8832
- if (leftTypeResult.isIncomplete || rightTypeResult.isIncomplete) {
8833
- isIncomplete = true;
8834
- }
8835
- // Is this a "|" operator used in a context where it is supposed to be
8836
- // interpreted as a union operator?
8837
- if (node.operator === 6 /* BitwiseOr */ &&
8838
- !customMetaclassSupportsMethod(leftType, '__or__') &&
8839
- !customMetaclassSupportsMethod(rightType, '__ror__')) {
8840
- let adjustedRightType = rightType;
8841
- let adjustedLeftType = leftType;
8842
- if (!(0, types_1.isNoneInstance)(leftType) && (0, types_1.isNoneInstance)(rightType)) {
8843
- // Handle the special case where "None" is being added to the union
8844
- // with something else. Even though "None" will normally be interpreted
8845
- // as the None singleton object in contexts where a type annotation isn't
8846
- // assumed, we'll allow it here.
8847
- adjustedRightType = types_1.NoneType.createType();
8848
- }
8849
- else if (!(0, types_1.isNoneInstance)(rightType) && (0, types_1.isNoneInstance)(leftType)) {
8850
- adjustedLeftType = types_1.NoneType.createType();
8851
- }
8852
- if ((0, typeUtils_1.isUnionableType)([adjustedLeftType, adjustedRightType])) {
8853
- const fileInfo = AnalyzerNodeInfo.getFileInfo(node);
8854
- const unionNotationSupported = fileInfo.isStubFile ||
8855
- (flags & 4 /* AllowForwardReferences */) !== 0 ||
8856
- fileInfo.executionEnvironment.pythonVersion >= pythonVersion_1.PythonVersion.V3_10;
8857
- if (!unionNotationSupported) {
8858
- // If the left type is Any, we can't say for sure whether this
8859
- // is an illegal syntax or a valid application of the "|" operator.
8860
- if (!(0, types_1.isAnyOrUnknown)(adjustedLeftType)) {
8861
- addError(localize_1.Localizer.Diagnostic.unionSyntaxIllegal(), node, node.operatorToken);
8862
- }
8863
- }
8864
- if (!validateTypeArg({ ...leftTypeResult, node: leftExpression }, { allowVariadicTypeVar: true, allowUnpackedTuples: true }) ||
8865
- !validateTypeArg({ ...rightTypeResult, node: rightExpression }, { allowVariadicTypeVar: true, allowUnpackedTuples: true })) {
8866
- return { type: types_1.UnknownType.create() };
8867
- }
8868
- const newUnion = (0, types_1.combineTypes)([adjustedLeftType, adjustedRightType]);
8869
- if ((0, types_1.isUnion)(newUnion)) {
8870
- types_1.TypeBase.setSpecialForm(newUnion);
8871
- }
8872
- // Check for "stringified" forward reference type expressions. The "|" operator
8873
- // doesn't support these except in certain circumstances. Notably, it can't be used
8874
- // with other strings or with types that are not specialized using an index form.
8875
- if (!fileInfo.isStubFile) {
8876
- let stringNode;
8877
- let otherNode;
8878
- let otherType;
8879
- if (leftExpression.nodeType === 48 /* StringList */) {
8880
- stringNode = leftExpression;
8881
- otherNode = rightExpression;
8882
- otherType = rightType;
8883
- }
8884
- else if (rightExpression.nodeType === 48 /* StringList */) {
8885
- stringNode = rightExpression;
8886
- otherNode = leftExpression;
8887
- otherType = leftType;
8888
- }
8889
- if (stringNode && otherNode && otherType) {
8890
- let isAllowed = true;
8891
- if ((0, types_1.isClass)(otherType)) {
8892
- if (!otherType.isTypeArgumentExplicit || (0, types_1.isClassInstance)(otherType)) {
8893
- isAllowed = false;
8894
- }
8895
- }
8896
- if (!isAllowed) {
8897
- addDiagnostic(fileInfo.diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.unionForwardReferenceNotAllowed(), stringNode);
8898
- }
8899
- }
8900
- }
8901
- return { type: newUnion };
8902
- }
8903
- }
8904
- // Optional checks apply to all operations except for boolean operations.
8905
- let isLeftOptionalType = false;
8906
- if (booleanOperatorMap[node.operator] === undefined) {
8907
- // None is a valid operand for == and != even if the type stub says otherwise.
8908
- if (node.operator === 12 /* Equals */ || node.operator === 28 /* NotEquals */) {
8909
- leftType = (0, types_1.removeNoneFromUnion)(leftType);
8910
- }
8911
- else {
8912
- isLeftOptionalType = (0, typeUtils_1.isOptionalType)(leftType);
8913
- }
8914
- // None is a valid operand for == and != even if the type stub says otherwise.
8915
- if (node.operator === 12 /* Equals */ || node.operator === 28 /* NotEquals */) {
8916
- rightType = (0, types_1.removeNoneFromUnion)(rightType);
8917
- }
8918
- }
8919
- const diag = new diagnostic_1.DiagnosticAddendum();
8920
- // Don't use literal math if either of the operation is within a loop
8921
- // because the literal values may change each time.
8922
- const isLiteralMathAllowed = !ParseTreeUtils.isWithinLoop(node);
8923
- // Don't special-case tuple __add__ if the left type is a union. This
8924
- // can result in an infinite loop if we keep creating new tuple types
8925
- // within a loop construct using __add__.
8926
- const isTupleAddAllowed = !(0, types_1.isUnion)(leftType);
8927
- let type = validateBinaryOperation(node.operator, { type: leftType, isIncomplete: leftTypeResult.isIncomplete }, { type: rightType, isIncomplete: rightTypeResult.isIncomplete }, node, inferenceContext, diag, { isLiteralMathAllowed, isTupleAddAllowed });
8928
- if (!diag.isEmpty() || !type) {
8929
- typeErrors = true;
8930
- if (!isIncomplete) {
8931
- const fileInfo = AnalyzerNodeInfo.getFileInfo(node);
8932
- if (isLeftOptionalType && diag.getMessages().length === 1) {
8933
- // If the left was an optional type and there is just one diagnostic,
8934
- // assume that it was due to a "None" not being supported. Report
8935
- // this as a reportOptionalOperand diagnostic rather than a
8936
- // reportGeneralTypeIssues diagnostic.
8937
- addDiagnostic(AnalyzerNodeInfo.getFileInfo(node).diagnosticRuleSet.reportOptionalOperand, diagnosticRules_1.DiagnosticRule.reportOptionalOperand, localize_1.Localizer.Diagnostic.noneOperator().format({
8938
- operator: ParseTreeUtils.printOperator(node.operator),
8939
- }), node.leftExpression);
8940
- }
8941
- else {
8942
- addDiagnostic(fileInfo.diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.typeNotSupportBinaryOperator().format({
8943
- operator: ParseTreeUtils.printOperator(node.operator),
8944
- leftType: printType(leftType),
8945
- rightType: printType(rightType),
8946
- }) + diag.getString(), node);
8947
- }
8948
- }
8949
- type = types_1.UnknownType.create();
8950
- }
8951
- return { type, isIncomplete, typeErrors };
8952
- }
8953
- function customMetaclassSupportsMethod(type, methodName) {
8954
- if (!(0, types_1.isInstantiableClass)(type)) {
8955
- return false;
8956
- }
8957
- const metaclass = type.details.effectiveMetaclass;
8958
- if (!metaclass || !(0, types_1.isInstantiableClass)(metaclass)) {
8959
- return false;
8960
- }
8961
- if (types_1.ClassType.isBuiltIn(metaclass, 'type')) {
8962
- return false;
8963
- }
8964
- const memberInfo = (0, typeUtils_1.lookUpClassMember)(metaclass, methodName);
8965
- if (!memberInfo) {
8966
- return false;
8967
- }
8968
- if ((0, types_1.isInstantiableClass)(memberInfo.classType) && types_1.ClassType.isBuiltIn(memberInfo.classType, 'type')) {
8969
- return false;
8970
- }
8971
- return true;
8972
- }
8973
- function getTypeOfAugmentedAssignment(node, inferenceContext) {
8974
- const operatorMap = {
8975
- [1 /* AddEqual */]: ['__iadd__', 0 /* Add */],
8976
- [34 /* SubtractEqual */]: ['__isub__', 33 /* Subtract */],
8977
- [27 /* MultiplyEqual */]: ['__imul__', 26 /* Multiply */],
8978
- [14 /* FloorDivideEqual */]: ['__ifloordiv__', 13 /* FloorDivide */],
8979
- [11 /* DivideEqual */]: ['__itruediv__', 10 /* Divide */],
8980
- [25 /* ModEqual */]: ['__imod__', 24 /* Mod */],
8981
- [30 /* PowerEqual */]: ['__ipow__', 29 /* Power */],
8982
- [23 /* MatrixMultiplyEqual */]: ['__imatmul__', 22 /* MatrixMultiply */],
8983
- [4 /* BitwiseAndEqual */]: ['__iand__', 3 /* BitwiseAnd */],
8984
- [7 /* BitwiseOrEqual */]: ['__ior__', 6 /* BitwiseOr */],
8985
- [9 /* BitwiseXorEqual */]: ['__ixor__', 8 /* BitwiseXor */],
8986
- [18 /* LeftShiftEqual */]: ['__ilshift__', 17 /* LeftShift */],
8987
- [32 /* RightShiftEqual */]: ['__irshift__', 31 /* RightShift */],
8988
- };
8989
- let type;
8990
- let typeResult;
8991
- const diag = new diagnostic_1.DiagnosticAddendum();
8992
- const leftTypeResult = getTypeOfExpression(node.leftExpression);
8993
- const leftType = leftTypeResult.type;
8994
- let expectedOperandType;
8995
- if (node.operator === 7 /* BitwiseOrEqual */) {
8996
- // If this is a bitwise or ("|="), use the type of the left operand. This allows
8997
- // us to support the case where a TypedDict is being updated with a dict expression.
8998
- expectedOperandType = leftType;
8999
- }
9000
- const rightTypeResult = getTypeOfExpression(node.rightExpression,
9001
- /* flags */ undefined, (0, typeUtils_1.makeInferenceContext)(expectedOperandType));
9002
- const rightType = rightTypeResult.type;
9003
- const isIncomplete = !!rightTypeResult.isIncomplete || !!leftTypeResult.isIncomplete;
9004
- if ((0, types_1.isNever)(leftType) || (0, types_1.isNever)(rightType)) {
9005
- typeResult = { type: types_1.NeverType.createNever(), isIncomplete };
9006
- }
9007
- else {
9008
- type = mapSubtypesExpandTypeVars(leftType,
9009
- /* conditionFilter */ undefined, (leftSubtypeExpanded, leftSubtypeUnexpanded) => {
9010
- return mapSubtypesExpandTypeVars(rightType, (0, typeUtils_1.getTypeCondition)(leftSubtypeExpanded), (rightSubtypeExpanded, rightSubtypeUnexpanded) => {
9011
- if ((0, types_1.isAnyOrUnknown)(leftSubtypeUnexpanded) || (0, types_1.isAnyOrUnknown)(rightSubtypeUnexpanded)) {
9012
- return (0, typeUtils_1.preserveUnknown)(leftSubtypeUnexpanded, rightSubtypeUnexpanded);
9013
- }
9014
- const magicMethodName = operatorMap[node.operator][0];
9015
- let returnType = getTypeOfMagicMethodReturn(leftSubtypeUnexpanded, [{ type: rightSubtypeUnexpanded, isIncomplete: rightTypeResult.isIncomplete }], magicMethodName, node, inferenceContext);
9016
- if (!returnType && leftSubtypeUnexpanded !== leftSubtypeExpanded) {
9017
- // Try with the expanded left type.
9018
- returnType = getTypeOfMagicMethodReturn(leftSubtypeExpanded, [{ type: rightSubtypeUnexpanded, isIncomplete: rightTypeResult.isIncomplete }], magicMethodName, node, inferenceContext);
9019
- }
9020
- if (!returnType && rightSubtypeUnexpanded !== rightSubtypeExpanded) {
9021
- // Try with the expanded left and right type.
9022
- returnType = getTypeOfMagicMethodReturn(leftSubtypeExpanded, [{ type: rightSubtypeExpanded, isIncomplete: rightTypeResult.isIncomplete }], magicMethodName, node, inferenceContext);
9023
- }
9024
- if (!returnType) {
9025
- // If the LHS class didn't support the magic method for augmented
9026
- // assignment, fall back on the normal binary expression evaluator.
9027
- const binaryOperator = operatorMap[node.operator][1];
9028
- // Don't use literal math if either of the operation is within a loop
9029
- // because the literal values may change each time.
9030
- const isLiteralMathAllowed = !ParseTreeUtils.isWithinLoop(node) &&
9031
- (0, typeUtils_1.getUnionSubtypeCount)(leftType) * (0, typeUtils_1.getUnionSubtypeCount)(rightType) <
9032
- maxLiteralMathSubtypeCount;
9033
- // Don't special-case tuple __add__ if the left type is a union. This
9034
- // can result in an infinite loop if we keep creating new tuple types
9035
- // within a loop construct using __add__.
9036
- const isTupleAddAllowed = !(0, types_1.isUnion)(leftType);
9037
- returnType = validateBinaryOperation(binaryOperator, { type: leftSubtypeUnexpanded, isIncomplete: leftTypeResult.isIncomplete }, { type: rightSubtypeUnexpanded, isIncomplete: rightTypeResult.isIncomplete }, node, inferenceContext, diag, { isLiteralMathAllowed, isTupleAddAllowed });
9038
- }
9039
- return returnType;
9040
- });
9041
- });
9042
- // If the LHS class didn't support the magic method for augmented
9043
- // assignment, fall back on the normal binary expression evaluator.
9044
- if (!diag.isEmpty() || !type || (0, types_1.isNever)(type)) {
9045
- if (!isIncomplete) {
9046
- const fileInfo = AnalyzerNodeInfo.getFileInfo(node);
9047
- addDiagnostic(fileInfo.diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.typeNotSupportBinaryOperator().format({
9048
- operator: ParseTreeUtils.printOperator(node.operator),
9049
- leftType: printType(leftType),
9050
- rightType: printType(rightType),
9051
- }) + diag.getString(), node);
9052
- }
9053
- type = types_1.UnknownType.create();
9054
- }
9055
- typeResult = { type, isIncomplete };
9056
- }
9057
- assignTypeToExpression(node.destExpression, typeResult.type, !!typeResult.isIncomplete, node.rightExpression);
9058
- return typeResult;
9059
- }
9060
- function validateBinaryOperation(operator, leftTypeResult, rightTypeResult, errorNode, inferenceContext, diag, options) {
9061
- const leftType = leftTypeResult.type;
9062
- const rightType = rightTypeResult.type;
9063
- let type;
9064
- let concreteLeftType = makeTopLevelTypeVarsConcrete(leftType);
9065
- if (booleanOperatorMap[operator] !== undefined) {
9066
- // If it's an AND or OR, we need to handle short-circuiting by
9067
- // eliminating any known-truthy or known-falsy types.
9068
- if (operator === 36 /* And */) {
9069
- // If the LHS evaluates to falsy, the And expression will
9070
- // always return the type of the left-hand side.
9071
- if (!canBeTruthy(concreteLeftType)) {
9072
- return leftType;
9073
- }
9074
- // If the LHS evaluates to truthy, the And expression will
9075
- // always return the type of the right-hand side.
9076
- if (!canBeFalsy(concreteLeftType)) {
9077
- return rightType;
9078
- }
9079
- concreteLeftType = removeTruthinessFromType(concreteLeftType);
9080
- if ((0, types_1.isNever)(rightType)) {
9081
- return concreteLeftType;
9082
- }
9083
- }
9084
- else if (operator === 37 /* Or */) {
9085
- // If the LHS evaluates to truthy, the Or expression will
9086
- // always return the type of the left-hand side.
9087
- if (!canBeFalsy(concreteLeftType)) {
9088
- return leftType;
9089
- }
9090
- // If the LHS evaluates to falsy, the Or expression will
9091
- // always return the type of the right-hand side.
9092
- if (!canBeTruthy(concreteLeftType)) {
9093
- return rightType;
9094
- }
9095
- concreteLeftType = removeFalsinessFromType(concreteLeftType);
9096
- if ((0, types_1.isNever)(rightType)) {
9097
- return concreteLeftType;
9098
- }
9099
- }
9100
- if ((0, types_1.isNever)(leftType) || (0, types_1.isNever)(rightType)) {
9101
- return types_1.NeverType.createNever();
9102
- }
9103
- // The "in" and "not in" operators make use of the __contains__
9104
- // magic method.
9105
- if (operator === 41 /* In */ || operator === 42 /* NotIn */) {
9106
- type = mapSubtypesExpandTypeVars(rightType,
9107
- /* conditionFilter */ undefined, (rightSubtypeExpanded, rightSubtypeUnexpanded) => {
9108
- return mapSubtypesExpandTypeVars(concreteLeftType, (0, typeUtils_1.getTypeCondition)(rightSubtypeExpanded), (leftSubtype) => {
9109
- var _a;
9110
- if ((0, types_1.isAnyOrUnknown)(leftSubtype) || (0, types_1.isAnyOrUnknown)(rightSubtypeUnexpanded)) {
9111
- return (0, typeUtils_1.preserveUnknown)(leftSubtype, rightSubtypeExpanded);
9112
- }
9113
- let returnType = getTypeOfMagicMethodReturn(rightSubtypeExpanded, [{ type: leftSubtype, isIncomplete: leftTypeResult.isIncomplete }], '__contains__', errorNode,
9114
- /* inferenceContext */ undefined);
9115
- if (!returnType) {
9116
- // If __contains__ was not supported, fall back
9117
- // on an iterable.
9118
- const iteratorType = (_a = getTypeOfIterator({ type: rightSubtypeExpanded, isIncomplete: rightTypeResult.isIncomplete },
9119
- /* isAsync */ false,
9120
- /* errorNode */ undefined)) === null || _a === void 0 ? void 0 : _a.type;
9121
- if (iteratorType && assignType(iteratorType, leftSubtype)) {
9122
- returnType = getBuiltInObject(errorNode, 'bool');
9123
- }
9124
- }
9125
- if (!returnType) {
9126
- diag.addMessage(localize_1.Localizer.Diagnostic.typeNotSupportBinaryOperator().format({
9127
- operator: ParseTreeUtils.printOperator(operator),
9128
- leftType: printType(leftSubtype),
9129
- rightType: printType(rightSubtypeExpanded),
9130
- }));
9131
- }
9132
- return returnType;
9133
- });
9134
- });
9135
- // Assume that a bool is returned even if the type is unknown
9136
- if (type && !(0, types_1.isNever)(type)) {
9137
- type = getBuiltInObject(errorNode, 'bool');
9138
- }
9139
- }
9140
- else {
9141
- type = mapSubtypesExpandTypeVars(concreteLeftType,
9142
- /* conditionFilter */ undefined, (leftSubtypeExpanded, leftSubtypeUnexpanded) => {
9143
- return mapSubtypesExpandTypeVars(rightType, (0, typeUtils_1.getTypeCondition)(leftSubtypeExpanded), (rightSubtypeExpanded, rightSubtypeUnexpanded) => {
9144
- // If the operator is an AND or OR, we need to combine the two types.
9145
- if (operator === 36 /* And */ || operator === 37 /* Or */) {
9146
- return (0, types_1.combineTypes)([leftSubtypeUnexpanded, rightSubtypeUnexpanded]);
9147
- }
9148
- // The other boolean operators always return a bool value.
9149
- return getBuiltInObject(errorNode, 'bool');
9150
- });
9151
- });
9152
- }
9153
- }
9154
- else if (binaryOperatorMap[operator]) {
9155
- if ((0, types_1.isNever)(leftType) || (0, types_1.isNever)(rightType)) {
9156
- return types_1.NeverType.createNever();
9157
- }
9158
- // Handle certain operations on certain homogenous literal types
9159
- // using special-case math. For example, Literal[1, 2] + Literal[3, 4]
9160
- // should result in Literal[4, 5, 6].
9161
- if (options.isLiteralMathAllowed) {
9162
- const leftLiteralClassName = (0, typeUtils_1.getLiteralTypeClassName)(leftType);
9163
- if (leftLiteralClassName && !(0, typeUtils_1.getTypeCondition)(leftType)) {
9164
- const rightLiteralClassName = (0, typeUtils_1.getLiteralTypeClassName)(rightType);
9165
- if (leftLiteralClassName === rightLiteralClassName &&
9166
- !(0, typeUtils_1.getTypeCondition)(rightType) &&
9167
- (0, typeUtils_1.getUnionSubtypeCount)(leftType) * (0, typeUtils_1.getUnionSubtypeCount)(rightType) < maxLiteralMathSubtypeCount) {
9168
- if (leftLiteralClassName === 'str' || leftLiteralClassName === 'bytes') {
9169
- if (operator === 0 /* Add */) {
9170
- type = (0, typeUtils_1.mapSubtypes)(leftType, (leftSubtype) => {
9171
- return (0, typeUtils_1.mapSubtypes)(rightType, (rightSubtype) => {
9172
- const leftClassSubtype = leftSubtype;
9173
- const rightClassSubtype = rightSubtype;
9174
- return types_1.ClassType.cloneWithLiteral(leftClassSubtype, (leftClassSubtype.literalValue +
9175
- rightClassSubtype.literalValue));
9176
- });
9177
- });
9178
- }
9179
- }
9180
- else if (leftLiteralClassName === 'int') {
9181
- if (operator === 0 /* Add */ ||
9182
- operator === 33 /* Subtract */ ||
9183
- operator === 26 /* Multiply */ ||
9184
- operator === 13 /* FloorDivide */ ||
9185
- operator === 24 /* Mod */) {
9186
- let isValidResult = true;
9187
- type = (0, typeUtils_1.mapSubtypes)(leftType, (leftSubtype) => {
9188
- return (0, typeUtils_1.mapSubtypes)(rightType, (rightSubtype) => {
9189
- try {
9190
- const leftClassSubtype = leftSubtype;
9191
- const rightClassSubtype = rightSubtype;
9192
- const leftLiteralValue = BigInt(leftClassSubtype.literalValue);
9193
- const rightLiteralValue = BigInt(rightClassSubtype.literalValue);
9194
- let newValue;
9195
- if (operator === 0 /* Add */) {
9196
- newValue = leftLiteralValue + rightLiteralValue;
9197
- }
9198
- else if (operator === 33 /* Subtract */) {
9199
- newValue = leftLiteralValue - rightLiteralValue;
9200
- }
9201
- else if (operator === 26 /* Multiply */) {
9202
- newValue = leftLiteralValue * rightLiteralValue;
9203
- }
9204
- else if (operator === 13 /* FloorDivide */) {
9205
- if (rightLiteralValue !== BigInt(0)) {
9206
- newValue = leftLiteralValue / rightLiteralValue;
9207
- }
9208
- }
9209
- else if (operator === 24 /* Mod */) {
9210
- if (rightLiteralValue !== BigInt(0)) {
9211
- newValue = leftLiteralValue % rightLiteralValue;
9212
- }
9213
- }
9214
- if (newValue === undefined) {
9215
- isValidResult = false;
9216
- return undefined;
9217
- }
9218
- else if (typeof newValue === 'number' && isNaN(newValue)) {
9219
- isValidResult = false;
9220
- return undefined;
9221
- }
9222
- else {
9223
- // Convert back to a simple number if it fits. Leave as a bigint
9224
- // if it doesn't.
9225
- if (newValue >= Number.MIN_SAFE_INTEGER &&
9226
- newValue <= Number.MAX_SAFE_INTEGER) {
9227
- newValue = Number(newValue);
9228
- }
9229
- return types_1.ClassType.cloneWithLiteral(leftClassSubtype, newValue);
9230
- }
9231
- }
9232
- catch {
9233
- isValidResult = false;
9234
- return undefined;
9235
- }
9236
- });
9237
- });
9238
- if (!isValidResult) {
9239
- type = undefined;
9240
- }
9241
- }
9242
- }
9243
- }
9244
- }
9245
- }
9246
- if (!type) {
9247
- type = mapSubtypesExpandTypeVars(leftType,
9248
- /* conditionFilter */ undefined, (leftSubtypeExpanded, leftSubtypeUnexpanded) => {
9249
- return mapSubtypesExpandTypeVars(rightType, (0, typeUtils_1.getTypeCondition)(leftSubtypeExpanded), (rightSubtypeExpanded, rightSubtypeUnexpanded) => {
9250
- if ((0, types_1.isAnyOrUnknown)(leftSubtypeUnexpanded) || (0, types_1.isAnyOrUnknown)(rightSubtypeUnexpanded)) {
9251
- return (0, typeUtils_1.preserveUnknown)(leftSubtypeUnexpanded, rightSubtypeUnexpanded);
9252
- }
9253
- // Special-case __add__ for tuples when the types for both tuples are known.
9254
- if (options.isTupleAddAllowed &&
9255
- operator === 0 /* Add */ &&
9256
- (0, types_1.isClassInstance)(leftSubtypeExpanded) &&
9257
- (0, typeUtils_1.isTupleClass)(leftSubtypeExpanded) &&
9258
- leftSubtypeExpanded.tupleTypeArguments &&
9259
- !(0, typeUtils_1.isUnboundedTupleClass)(leftSubtypeExpanded) &&
9260
- (0, types_1.isClassInstance)(rightSubtypeExpanded) &&
9261
- (0, typeUtils_1.isTupleClass)(rightSubtypeExpanded) &&
9262
- rightSubtypeExpanded.tupleTypeArguments &&
9263
- !(0, typeUtils_1.isUnboundedTupleClass)(rightSubtypeExpanded) &&
9264
- tupleClassType &&
9265
- (0, types_1.isInstantiableClass)(tupleClassType)) {
9266
- return types_1.ClassType.cloneAsInstance((0, typeUtils_1.specializeTupleClass)(tupleClassType, [
9267
- ...leftSubtypeExpanded.tupleTypeArguments,
9268
- ...rightSubtypeExpanded.tupleTypeArguments,
9269
- ]));
9270
- }
9271
- const magicMethodName = binaryOperatorMap[operator][0];
9272
- let resultType = getTypeOfMagicMethodReturn(convertFunctionToObject(leftSubtypeUnexpanded), [{ type: rightSubtypeUnexpanded, isIncomplete: rightTypeResult.isIncomplete }], magicMethodName, errorNode, inferenceContext);
9273
- if (!resultType && leftSubtypeUnexpanded !== leftSubtypeExpanded) {
9274
- // Try the expanded left type.
9275
- resultType = getTypeOfMagicMethodReturn(convertFunctionToObject(leftSubtypeExpanded), [{ type: rightSubtypeUnexpanded, isIncomplete: rightTypeResult.isIncomplete }], magicMethodName, errorNode, inferenceContext);
9276
- }
9277
- if (!resultType && rightSubtypeUnexpanded !== rightSubtypeExpanded) {
9278
- // Try the expanded left and right type.
9279
- resultType = getTypeOfMagicMethodReturn(convertFunctionToObject(leftSubtypeExpanded), [{ type: rightSubtypeExpanded, isIncomplete: rightTypeResult.isIncomplete }], magicMethodName, errorNode, inferenceContext);
9280
- }
9281
- if (!resultType) {
9282
- // Try the alternate form (swapping right and left).
9283
- const altMagicMethodName = binaryOperatorMap[operator][1];
9284
- resultType = getTypeOfMagicMethodReturn(convertFunctionToObject(rightSubtypeUnexpanded), [{ type: leftSubtypeUnexpanded, isIncomplete: leftTypeResult.isIncomplete }], altMagicMethodName, errorNode, inferenceContext);
9285
- if (!resultType && rightSubtypeUnexpanded !== rightSubtypeExpanded) {
9286
- // Try the expanded right type.
9287
- resultType = getTypeOfMagicMethodReturn(convertFunctionToObject(rightSubtypeExpanded), [
9288
- {
9289
- type: leftSubtypeUnexpanded,
9290
- isIncomplete: leftTypeResult.isIncomplete,
9291
- },
9292
- ], altMagicMethodName, errorNode, inferenceContext);
9293
- }
9294
- if (!resultType && leftSubtypeUnexpanded !== leftSubtypeExpanded) {
9295
- // Try the expanded right and left type.
9296
- resultType = getTypeOfMagicMethodReturn(convertFunctionToObject(rightSubtypeExpanded), [{ type: leftSubtypeExpanded, isIncomplete: leftTypeResult.isIncomplete }], altMagicMethodName, errorNode, inferenceContext);
9297
- }
9298
- }
9299
- if (!resultType) {
9300
- if (inferenceContext) {
9301
- diag.addMessage(localize_1.Localizer.Diagnostic.typeNotSupportBinaryOperatorBidirectional().format({
9302
- operator: ParseTreeUtils.printOperator(operator),
9303
- leftType: printType(leftSubtypeExpanded),
9304
- rightType: printType(rightSubtypeExpanded),
9305
- expectedType: printType(inferenceContext.expectedType),
9306
- }));
9307
- }
9308
- else {
9309
- diag.addMessage(localize_1.Localizer.Diagnostic.typeNotSupportBinaryOperator().format({
9310
- operator: ParseTreeUtils.printOperator(operator),
9311
- leftType: printType(leftSubtypeExpanded),
9312
- rightType: printType(rightSubtypeExpanded),
9313
- }));
9314
- }
9315
- }
9316
- return resultType;
9317
- });
9318
- });
9319
- }
9320
- }
9321
- return type && (0, types_1.isNever)(type) ? undefined : type;
9322
- }
9323
8293
  function getTypeOfMagicMethodReturn(objType, args, magicMethodName, errorNode, inferenceContext) {
9324
8294
  let magicMethodSupported = true;
9325
8295
  // Create a helper lambda for object subtypes.
@@ -9394,17 +8364,6 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
9394
8364
  }
9395
8365
  return returnType;
9396
8366
  }
9397
- // All functions in Python derive from object, so they inherit all
9398
- // of the capabilities of an object. This function converts a function
9399
- // to an object instance.
9400
- function convertFunctionToObject(type) {
9401
- if ((0, types_1.isFunction)(type) || (0, types_1.isOverloadedFunction)(type)) {
9402
- if (objectType) {
9403
- return objectType;
9404
- }
9405
- }
9406
- return type;
9407
- }
9408
8367
  function getTypeOfDictionary(node, inferenceContext) {
9409
8368
  // If the expected type is a union, analyze for each of the subtypes
9410
8369
  // to find one that matches.
@@ -9480,7 +8439,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
9480
8439
  return undefined;
9481
8440
  }
9482
8441
  const dictTypeVarContext = new typeVarContext_1.TypeVarContext((0, typeUtils_1.getTypeVarScopeId)(builtInDict));
9483
- if (!(0, constraintSolver_1.populateTypeVarContextBasedOnExpectedType)(evaluatorInterface, builtInDict, inferenceContext.expectedType, dictTypeVarContext, getTypeVarScopesForNode(node))) {
8442
+ if (!(0, constraintSolver_1.populateTypeVarContextBasedOnExpectedType)(evaluatorInterface, builtInDict, inferenceContext.expectedType, dictTypeVarContext, ParseTreeUtils.getTypeVarScopesForNode(node))) {
9484
8443
  return undefined;
9485
8444
  }
9486
8445
  const specializedDict = (0, typeUtils_1.applySolvedTypeVars)(types_1.ClassType.cloneAsInstantiable(builtInDict), dictTypeVarContext);
@@ -9491,7 +8450,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
9491
8450
  const expectedValueType = specializedDict.typeArguments[1];
9492
8451
  // Infer the key and value types if possible.
9493
8452
  if (getKeyAndValueTypesFromDictionary(node, keyTypes, valueTypes,
9494
- /* forceStrictInference */ true, expectedKeyType, expectedValueType, undefined, expectedDiagAddendum)) {
8453
+ /* forceStrictInference */ true, expectedKeyType, expectedValueType, undefined, expectedDiagAddendum, inferenceContext)) {
9495
8454
  isIncomplete = true;
9496
8455
  }
9497
8456
  // Dict and MutableMapping types have invariant value types, so they
@@ -9500,10 +8459,9 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
9500
8459
  const isValueTypeInvariant = (0, types_1.isClassInstance)(inferenceContext.expectedType) &&
9501
8460
  (types_1.ClassType.isBuiltIn(inferenceContext.expectedType, 'dict') ||
9502
8461
  types_1.ClassType.isBuiltIn(inferenceContext.expectedType, 'MutableMapping'));
9503
- const specializedKeyType = inferTypeArgFromExpectedType(expectedKeyType, keyTypes.map((result) => result.type),
8462
+ const specializedKeyType = inferTypeArgFromExpectedType((0, typeUtils_1.makeInferenceContext)(expectedKeyType, inferenceContext === null || inferenceContext === void 0 ? void 0 : inferenceContext.typeVarContext), keyTypes.map((result) => result.type),
9504
8463
  /* isNarrowable */ false);
9505
- const specializedValueType = inferTypeArgFromExpectedType(expectedValueType, valueTypes.map((result) => result.type),
9506
- /* isNarrowable */ !isValueTypeInvariant);
8464
+ const specializedValueType = inferTypeArgFromExpectedType((0, typeUtils_1.makeInferenceContext)(expectedValueType, inferenceContext === null || inferenceContext === void 0 ? void 0 : inferenceContext.typeVarContext), valueTypes.map((result) => result.type), !isValueTypeInvariant);
9507
8465
  if (!specializedKeyType || !specializedValueType) {
9508
8466
  return undefined;
9509
8467
  }
@@ -9560,7 +8518,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
9560
8518
  }
9561
8519
  return { type, isIncomplete };
9562
8520
  }
9563
- function getKeyAndValueTypesFromDictionary(node, keyTypes, valueTypes, forceStrictInference, expectedKeyType, expectedValueType, expectedTypedDictEntries, expectedDiagAddendum) {
8521
+ function getKeyAndValueTypesFromDictionary(node, keyTypes, valueTypes, forceStrictInference, expectedKeyType, expectedValueType, expectedTypedDictEntries, expectedDiagAddendum, inferenceContext) {
9564
8522
  let isIncomplete = false;
9565
8523
  // Infer the key and value types if possible.
9566
8524
  node.entries.forEach((entryNode, index) => {
@@ -9568,7 +8526,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
9568
8526
  let addUnknown = true;
9569
8527
  if (entryNode.nodeType === 17 /* DictionaryKeyEntry */) {
9570
8528
  const keyTypeResult = getTypeOfExpression(entryNode.keyExpression,
9571
- /* flags */ undefined, (0, typeUtils_1.makeInferenceContext)(expectedKeyType !== null && expectedKeyType !== void 0 ? expectedKeyType : (forceStrictInference ? types_1.NeverType.createNever() : undefined)));
8529
+ /* flags */ undefined, (0, typeUtils_1.makeInferenceContext)(expectedKeyType !== null && expectedKeyType !== void 0 ? expectedKeyType : (forceStrictInference ? types_1.NeverType.createNever() : undefined), inferenceContext === null || inferenceContext === void 0 ? void 0 : inferenceContext.typeVarContext));
9572
8530
  if (keyTypeResult.isIncomplete) {
9573
8531
  isIncomplete = true;
9574
8532
  }
@@ -9587,12 +8545,12 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
9587
8545
  expectedTypedDictEntries.has(keyType.literalValue)) {
9588
8546
  const effectiveValueType = expectedTypedDictEntries.get(keyType.literalValue).valueType;
9589
8547
  valueTypeResult = getTypeOfExpression(entryNode.valueExpression,
9590
- /* flags */ undefined, (0, typeUtils_1.makeInferenceContext)(effectiveValueType));
8548
+ /* flags */ undefined, (0, typeUtils_1.makeInferenceContext)(effectiveValueType, inferenceContext === null || inferenceContext === void 0 ? void 0 : inferenceContext.typeVarContext));
9591
8549
  }
9592
8550
  else {
9593
8551
  const effectiveValueType = expectedValueType !== null && expectedValueType !== void 0 ? expectedValueType : (forceStrictInference ? types_1.NeverType.createNever() : undefined);
9594
8552
  valueTypeResult = getTypeOfExpression(entryNode.valueExpression,
9595
- /* flags */ undefined, (0, typeUtils_1.makeInferenceContext)(effectiveValueType));
8553
+ /* flags */ undefined, (0, typeUtils_1.makeInferenceContext)(effectiveValueType, inferenceContext === null || inferenceContext === void 0 ? void 0 : inferenceContext.typeVarContext));
9596
8554
  }
9597
8555
  if (expectedDiagAddendum && valueTypeResult.expectedTypeDiagAddendum) {
9598
8556
  expectedDiagAddendum.addAddendum(valueTypeResult.expectedTypeDiagAddendum);
@@ -9616,7 +8574,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
9616
8574
  }
9617
8575
  }
9618
8576
  const unexpandedTypeResult = getTypeOfExpression(entryNode.expandExpression,
9619
- /* flags */ undefined, (0, typeUtils_1.makeInferenceContext)(expectedType));
8577
+ /* flags */ undefined, (0, typeUtils_1.makeInferenceContext)(expectedType, inferenceContext === null || inferenceContext === void 0 ? void 0 : inferenceContext.typeVarContext));
9620
8578
  if (unexpandedTypeResult.isIncomplete) {
9621
8579
  isIncomplete = true;
9622
8580
  }
@@ -9743,7 +8701,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
9743
8701
  return undefined;
9744
8702
  }
9745
8703
  const typeVarContext = new typeVarContext_1.TypeVarContext((0, typeUtils_1.getTypeVarScopeId)(builtInListOrSet));
9746
- if (!(0, constraintSolver_1.populateTypeVarContextBasedOnExpectedType)(evaluatorInterface, builtInListOrSet, inferenceContext.expectedType, typeVarContext, getTypeVarScopesForNode(node))) {
8704
+ if (!(0, constraintSolver_1.populateTypeVarContextBasedOnExpectedType)(evaluatorInterface, builtInListOrSet, inferenceContext.expectedType, typeVarContext, ParseTreeUtils.getTypeVarScopesForNode(node))) {
9747
8705
  return undefined;
9748
8706
  }
9749
8707
  const specializedListOrSet = (0, typeUtils_1.applySolvedTypeVars)(types_1.ClassType.cloneAsInstantiable(builtInListOrSet), typeVarContext);
@@ -9776,10 +8734,9 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
9776
8734
  verifySetEntryOrDictKeyIsHashable(entry, entryTypeResult.type, /* isDictKey */ false);
9777
8735
  }
9778
8736
  });
9779
- const isExpectedTypeListOrSet = (0, types_1.isClassInstance)(inferenceContext.expectedType) &&
8737
+ const isTypeInvariant = (0, types_1.isClassInstance)(inferenceContext.expectedType) &&
9780
8738
  types_1.ClassType.isBuiltIn(inferenceContext.expectedType, builtInClassName);
9781
- const specializedEntryType = inferTypeArgFromExpectedType(expectedEntryType, entryTypes,
9782
- /* isNarrowable */ !isExpectedTypeListOrSet);
8739
+ const specializedEntryType = inferTypeArgFromExpectedType((0, typeUtils_1.makeInferenceContext)(expectedEntryType, inferenceContext === null || inferenceContext === void 0 ? void 0 : inferenceContext.typeVarContext), entryTypes, !isTypeInvariant);
9783
8740
  if (!specializedEntryType) {
9784
8741
  return { type: types_1.UnknownType.create(), isIncomplete, typeErrors: true, expectedTypeDiagAddendum };
9785
8742
  }
@@ -9862,77 +8819,33 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
9862
8819
  addDiagnostic(fileInfo.diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, message + diag.getString(), entry);
9863
8820
  }
9864
8821
  }
9865
- function inferTypeArgFromExpectedType(expectedType, entryTypes, isNarrowable) {
9866
- let targetTypeVar;
9867
- let useSynthesizedTypeVar = false;
9868
- // If the expected type is a TypeVar, use it as a target to find
9869
- // a common (narrowest) type among the entry types.
9870
- if ((0, types_1.isTypeVar)(expectedType)) {
9871
- if (expectedType.details.isParamSpec || expectedType.details.isVariadic) {
9872
- return undefined;
9873
- }
9874
- targetTypeVar = expectedType;
9875
- }
9876
- else {
9877
- // Synthesize a temporary bound type var. We will attempt to assign all list
9878
- // entries to this type var, possibly narrowing the type in the process.
9879
- targetTypeVar = types_1.TypeVarType.createInstance('__typeArg');
9880
- targetTypeVar.details.isSynthesized = true;
9881
- targetTypeVar.details.boundType = makeTopLevelTypeVarsConcrete(expectedType);
9882
- // Use a dummy scope ID. It needs to be a non-empty string.
9883
- targetTypeVar.scopeId = '__typeArgScopeId';
9884
- useSynthesizedTypeVar = true;
9885
- }
9886
- // First, try to assign entries with their literal values stripped.
9887
- // The only time we don't want to strip them is if the expected
9888
- // type explicitly includes literals.
9889
- let typeVarContext = new typeVarContext_1.TypeVarContext(targetTypeVar.scopeId);
9890
- if (useSynthesizedTypeVar) {
9891
- typeVarContext.setTypeVarType(targetTypeVar, isNarrowable ? undefined : expectedType,
9892
- /* narrowBoundNoLiterals */ undefined, expectedType);
9893
- }
9894
- if (entryTypes.every((entryType) => assignType(targetTypeVar, stripLiteralValue(entryType), /* diag */ undefined, typeVarContext))) {
9895
- return (0, typeUtils_1.applySolvedTypeVars)(targetTypeVar, typeVarContext);
9896
- }
9897
- // Allocate a fresh typeVarContext before we try again with literals not stripped.
9898
- typeVarContext = new typeVarContext_1.TypeVarContext(targetTypeVar.scopeId);
9899
- if (useSynthesizedTypeVar) {
9900
- typeVarContext.setTypeVarType(targetTypeVar, isNarrowable ? undefined : expectedType,
9901
- /* narrowBoundNoLiterals */ undefined, expectedType);
9902
- }
9903
- if (entryTypes.every((entryType) => assignType(targetTypeVar, entryType, /* diag */ undefined, typeVarContext))) {
9904
- return (0, typeUtils_1.applySolvedTypeVars)(targetTypeVar, typeVarContext);
8822
+ function inferTypeArgFromExpectedType(inferenceContext, entryTypes, isNarrowable) {
8823
+ var _a;
8824
+ // If the expected type is Any, the resulting type becomes Any.
8825
+ if ((0, types_1.isAnyOrUnknown)(inferenceContext.expectedType)) {
8826
+ return inferenceContext.expectedType;
9905
8827
  }
9906
- return undefined;
9907
- }
9908
- function getTypeOfTernary(node, flags, inferenceContext) {
9909
- getTypeOfExpression(node.testExpression);
9910
- const typesToCombine = [];
9911
- let isIncomplete = false;
9912
- let typeErrors = false;
9913
- const fileInfo = AnalyzerNodeInfo.getFileInfo(node);
9914
- const constExprValue = (0, staticExpressions_1.evaluateStaticBoolExpression)(node.testExpression, fileInfo.executionEnvironment, fileInfo.definedConstants);
9915
- if (constExprValue !== false && isNodeReachable(node.ifExpression)) {
9916
- const ifType = getTypeOfExpression(node.ifExpression, flags, inferenceContext);
9917
- typesToCombine.push(ifType.type);
9918
- if (ifType.isIncomplete) {
9919
- isIncomplete = true;
9920
- }
9921
- if (ifType.typeErrors) {
9922
- typeErrors = true;
8828
+ const typeVarContext = (_a = inferenceContext.typeVarContext) === null || _a === void 0 ? void 0 : _a.clone();
8829
+ let isCompatible = true;
8830
+ entryTypes.forEach((entryType) => {
8831
+ if (isCompatible &&
8832
+ !assignType(inferenceContext.expectedType, entryType, /* diag */ undefined, typeVarContext)) {
8833
+ isCompatible = false;
9923
8834
  }
8835
+ });
8836
+ if (!isCompatible) {
8837
+ return undefined;
9924
8838
  }
9925
- if (constExprValue !== true && isNodeReachable(node.elseExpression)) {
9926
- const elseType = getTypeOfExpression(node.elseExpression, flags, inferenceContext);
9927
- typesToCombine.push(elseType.type);
9928
- if (elseType.isIncomplete) {
9929
- isIncomplete = true;
9930
- }
9931
- if (elseType.typeErrors) {
9932
- typeErrors = true;
9933
- }
8839
+ if (isNarrowable && entryTypes.length > 0) {
8840
+ const combinedTypes = (0, types_1.combineTypes)(entryTypes);
8841
+ return (0, typeUtils_1.containsLiteralType)(inferenceContext.expectedType)
8842
+ ? combinedTypes
8843
+ : stripLiteralValue(combinedTypes);
9934
8844
  }
9935
- return { type: (0, types_1.combineTypes)(typesToCombine), isIncomplete, typeErrors };
8845
+ if (typeVarContext) {
8846
+ return (0, typeUtils_1.applySolvedTypeVars)(inferenceContext.expectedType, typeVarContext);
8847
+ }
8848
+ return inferenceContext.expectedType;
9936
8849
  }
9937
8850
  function getTypeOfYield(node) {
9938
8851
  let expectedYieldType;
@@ -9962,33 +8875,31 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
9962
8875
  return { type: sentType || types_1.UnknownType.create(), isIncomplete };
9963
8876
  }
9964
8877
  function getTypeOfYieldFrom(node) {
9965
- var _a, _b;
9966
8878
  const yieldFromTypeResult = getTypeOfExpression(node.expression);
9967
8879
  const yieldFromType = yieldFromTypeResult.type;
9968
- let generatorTypeArgs = (0, typeUtils_1.getGeneratorTypeArgs)(yieldFromType);
9969
- let returnedType;
9970
- // Is the expression a Generator type?
9971
- if (generatorTypeArgs) {
9972
- returnedType = generatorTypeArgs.length >= 2 ? generatorTypeArgs[2] : types_1.UnknownType.create();
9973
- }
9974
- else if ((0, types_1.isClassInstance)(yieldFromType) && types_1.ClassType.isBuiltIn(yieldFromType, 'Coroutine')) {
8880
+ const returnedType = (0, typeUtils_1.mapSubtypes)(yieldFromType, (yieldFromSubtype) => {
8881
+ var _a, _b;
8882
+ // Is the expression a Generator type?
8883
+ let generatorTypeArgs = (0, typeUtils_1.getGeneratorTypeArgs)(yieldFromSubtype);
8884
+ if (generatorTypeArgs) {
8885
+ return generatorTypeArgs.length >= 2 ? generatorTypeArgs[2] : types_1.UnknownType.create();
8886
+ }
9975
8887
  // Handle old-style (pre-await) Coroutines as a special case.
9976
- returnedType = types_1.UnknownType.create();
9977
- }
9978
- else {
8888
+ if ((0, types_1.isClassInstance)(yieldFromSubtype) && types_1.ClassType.isBuiltIn(yieldFromSubtype, 'Coroutine')) {
8889
+ return types_1.UnknownType.create();
8890
+ }
8891
+ // Handle simple iterables.
9979
8892
  const iterableType = (_b = (_a = getTypeOfIterable(yieldFromTypeResult, /* isAsync */ false, node)) === null || _a === void 0 ? void 0 : _a.type) !== null && _b !== void 0 ? _b : types_1.UnknownType.create();
9980
8893
  // Does the iterable return a Generator?
9981
8894
  generatorTypeArgs = (0, typeUtils_1.getGeneratorTypeArgs)(iterableType);
9982
- if (generatorTypeArgs) {
9983
- returnedType = generatorTypeArgs.length >= 2 ? generatorTypeArgs[2] : types_1.UnknownType.create();
9984
- }
9985
- }
9986
- return { type: returnedType || types_1.UnknownType.create() };
8895
+ return generatorTypeArgs && generatorTypeArgs.length >= 2 ? generatorTypeArgs[2] : types_1.UnknownType.create();
8896
+ });
8897
+ return { type: returnedType };
9987
8898
  }
9988
8899
  function getTypeOfLambda(node, inferenceContext) {
9989
8900
  let isIncomplete = !!(inferenceContext === null || inferenceContext === void 0 ? void 0 : inferenceContext.isTypeIncomplete);
9990
8901
  const functionType = types_1.FunctionType.createInstance('', '', '', 131072 /* PartiallyEvaluated */);
9991
- functionType.details.typeVarScopeId = getScopeIdForNode(node);
8902
+ functionType.details.typeVarScopeId = ParseTreeUtils.getScopeIdForNode(node);
9992
8903
  // Pre-cache the incomplete function type in case the evaluation of the
9993
8904
  // lambda depends on itself.
9994
8905
  writeTypeCache(node, { type: functionType, isIncomplete: true }, 0 /* None */);
@@ -10077,33 +8988,31 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
10077
8988
  type: types_1.UnknownType.create(),
10078
8989
  });
10079
8990
  }
10080
- const expectedReturnType = expectedFunctionType
8991
+ let expectedReturnType = expectedFunctionType
10081
8992
  ? getFunctionEffectiveReturnType(expectedFunctionType)
10082
8993
  : undefined;
8994
+ if (expectedReturnType && (inferenceContext === null || inferenceContext === void 0 ? void 0 : inferenceContext.typeVarContext)) {
8995
+ expectedReturnType = (0, typeUtils_1.applySolvedTypeVars)(expectedReturnType, inferenceContext.typeVarContext);
8996
+ }
10083
8997
  // If we're speculatively evaluating the lambda, create another speculative
10084
8998
  // evaluation scope for the return expression and do not allow retention
10085
8999
  // of the cached types.
10086
9000
  const inferLambdaReturnType = () => {
10087
9001
  const returnTypeResult = getTypeOfExpression(node.expression,
10088
- /* flags */ undefined, (0, typeUtils_1.makeInferenceContext)(expectedReturnType));
9002
+ /* flags */ undefined, (0, typeUtils_1.makeInferenceContext)(expectedReturnType, inferenceContext === null || inferenceContext === void 0 ? void 0 : inferenceContext.typeVarContext));
10089
9003
  functionType.inferredReturnType = returnTypeResult.type;
10090
9004
  if (returnTypeResult.isIncomplete) {
10091
9005
  isIncomplete = true;
10092
9006
  }
10093
9007
  };
10094
- if (speculativeTypeTracker.isSpeculative(node) || (inferenceContext === null || inferenceContext === void 0 ? void 0 : inferenceContext.isTypeIncomplete)) {
10095
- // We need to set allowCacheRetention to false because we don't want to
10096
- // cache the type of the lambda return expression because it depends on
10097
- // the parameter types that we set above, and the speculative type cache
10098
- // doesn't know about that context.
10099
- useSpeculativeMode(node.expression, () => {
10100
- inferLambdaReturnType();
10101
- },
10102
- /* allowCacheRetention */ false);
10103
- }
10104
- else {
9008
+ // We need to set allowCacheRetention to false because we don't want to
9009
+ // cache the type of the lambda return expression because it depends on
9010
+ // the parameter types that we set above, and the speculative type cache
9011
+ // doesn't know about that context.
9012
+ useSpeculativeMode(isSpeculativeModeInUse(node) || (inferenceContext === null || inferenceContext === void 0 ? void 0 : inferenceContext.isTypeIncomplete) ? node.expression : undefined, () => {
10105
9013
  inferLambdaReturnType();
10106
- }
9014
+ },
9015
+ /* allowCacheRetention */ false);
10107
9016
  // Mark the function type as no longer being evaluated.
10108
9017
  functionType.details.flags &= ~131072 /* PartiallyEvaluated */;
10109
9018
  return { type: functionType, isIncomplete };
@@ -10196,7 +9105,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
10196
9105
  // Evaluate the test expression to validate it and mark symbols
10197
9106
  // as referenced. Don't bother doing this if we're in speculative
10198
9107
  // mode because it doesn't affect the element type.
10199
- if (!speculativeTypeTracker.isSpeculative(node.testExpression)) {
9108
+ if (!isSpeculativeModeInUse(node.testExpression)) {
10200
9109
  getTypeOfExpression(node.testExpression);
10201
9110
  }
10202
9111
  }
@@ -10263,7 +9172,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
10263
9172
  function getTypeOfSlice(node) {
10264
9173
  // Evaluate the expressions to report errors and record symbol
10265
9174
  // references. We can skip this if we're executing speculatively.
10266
- if (!speculativeTypeTracker.isSpeculative(node)) {
9175
+ if (!isSpeculativeModeInUse(node)) {
10267
9176
  if (node.startValue) {
10268
9177
  getTypeOfExpression(node.startValue);
10269
9178
  }
@@ -10336,7 +9245,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
10336
9245
  const functionType = types_1.FunctionType.createInstantiable(0 /* None */);
10337
9246
  types_1.TypeBase.setSpecialForm(functionType);
10338
9247
  functionType.details.declaredReturnType = types_1.UnknownType.create();
10339
- functionType.details.typeVarScopeId = getScopeIdForNode(errorNode);
9248
+ functionType.details.typeVarScopeId = ParseTreeUtils.getScopeIdForNode(errorNode);
10340
9249
  if (typeArgs && typeArgs.length > 0) {
10341
9250
  if (typeArgs[0].typeList) {
10342
9251
  const typeList = typeArgs[0].typeList;
@@ -11030,7 +9939,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
11030
9939
  }), errorNode);
11031
9940
  }
11032
9941
  const fileInfo = AnalyzerNodeInfo.getFileInfo(name);
11033
- const typeAliasScopeId = getScopeIdForNode(name);
9942
+ const typeAliasScopeId = ParseTreeUtils.getScopeIdForNode(name);
11034
9943
  const boundTypeVars = typeParameters.filter((typeVar) => typeVar.scopeId !== typeAliasScopeId && typeVar.scopeType === 0 /* Class */);
11035
9944
  if (boundTypeVars.length > 0) {
11036
9945
  addError(localize_1.Localizer.Diagnostic.genericTypeAliasBoundTypeVar().format({
@@ -11251,7 +10160,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
11251
10160
  typeAliasTypeVar = types_1.TypeVarType.createInstantiable(`__type_alias_${typeAliasNameNode.value}`);
11252
10161
  typeAliasTypeVar.details.isSynthesized = true;
11253
10162
  typeAliasTypeVar.details.recursiveTypeAliasName = typeAliasNameNode.value;
11254
- const scopeId = getScopeIdForNode(typeAliasNameNode);
10163
+ const scopeId = ParseTreeUtils.getScopeIdForNode(typeAliasNameNode);
11255
10164
  typeAliasTypeVar.details.recursiveTypeAliasScopeId = scopeId;
11256
10165
  typeAliasTypeVar.scopeId = scopeId;
11257
10166
  // Write the type back to the type cache. It will be replaced below.
@@ -11360,7 +10269,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
11360
10269
  const typeAliasTypeVar = types_1.TypeVarType.createInstantiable(`__type_alias_${node.name.value}`);
11361
10270
  typeAliasTypeVar.details.isSynthesized = true;
11362
10271
  typeAliasTypeVar.details.recursiveTypeAliasName = node.name.value;
11363
- const scopeId = getScopeIdForNode(node.name);
10272
+ const scopeId = ParseTreeUtils.getScopeIdForNode(node.name);
11364
10273
  typeAliasTypeVar.details.recursiveTypeAliasScopeId = scopeId;
11365
10274
  typeAliasTypeVar.scopeId = scopeId;
11366
10275
  // Write the type to the type cache. It will be replaced below.
@@ -11403,7 +10312,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
11403
10312
  if (isTypeCached(node)) {
11404
10313
  return;
11405
10314
  }
11406
- const destTypeResult = getTypeOfAugmentedAssignment(node, /* inferenceContext */ undefined);
10315
+ const destTypeResult = (0, operations_1.getTypeOfAugmentedAssignment)(evaluatorInterface, node, /* inferenceContext */ undefined);
11407
10316
  writeTypeCache(node, destTypeResult, 0 /* None */);
11408
10317
  }
11409
10318
  function getPseudoGenericTypeVarName(paramName) {
@@ -11449,7 +10358,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
11449
10358
  /* typeSourceId */ 0,
11450
10359
  /* declaredMetaclass */ undefined,
11451
10360
  /* effectiveMetaclass */ undefined, ParseTreeUtils.getDocString(node.suite.statements));
11452
- classType.details.typeVarScopeId = getScopeIdForNode(node);
10361
+ classType.details.typeVarScopeId = ParseTreeUtils.getScopeIdForNode(node);
11453
10362
  // Some classes refer to themselves within type arguments used within
11454
10363
  // base classes. We'll register the partially-constructed class type
11455
10364
  // to allow these to be resolved.
@@ -11766,9 +10675,9 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
11766
10675
  classType.details.typeParameters = genericParams.map((param) => {
11767
10676
  const typeVar = types_1.TypeVarType.createInstance(getPseudoGenericTypeVarName(param.name.value));
11768
10677
  typeVar.details.isSynthesized = true;
11769
- typeVar.scopeId = getScopeIdForNode(initDeclNode);
10678
+ typeVar.scopeId = ParseTreeUtils.getScopeIdForNode(initDeclNode);
11770
10679
  typeVar.details.boundType = types_1.UnknownType.create();
11771
- return types_1.TypeVarType.cloneForScopeId(typeVar, getScopeIdForNode(node), node.name.value, 0 /* Class */);
10680
+ return types_1.TypeVarType.cloneForScopeId(typeVar, ParseTreeUtils.getScopeIdForNode(node), node.name.value, 0 /* Class */);
11772
10681
  });
11773
10682
  }
11774
10683
  }
@@ -11898,11 +10807,6 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
11898
10807
  writeTypeCache(node.name, { type: classType }, 0 /* None */);
11899
10808
  // Update the decorated class type.
11900
10809
  writeTypeCache(node, { type: decoratedType }, 0 /* None */);
11901
- // Stash away a reference to the UnionType class if we encounter it.
11902
- // There's no easy way to otherwise reference it.
11903
- if (types_1.ClassType.isBuiltIn(classType, 'UnionType')) {
11904
- unionType = types_1.ClassType.cloneAsInstance(classType);
11905
- }
11906
10810
  // Validate that arguments passed to `__init_subclass__` are of the correct type.
11907
10811
  // Defer this if the metaclass calculation is deferred.
11908
10812
  if (!isMetaclassDeferred) {
@@ -12257,11 +11161,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
12257
11161
  argument: arg,
12258
11162
  errorNode: (_b = arg.valueExpression) !== null && _b !== void 0 ? _b : errorNode,
12259
11163
  };
12260
- validateArgType(argParam, new typeVarContext_1.TypeVarContext(), signatureTracker, { type: newMethodType },
12261
- /* skipUnknownCheck */ true,
12262
- /* skipOverloadArg */ true,
12263
- /* useNarrowBoundOnly */ false,
12264
- /* conditionFilter */ undefined);
11164
+ validateArgType(argParam, new typeVarContext_1.TypeVarContext(), signatureTracker, { type: newMethodType }, { skipUnknownArgCheck: true, skipOverloadArg: true });
12265
11165
  paramMap.delete(arg.name.value);
12266
11166
  }
12267
11167
  else {
@@ -12341,10 +11241,10 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
12341
11241
  functionFlags |= 512 /* Async */;
12342
11242
  }
12343
11243
  const functionType = types_1.FunctionType.createInstance(node.name.value, getFunctionFullName(node, fileInfo.moduleName, node.name.value), fileInfo.moduleName, functionFlags | 131072 /* PartiallyEvaluated */, ParseTreeUtils.getDocString(node.suite.statements));
12344
- functionType.details.typeVarScopeId = getScopeIdForNode(node);
11244
+ functionType.details.typeVarScopeId = ParseTreeUtils.getScopeIdForNode(node);
12345
11245
  if (node.name.value === '__init__' || node.name.value === '__new__') {
12346
11246
  if (containingClassNode) {
12347
- functionType.details.constructorTypeVarScopeId = getScopeIdForNode(containingClassNode);
11247
+ functionType.details.constructorTypeVarScopeId = ParseTreeUtils.getScopeIdForNode(containingClassNode);
12348
11248
  }
12349
11249
  }
12350
11250
  if (fileInfo.isBuiltInStubFile || fileInfo.isTypingStubFile || fileInfo.isTypingExtensionsStubFile) {
@@ -13681,9 +12581,9 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
13681
12581
  (0, debug_1.assert)(aliasDecl.type === 8 /* Alias */);
13682
12582
  const fileInfo = AnalyzerNodeInfo.getFileInfo(node);
13683
12583
  // Try to resolve the alias while honoring external visibility.
13684
- const resolvedAliasInfo = resolveAliasDeclarationWithInfo(aliasDecl,
13685
- /* resolveLocalNames */ true,
13686
- /* allowExternallyHiddenAccess */ fileInfo.isStubFile);
12584
+ const resolvedAliasInfo = resolveAliasDeclarationWithInfo(aliasDecl, /* resolveLocalNames */ true, {
12585
+ allowExternallyHiddenAccess: fileInfo.isStubFile,
12586
+ });
13687
12587
  if (!resolvedAliasInfo) {
13688
12588
  return undefined;
13689
12589
  }
@@ -14696,10 +13596,14 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
14696
13596
  throw e;
14697
13597
  }
14698
13598
  }
14699
- // Disables recording of errors and warnings and disables
14700
- // any caching of types, under the assumption that we're
14701
- // performing speculative evaluations.
13599
+ // Disables recording of errors and warnings and disables any caching of
13600
+ // types, under the assumption that we're performing speculative evaluations.
13601
+ // If speculativeNode is undefined, speculative mode is not used. This is
13602
+ // useful in cases where we conditionally want to use speculative mode.
14702
13603
  function useSpeculativeMode(speculativeNode, callback, allowCacheRetention = true) {
13604
+ if (!speculativeNode) {
13605
+ return callback();
13606
+ }
14703
13607
  speculativeTypeTracker.enterSpeculativeContext(speculativeNode, allowCacheRetention);
14704
13608
  try {
14705
13609
  const result = callback();
@@ -14726,6 +13630,12 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
14726
13630
  throw e;
14727
13631
  }
14728
13632
  }
13633
+ // Indicates whether the specified node is within a context that
13634
+ // is currently being evaluated speculative. If node is undefined,
13635
+ // returns true if any node is being evaluated speculatively.
13636
+ function isSpeculativeModeInUse(node) {
13637
+ return speculativeTypeTracker.isSpeculative(node);
13638
+ }
14729
13639
  function getDeclarationFromFunctionNamedParameter(type, paramName) {
14730
13640
  if ((0, types_1.isFunction)(type)) {
14731
13641
  if (type.details.declaration) {
@@ -15155,15 +14065,15 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
15155
14065
  (0, debug_1.assert)(scopeNode.nodeType === 77 /* TypeAlias */);
15156
14066
  scopeType = 2 /* TypeAlias */;
15157
14067
  }
15158
- typeVar = types_1.TypeVarType.cloneForScopeId(typeVar, getScopeIdForNode(scopeNode.nodeType === 77 /* TypeAlias */ ? scopeNode.name : scopeNode), scopeNode.name.value, scopeType);
14068
+ typeVar = types_1.TypeVarType.cloneForScopeId(typeVar, ParseTreeUtils.getScopeIdForNode(scopeNode.nodeType === 77 /* TypeAlias */ ? scopeNode.name : scopeNode), scopeNode.name.value, scopeType);
15159
14069
  }
15160
14070
  return typeVar;
15161
14071
  }
15162
14072
  function getInferredTypeOfDeclaration(symbol, decl) {
15163
14073
  var _a, _b, _c;
15164
- const resolvedDecl = resolveAliasDeclaration(decl,
15165
- /* resolveLocalNames */ true,
15166
- /* allowExternallyHiddenAccess */ AnalyzerNodeInfo.getFileInfo(decl.node).isStubFile);
14074
+ const resolvedDecl = resolveAliasDeclaration(decl, /* resolveLocalNames */ true, {
14075
+ allowExternallyHiddenAccess: AnalyzerNodeInfo.getFileInfo(decl.node).isStubFile,
14076
+ });
15167
14077
  // We couldn't resolve the alias. Substitute an unknown
15168
14078
  // type in this case.
15169
14079
  if (!resolvedDecl) {
@@ -15395,12 +14305,21 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
15395
14305
  // associated with that symbol. It does this recursively if necessary. If a symbol
15396
14306
  // lookup fails, undefined is returned. If resolveLocalNames is true, the method
15397
14307
  // resolves aliases through local renames ("as" clauses found in import statements).
15398
- function resolveAliasDeclaration(declaration, resolveLocalNames, allowExternallyHiddenAccess = false) {
15399
- var _a;
15400
- return (_a = (0, declarationUtils_1.resolveAliasDeclaration)(importLookup, declaration, resolveLocalNames, allowExternallyHiddenAccess)) === null || _a === void 0 ? void 0 : _a.declaration;
14308
+ function resolveAliasDeclaration(declaration, resolveLocalNames, options) {
14309
+ var _a, _b, _c;
14310
+ return (_c = (0, declarationUtils_1.resolveAliasDeclaration)(importLookup, declaration, {
14311
+ resolveLocalNames,
14312
+ allowExternallyHiddenAccess: (_a = options === null || options === void 0 ? void 0 : options.allowExternallyHiddenAccess) !== null && _a !== void 0 ? _a : false,
14313
+ skipFileNeededCheck: (_b = options === null || options === void 0 ? void 0 : options.skipFileNeededCheck) !== null && _b !== void 0 ? _b : false,
14314
+ })) === null || _c === void 0 ? void 0 : _c.declaration;
15401
14315
  }
15402
- function resolveAliasDeclarationWithInfo(declaration, resolveLocalNames, allowExternallyHiddenAccess = false) {
15403
- return (0, declarationUtils_1.resolveAliasDeclaration)(importLookup, declaration, resolveLocalNames, allowExternallyHiddenAccess);
14316
+ function resolveAliasDeclarationWithInfo(declaration, resolveLocalNames, options) {
14317
+ var _a, _b;
14318
+ return (0, declarationUtils_1.resolveAliasDeclaration)(importLookup, declaration, {
14319
+ resolveLocalNames,
14320
+ allowExternallyHiddenAccess: (_a = options === null || options === void 0 ? void 0 : options.allowExternallyHiddenAccess) !== null && _a !== void 0 ? _a : false,
14321
+ skipFileNeededCheck: (_b = options === null || options === void 0 ? void 0 : options.skipFileNeededCheck) !== null && _b !== void 0 ? _b : false,
14322
+ });
15404
14323
  }
15405
14324
  // Returns the type of the symbol. If the type is explicitly declared, that type
15406
14325
  // is returned. If not, the type is inferred from assignments to the symbol. All
@@ -15523,9 +14442,9 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
15523
14442
  }
15524
14443
  }
15525
14444
  if (considerDecl) {
15526
- const resolvedDecl = (_a = resolveAliasDeclaration(decl,
15527
- /* resolveLocalNames */ true,
15528
- /* allowExternallyHiddenAccess */ AnalyzerNodeInfo.getFileInfo(decl.node).isStubFile)) !== null && _a !== void 0 ? _a : decl;
14445
+ const resolvedDecl = (_a = resolveAliasDeclaration(decl, /* resolveLocalNames */ true, {
14446
+ allowExternallyHiddenAccess: AnalyzerNodeInfo.getFileInfo(decl.node).isStubFile,
14447
+ })) !== null && _a !== void 0 ? _a : decl;
15529
14448
  const isExplicitTypeAlias = isExplicitTypeAliasDeclaration(resolvedDecl);
15530
14449
  const isTypeAlias = isExplicitTypeAlias || isPossibleTypeAliasOrTypedDict(resolvedDecl);
15531
14450
  if (isExplicitTypeAlias) {
@@ -15572,7 +14491,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
15572
14491
  }
15573
14492
  }
15574
14493
  typesToCombine.push(type);
15575
- if (speculativeTypeTracker.isSpeculative(decl.node)) {
14494
+ if (isSpeculativeModeInUse(decl.node)) {
15576
14495
  includesSpeculativeResult = true;
15577
14496
  }
15578
14497
  }
@@ -16239,6 +15158,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
16239
15158
  // specified inheritance chain, taking into account its type arguments.
16240
15159
  function assignClassWithTypeArgs(destType, srcType, inheritanceChain, diag, destTypeVarContext, srcTypeVarContext, flags, recursionCount) {
16241
15160
  let curSrcType = srcType;
15161
+ let prevSrcType;
16242
15162
  let curDestTypeVarContext = destTypeVarContext;
16243
15163
  let effectiveFlags = flags;
16244
15164
  inferTypeParameterVarianceForClass(destType);
@@ -16268,7 +15188,16 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
16268
15188
  // If this isn't the first time through the loop, specialize
16269
15189
  // for the next ancestor in the chain.
16270
15190
  if (ancestorIndex < inheritanceChain.length - 1) {
16271
- curSrcType = (0, typeUtils_1.specializeForBaseClass)(curSrcType, ancestorType);
15191
+ // If the curSrcType is a NamedTuple and the ancestorType is a tuple,
15192
+ // we need to handle this as a special case because the NamedTuple may
15193
+ // include typeParams from its parent class.
15194
+ let effectiveCurSrcType = curSrcType;
15195
+ if (types_1.ClassType.isBuiltIn(curSrcType, 'NamedTuple') &&
15196
+ types_1.ClassType.isBuiltIn(ancestorType, 'tuple') &&
15197
+ prevSrcType) {
15198
+ effectiveCurSrcType = prevSrcType;
15199
+ }
15200
+ curSrcType = (0, typeUtils_1.specializeForBaseClass)(effectiveCurSrcType, ancestorType);
16272
15201
  }
16273
15202
  // Handle built-in types that support arbitrary numbers
16274
15203
  // of type parameters like Tuple.
@@ -16291,6 +15220,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
16291
15220
  // Allocate a new type var map for the next time through the loop.
16292
15221
  curDestTypeVarContext = new typeVarContext_1.TypeVarContext((0, typeUtils_1.getTypeVarScopeId)(ancestorType));
16293
15222
  effectiveFlags &= ~8 /* SkipSolveTypeVars */;
15223
+ prevSrcType = curSrcType;
16294
15224
  }
16295
15225
  if (destType.typeArguments) {
16296
15226
  // If the dest type is specialized, make sure the specialized source
@@ -16623,11 +15553,6 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
16623
15553
  }
16624
15554
  return true;
16625
15555
  }
16626
- // Handle the special case where the expression is an actual
16627
- // UnionType special form.
16628
- if ((0, types_1.isUnion)(srcType) && types_1.TypeBase.isSpecialForm(srcType)) {
16629
- srcType = unionType || objectType || types_1.AnyType.create();
16630
- }
16631
15556
  if ((0, types_1.isUnion)(destType)) {
16632
15557
  if ((0, types_1.isUnion)(srcType)) {
16633
15558
  if (assignFromUnionType(destType, srcType,
@@ -16854,7 +15779,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
16854
15779
  }
16855
15780
  // If it's a class, use the constructor for type compatibility checking.
16856
15781
  if ((0, types_1.isInstantiableClass)(concreteSrcType) && concreteSrcType.literalValue === undefined) {
16857
- const constructor = createFunctionFromConstructor(concreteSrcType, recursionCount);
15782
+ const constructor = (0, constructors_1.createFunctionFromConstructor)(evaluatorInterface, concreteSrcType, recursionCount);
16858
15783
  if (constructor) {
16859
15784
  concreteSrcType = constructor;
16860
15785
  }
@@ -17301,98 +16226,6 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
17301
16226
  });
17302
16227
  });
17303
16228
  }
17304
- // Synthesize a function that represents the constructor for this class
17305
- // taking into consideration the __init__ and __new__ methods.
17306
- function createFunctionFromConstructor(classType, recursionCount = 0) {
17307
- // Use the __init__ method if available. It's usually more detailed.
17308
- const initInfo = (0, typeUtils_1.lookUpClassMember)(classType, '__init__', 8 /* SkipInstanceVariables */ | 4 /* SkipObjectBaseClass */);
17309
- if (initInfo) {
17310
- const initType = getTypeOfMember(initInfo);
17311
- const objectType = types_1.ClassType.cloneAsInstance(classType);
17312
- const convertInitToConstructor = (initSubtype) => {
17313
- let constructorFunction = bindFunctionToClassOrObject(objectType, initSubtype,
17314
- /* memberClass */ undefined,
17315
- /* errorNode */ undefined, recursionCount);
17316
- if (constructorFunction) {
17317
- constructorFunction = types_1.FunctionType.clone(constructorFunction);
17318
- constructorFunction.details.declaredReturnType = objectType;
17319
- if (constructorFunction.specializedTypes) {
17320
- constructorFunction.specializedTypes.returnType = objectType;
17321
- }
17322
- if (!constructorFunction.details.docString && classType.details.docString) {
17323
- constructorFunction.details.docString = classType.details.docString;
17324
- }
17325
- constructorFunction.details.flags &= ~4 /* StaticMethod */;
17326
- }
17327
- return constructorFunction;
17328
- };
17329
- if ((0, types_1.isFunction)(initType)) {
17330
- return convertInitToConstructor(initType);
17331
- }
17332
- else if ((0, types_1.isOverloadedFunction)(initType)) {
17333
- const initOverloads = [];
17334
- initType.overloads.forEach((overload) => {
17335
- const converted = convertInitToConstructor(overload);
17336
- if (converted) {
17337
- initOverloads.push(converted);
17338
- }
17339
- });
17340
- if (initOverloads.length === 0) {
17341
- return undefined;
17342
- }
17343
- else if (initOverloads.length === 1) {
17344
- return initOverloads[0];
17345
- }
17346
- return types_1.OverloadedFunctionType.create(initOverloads);
17347
- }
17348
- }
17349
- // Fall back on the __new__ method if __init__ isn't available.
17350
- const newInfo = (0, typeUtils_1.lookUpClassMember)(classType, '__new__', 8 /* SkipInstanceVariables */ | 4 /* SkipObjectBaseClass */);
17351
- if (newInfo) {
17352
- const newType = getTypeOfMember(newInfo);
17353
- const convertNewToConstructor = (newSubtype) => {
17354
- let constructorFunction = bindFunctionToClassOrObject(classType, newSubtype,
17355
- /* memberClass */ undefined,
17356
- /* errorNode */ undefined, recursionCount,
17357
- /* treatConstructorAsClassMember */ true);
17358
- if (constructorFunction) {
17359
- constructorFunction = types_1.FunctionType.clone(constructorFunction);
17360
- if (!constructorFunction.details.docString && classType.details.docString) {
17361
- constructorFunction.details.docString = classType.details.docString;
17362
- }
17363
- constructorFunction.details.flags &= ~(4 /* StaticMethod */ | 1 /* ConstructorMethod */);
17364
- }
17365
- return constructorFunction;
17366
- };
17367
- if ((0, types_1.isFunction)(newType)) {
17368
- return convertNewToConstructor(newType);
17369
- }
17370
- else if ((0, types_1.isOverloadedFunction)(newType)) {
17371
- const newOverloads = [];
17372
- newType.overloads.forEach((overload) => {
17373
- const converted = convertNewToConstructor(overload);
17374
- if (converted) {
17375
- newOverloads.push(converted);
17376
- }
17377
- });
17378
- if (newOverloads.length === 0) {
17379
- return undefined;
17380
- }
17381
- else if (newOverloads.length === 1) {
17382
- return newOverloads[0];
17383
- }
17384
- return types_1.OverloadedFunctionType.create(newOverloads);
17385
- }
17386
- }
17387
- // Return a generic constructor.
17388
- const constructorFunction = types_1.FunctionType.createSynthesizedInstance('__new__', 0 /* None */);
17389
- constructorFunction.details.declaredReturnType = types_1.ClassType.cloneAsInstance(classType);
17390
- types_1.FunctionType.addDefaultParameters(constructorFunction);
17391
- if (!constructorFunction.details.docString && classType.details.docString) {
17392
- constructorFunction.details.docString = classType.details.docString;
17393
- }
17394
- return constructorFunction;
17395
- }
17396
16229
  // If the class is a protocol and it has a `__call__` method but no other methods
17397
16230
  // or attributes that would be incompatible with a function, this method returns
17398
16231
  // the signature of the call implied by the `__call__` method. Otherwise it returns
@@ -17784,7 +16617,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
17784
16617
  const srcParamType = srcParamInfo.type;
17785
16618
  if (!destParamInfo) {
17786
16619
  if (destParamDetails.kwargsIndex === undefined && !srcParamInfo.param.hasDefault) {
17787
- if (paramDiag) {
16620
+ if (paramDiag && srcParamDetails.firstKeywordOnlyIndex !== undefined) {
17788
16621
  paramDiag.addMessage(localize_1.Localizer.DiagnosticAddendum.namedParamMissingInDest().format({
17789
16622
  name: srcParamInfo.param.name,
17790
16623
  }));
@@ -18153,213 +16986,224 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
18153
16986
  const baseParamDetails = (0, parameterUtils_1.getParameterListDetails)(baseMethod);
18154
16987
  const overrideParamDetails = (0, parameterUtils_1.getParameterListDetails)(overrideMethod);
18155
16988
  let canOverride = true;
18156
- // Verify that we're not overriding a static, class or instance method with
18157
- // an incompatible type.
18158
- if (types_1.FunctionType.isStaticMethod(baseMethod)) {
18159
- if (!types_1.FunctionType.isStaticMethod(overrideMethod)) {
18160
- diag === null || diag === void 0 ? void 0 : diag.addMessage(localize_1.Localizer.DiagnosticAddendum.overrideNotStaticMethod());
18161
- canOverride = false;
18162
- }
18163
- }
18164
- else if (types_1.FunctionType.isClassMethod(baseMethod)) {
18165
- if (!types_1.FunctionType.isClassMethod(overrideMethod)) {
18166
- diag === null || diag === void 0 ? void 0 : diag.addMessage(localize_1.Localizer.DiagnosticAddendum.overrideNotClassMethod());
18167
- canOverride = false;
18168
- }
18169
- }
18170
- if (types_1.FunctionType.isInstanceMethod(baseMethod)) {
18171
- if (!types_1.FunctionType.isInstanceMethod(overrideMethod)) {
18172
- diag === null || diag === void 0 ? void 0 : diag.addMessage(localize_1.Localizer.DiagnosticAddendum.overrideNotInstanceMethod());
18173
- canOverride = false;
18174
- }
18175
- }
18176
- // Verify that the positional param count matches exactly or that the override
18177
- // adds only params that preserve the original signature.
18178
- let foundParamCountMismatch = false;
18179
- if (overrideParamDetails.positionParamCount < baseParamDetails.positionParamCount) {
18180
- if (overrideParamDetails.argsIndex === undefined) {
18181
- foundParamCountMismatch = true;
18182
- }
18183
- else {
18184
- const overrideArgsType = overrideParamDetails.params[overrideParamDetails.argsIndex].type;
18185
- for (let i = overrideParamDetails.positionParamCount; i < baseParamDetails.positionParamCount; i++) {
18186
- if (!assignType(overrideArgsType, baseParamDetails.params[i].type, diag === null || diag === void 0 ? void 0 : diag.createAddendum(), new typeVarContext_1.TypeVarContext((0, typeUtils_1.getTypeVarScopeId)(overrideMethod)), new typeVarContext_1.TypeVarContext((0, typeUtils_1.getTypeVarScopeId)(baseMethod)), 8 /* SkipSolveTypeVars */)) {
18187
- localize_1.Localizer.DiagnosticAddendum.overrideParamType().format({
18188
- index: i + 1,
18189
- baseType: printType(baseParamDetails.params[i].type),
18190
- overrideType: printType(overrideArgsType),
18191
- });
18192
- canOverride = false;
18193
- }
16989
+ if (!types_1.FunctionType.shouldSkipArgsKwargsCompatibilityCheck(baseMethod) &&
16990
+ !types_1.FunctionType.shouldSkipArgsKwargsCompatibilityCheck(overrideMethod)) {
16991
+ // Verify that we're not overriding a static, class or instance method with
16992
+ // an incompatible type.
16993
+ if (types_1.FunctionType.isStaticMethod(baseMethod)) {
16994
+ if (!types_1.FunctionType.isStaticMethod(overrideMethod)) {
16995
+ diag === null || diag === void 0 ? void 0 : diag.addMessage(localize_1.Localizer.DiagnosticAddendum.overrideNotStaticMethod());
16996
+ canOverride = false;
18194
16997
  }
18195
16998
  }
18196
- }
18197
- else if (overrideParamDetails.positionParamCount > baseParamDetails.positionParamCount) {
18198
- // Verify that all of the override parameters that extend the
18199
- // signature are either *args, **kwargs or parameters with
18200
- // default values.
18201
- for (let i = baseParamDetails.positionParamCount; i < overrideParamDetails.positionParamCount; i++) {
18202
- const overrideParam = overrideParamDetails.params[i].param;
18203
- if (overrideParam.category === 0 /* Simple */ &&
18204
- overrideParam.name &&
18205
- !overrideParam.hasDefault) {
18206
- foundParamCountMismatch = true;
16999
+ else if (types_1.FunctionType.isClassMethod(baseMethod)) {
17000
+ if (!types_1.FunctionType.isClassMethod(overrideMethod)) {
17001
+ diag === null || diag === void 0 ? void 0 : diag.addMessage(localize_1.Localizer.DiagnosticAddendum.overrideNotClassMethod());
17002
+ canOverride = false;
18207
17003
  }
18208
17004
  }
18209
- }
18210
- if (foundParamCountMismatch) {
18211
- diag === null || diag === void 0 ? void 0 : diag.addMessage(localize_1.Localizer.DiagnosticAddendum.overridePositionalParamCount().format({
18212
- baseCount: baseParamDetails.params.length,
18213
- overrideCount: overrideParamDetails.params.length,
18214
- }));
18215
- canOverride = false;
18216
- }
18217
- const positionalParamCount = Math.min(baseParamDetails.positionParamCount, overrideParamDetails.positionParamCount);
18218
- for (let i = 0; i < positionalParamCount; i++) {
18219
- // If the first parameter is a "self" or "cls" parameter, skip the
18220
- // test because these are allowed to violate the Liskov substitution
18221
- // principle.
18222
- if (i === 0) {
18223
- if (types_1.FunctionType.isInstanceMethod(overrideMethod) ||
18224
- types_1.FunctionType.isClassMethod(overrideMethod) ||
18225
- types_1.FunctionType.isConstructorMethod(overrideMethod)) {
18226
- continue;
17005
+ if (types_1.FunctionType.isInstanceMethod(baseMethod)) {
17006
+ if (!types_1.FunctionType.isInstanceMethod(overrideMethod)) {
17007
+ diag === null || diag === void 0 ? void 0 : diag.addMessage(localize_1.Localizer.DiagnosticAddendum.overrideNotInstanceMethod());
17008
+ canOverride = false;
18227
17009
  }
18228
17010
  }
18229
- const baseParam = baseParamDetails.params[i].param;
18230
- const overrideParam = overrideParamDetails.params[i].param;
18231
- if (i >= baseParamDetails.positionOnlyParamCount &&
18232
- !(0, symbolNameUtils_1.isPrivateOrProtectedName)(baseParam.name || '') &&
18233
- baseParamDetails.params[i].source !== parameterUtils_1.ParameterSource.PositionOnly &&
18234
- baseParam.category === 0 /* Simple */ &&
18235
- baseParam.name !== overrideParam.name) {
18236
- if (overrideParam.category === 0 /* Simple */) {
18237
- if (enforceParamNames) {
18238
- if (overrideParamDetails.params[i].source === parameterUtils_1.ParameterSource.PositionOnly) {
18239
- diag === null || diag === void 0 ? void 0 : diag.addMessage(localize_1.Localizer.DiagnosticAddendum.overrideParamNamePositionOnly().format({
18240
- index: i + 1,
18241
- baseName: baseParam.name || '*',
18242
- }));
18243
- }
18244
- else {
18245
- diag === null || diag === void 0 ? void 0 : diag.addMessage(localize_1.Localizer.DiagnosticAddendum.overrideParamName().format({
17011
+ // Verify that the positional param count matches exactly or that the override
17012
+ // adds only params that preserve the original signature.
17013
+ let foundParamCountMismatch = false;
17014
+ if (overrideParamDetails.positionParamCount < baseParamDetails.positionParamCount) {
17015
+ if (overrideParamDetails.argsIndex === undefined) {
17016
+ foundParamCountMismatch = true;
17017
+ }
17018
+ else {
17019
+ const overrideArgsType = overrideParamDetails.params[overrideParamDetails.argsIndex].type;
17020
+ for (let i = overrideParamDetails.positionParamCount; i < baseParamDetails.positionParamCount; i++) {
17021
+ if (!assignType(overrideArgsType, baseParamDetails.params[i].type, diag === null || diag === void 0 ? void 0 : diag.createAddendum(), new typeVarContext_1.TypeVarContext((0, typeUtils_1.getTypeVarScopeId)(overrideMethod)), new typeVarContext_1.TypeVarContext((0, typeUtils_1.getTypeVarScopeId)(baseMethod)), 8 /* SkipSolveTypeVars */)) {
17022
+ localize_1.Localizer.DiagnosticAddendum.overrideParamType().format({
18246
17023
  index: i + 1,
18247
- baseName: baseParam.name || '*',
18248
- overrideName: overrideParam.name || '*',
18249
- }));
17024
+ baseType: printType(baseParamDetails.params[i].type),
17025
+ overrideType: printType(overrideArgsType),
17026
+ });
17027
+ canOverride = false;
18250
17028
  }
18251
- canOverride = false;
18252
17029
  }
18253
17030
  }
18254
17031
  }
18255
- else if (i < overrideParamDetails.positionOnlyParamCount &&
18256
- i >= baseParamDetails.positionOnlyParamCount) {
18257
- diag === null || diag === void 0 ? void 0 : diag.addMessage(localize_1.Localizer.DiagnosticAddendum.overrideParamNamePositionOnly().format({
18258
- index: i + 1,
18259
- baseName: baseParam.name || '*',
17032
+ else if (overrideParamDetails.positionParamCount > baseParamDetails.positionParamCount) {
17033
+ // Verify that all of the override parameters that extend the
17034
+ // signature are either *args, **kwargs or parameters with
17035
+ // default values.
17036
+ for (let i = baseParamDetails.positionParamCount; i < overrideParamDetails.positionParamCount; i++) {
17037
+ const overrideParam = overrideParamDetails.params[i].param;
17038
+ if (overrideParam.category === 0 /* Simple */ &&
17039
+ overrideParam.name &&
17040
+ !overrideParam.hasDefault) {
17041
+ foundParamCountMismatch = true;
17042
+ }
17043
+ }
17044
+ }
17045
+ if (foundParamCountMismatch) {
17046
+ diag === null || diag === void 0 ? void 0 : diag.addMessage(localize_1.Localizer.DiagnosticAddendum.overridePositionalParamCount().format({
17047
+ baseCount: baseParamDetails.params.length,
17048
+ overrideCount: overrideParamDetails.params.length,
18260
17049
  }));
18261
17050
  canOverride = false;
18262
17051
  }
18263
- else {
18264
- const baseParamType = baseParamDetails.params[i].type;
18265
- const overrideParamType = overrideParamDetails.params[i].type;
18266
- const baseIsSynthesizedTypeVar = (0, types_1.isTypeVar)(baseParamType) && baseParamType.details.isSynthesized;
18267
- const overrideIsSynthesizedTypeVar = (0, types_1.isTypeVar)(overrideParamType) && overrideParamType.details.isSynthesized;
18268
- if (!baseIsSynthesizedTypeVar && !overrideIsSynthesizedTypeVar) {
18269
- if (baseParam.category !== overrideParam.category ||
18270
- !assignType(overrideParamType, baseParamType, diag === null || diag === void 0 ? void 0 : diag.createAddendum(), new typeVarContext_1.TypeVarContext((0, typeUtils_1.getTypeVarScopeId)(overrideMethod)), new typeVarContext_1.TypeVarContext((0, typeUtils_1.getTypeVarScopeId)(baseMethod)), 8 /* SkipSolveTypeVars */)) {
18271
- diag === null || diag === void 0 ? void 0 : diag.addMessage(localize_1.Localizer.DiagnosticAddendum.overrideParamType().format({
18272
- index: i + 1,
18273
- baseType: printType(baseParamType),
18274
- overrideType: printType(overrideParamType),
18275
- }));
18276
- canOverride = false;
17052
+ const positionalParamCount = Math.min(baseParamDetails.positionParamCount, overrideParamDetails.positionParamCount);
17053
+ for (let i = 0; i < positionalParamCount; i++) {
17054
+ // If the first parameter is a "self" or "cls" parameter, skip the
17055
+ // test because these are allowed to violate the Liskov substitution
17056
+ // principle.
17057
+ if (i === 0) {
17058
+ if (types_1.FunctionType.isInstanceMethod(overrideMethod) ||
17059
+ types_1.FunctionType.isClassMethod(overrideMethod) ||
17060
+ types_1.FunctionType.isConstructorMethod(overrideMethod)) {
17061
+ continue;
18277
17062
  }
18278
17063
  }
18279
- if (baseParamDetails.params[i].param.hasDefault && !overrideParamDetails.params[i].param.hasDefault) {
18280
- diag === null || diag === void 0 ? void 0 : diag.addMessage(localize_1.Localizer.DiagnosticAddendum.overrideParamNoDefault().format({
17064
+ const baseParam = baseParamDetails.params[i].param;
17065
+ const overrideParam = overrideParamDetails.params[i].param;
17066
+ if (i >= baseParamDetails.positionOnlyParamCount &&
17067
+ !(0, symbolNameUtils_1.isPrivateOrProtectedName)(baseParam.name || '') &&
17068
+ baseParamDetails.params[i].source !== parameterUtils_1.ParameterSource.PositionOnly &&
17069
+ baseParam.category === 0 /* Simple */ &&
17070
+ baseParam.name !== overrideParam.name) {
17071
+ if (overrideParam.category === 0 /* Simple */) {
17072
+ if (enforceParamNames) {
17073
+ if (overrideParamDetails.params[i].source === parameterUtils_1.ParameterSource.PositionOnly) {
17074
+ diag === null || diag === void 0 ? void 0 : diag.addMessage(localize_1.Localizer.DiagnosticAddendum.overrideParamNamePositionOnly().format({
17075
+ index: i + 1,
17076
+ baseName: baseParam.name || '*',
17077
+ }));
17078
+ }
17079
+ else {
17080
+ diag === null || diag === void 0 ? void 0 : diag.addMessage(localize_1.Localizer.DiagnosticAddendum.overrideParamName().format({
17081
+ index: i + 1,
17082
+ baseName: baseParam.name || '*',
17083
+ overrideName: overrideParam.name || '*',
17084
+ }));
17085
+ }
17086
+ canOverride = false;
17087
+ }
17088
+ }
17089
+ }
17090
+ else if (i < overrideParamDetails.positionOnlyParamCount &&
17091
+ i >= baseParamDetails.positionOnlyParamCount) {
17092
+ diag === null || diag === void 0 ? void 0 : diag.addMessage(localize_1.Localizer.DiagnosticAddendum.overrideParamNamePositionOnly().format({
18281
17093
  index: i + 1,
17094
+ baseName: baseParam.name || '*',
18282
17095
  }));
18283
17096
  canOverride = false;
18284
17097
  }
18285
- }
18286
- }
18287
- // Check for a *args match.
18288
- if (baseParamDetails.argsIndex !== undefined) {
18289
- if (overrideParamDetails.argsIndex === undefined) {
18290
- diag === null || diag === void 0 ? void 0 : diag.addMessage(localize_1.Localizer.DiagnosticAddendum.overrideParamNameMissing().format({
18291
- name: (_a = baseParamDetails.params[baseParamDetails.argsIndex].param.name) !== null && _a !== void 0 ? _a : '?',
18292
- }));
18293
- canOverride = false;
18294
- }
18295
- else {
18296
- const overrideParamType = overrideParamDetails.params[overrideParamDetails.argsIndex].type;
18297
- const baseParamType = baseParamDetails.params[baseParamDetails.argsIndex].type;
18298
- if (!assignType(overrideParamType, baseParamType, diag === null || diag === void 0 ? void 0 : diag.createAddendum(), new typeVarContext_1.TypeVarContext((0, typeUtils_1.getTypeVarScopeId)(overrideMethod)),
18299
- /* srcTypeVarContext */ undefined, 8 /* SkipSolveTypeVars */)) {
18300
- diag === null || diag === void 0 ? void 0 : diag.addMessage(localize_1.Localizer.DiagnosticAddendum.overrideParamKeywordType().format({
18301
- name: (_b = overrideParamDetails.params[overrideParamDetails.argsIndex].param.name) !== null && _b !== void 0 ? _b : '?',
18302
- baseType: printType(baseParamType),
18303
- overrideType: printType(overrideParamType),
18304
- }));
18305
- canOverride = false;
17098
+ else {
17099
+ const baseParamType = baseParamDetails.params[i].type;
17100
+ const overrideParamType = overrideParamDetails.params[i].type;
17101
+ const baseIsSynthesizedTypeVar = (0, types_1.isTypeVar)(baseParamType) && baseParamType.details.isSynthesized;
17102
+ const overrideIsSynthesizedTypeVar = (0, types_1.isTypeVar)(overrideParamType) && overrideParamType.details.isSynthesized;
17103
+ if (!baseIsSynthesizedTypeVar && !overrideIsSynthesizedTypeVar) {
17104
+ if (baseParam.category !== overrideParam.category ||
17105
+ !assignType(overrideParamType, baseParamType, diag === null || diag === void 0 ? void 0 : diag.createAddendum(), new typeVarContext_1.TypeVarContext((0, typeUtils_1.getTypeVarScopeId)(overrideMethod)), new typeVarContext_1.TypeVarContext((0, typeUtils_1.getTypeVarScopeId)(baseMethod)), 8 /* SkipSolveTypeVars */)) {
17106
+ diag === null || diag === void 0 ? void 0 : diag.addMessage(localize_1.Localizer.DiagnosticAddendum.overrideParamType().format({
17107
+ index: i + 1,
17108
+ baseType: printType(baseParamType),
17109
+ overrideType: printType(overrideParamType),
17110
+ }));
17111
+ canOverride = false;
17112
+ }
17113
+ }
17114
+ if (baseParamDetails.params[i].param.hasDefault &&
17115
+ !overrideParamDetails.params[i].param.hasDefault) {
17116
+ diag === null || diag === void 0 ? void 0 : diag.addMessage(localize_1.Localizer.DiagnosticAddendum.overrideParamNoDefault().format({
17117
+ index: i + 1,
17118
+ }));
17119
+ canOverride = false;
17120
+ }
18306
17121
  }
18307
17122
  }
18308
- }
18309
- // Now check any keyword-only parameters.
18310
- const baseKwOnlyParams = baseParamDetails.params.filter((paramInfo) => paramInfo.source === parameterUtils_1.ParameterSource.KeywordOnly &&
18311
- paramInfo.param.category === 0 /* Simple */);
18312
- const overrideWkOnlyParams = overrideParamDetails.params.filter((paramInfo) => paramInfo.source === parameterUtils_1.ParameterSource.KeywordOnly &&
18313
- paramInfo.param.category === 0 /* Simple */);
18314
- baseKwOnlyParams.forEach((paramInfo) => {
18315
- var _a, _b, _c;
18316
- const overrideParamInfo = overrideWkOnlyParams.find((pi) => paramInfo.param.name === pi.param.name);
18317
- if (!overrideParamInfo && overrideParamDetails.kwargsIndex === undefined) {
18318
- diag === null || diag === void 0 ? void 0 : diag.addMessage(localize_1.Localizer.DiagnosticAddendum.overrideParamNameMissing().format({
18319
- name: (_a = paramInfo.param.name) !== null && _a !== void 0 ? _a : '?',
18320
- }));
18321
- canOverride = false;
18322
- }
18323
- else {
18324
- let targetParamType = overrideParamInfo === null || overrideParamInfo === void 0 ? void 0 : overrideParamInfo.type;
18325
- if (!targetParamType) {
18326
- targetParamType = overrideParamDetails.params[overrideParamDetails.kwargsIndex].type;
18327
- }
18328
- if (!assignType(targetParamType, paramInfo.type, diag === null || diag === void 0 ? void 0 : diag.createAddendum(), new typeVarContext_1.TypeVarContext((0, typeUtils_1.getTypeVarScopeId)(overrideMethod)),
18329
- /* srcTypeVarContext */ undefined, 8 /* SkipSolveTypeVars */)) {
18330
- diag === null || diag === void 0 ? void 0 : diag.addMessage(localize_1.Localizer.DiagnosticAddendum.overrideParamKeywordType().format({
18331
- name: (_b = paramInfo.param.name) !== null && _b !== void 0 ? _b : '?',
18332
- baseType: printType(paramInfo.type),
18333
- overrideType: printType(targetParamType),
17123
+ // Check for a *args match.
17124
+ if (baseParamDetails.argsIndex !== undefined) {
17125
+ if (overrideParamDetails.argsIndex === undefined) {
17126
+ diag === null || diag === void 0 ? void 0 : diag.addMessage(localize_1.Localizer.DiagnosticAddendum.overrideParamNameMissing().format({
17127
+ name: (_a = baseParamDetails.params[baseParamDetails.argsIndex].param.name) !== null && _a !== void 0 ? _a : '?',
18334
17128
  }));
18335
17129
  canOverride = false;
18336
17130
  }
18337
- if (overrideParamInfo) {
18338
- if (paramInfo.param.hasDefault && !overrideParamInfo.param.hasDefault) {
18339
- diag === null || diag === void 0 ? void 0 : diag.addMessage(localize_1.Localizer.DiagnosticAddendum.overrideParamKeywordNoDefault().format({
18340
- name: (_c = overrideParamInfo.param.name) !== null && _c !== void 0 ? _c : '?',
17131
+ else {
17132
+ const overrideParamType = overrideParamDetails.params[overrideParamDetails.argsIndex].type;
17133
+ const baseParamType = baseParamDetails.params[baseParamDetails.argsIndex].type;
17134
+ if (!assignType(overrideParamType, baseParamType, diag === null || diag === void 0 ? void 0 : diag.createAddendum(), new typeVarContext_1.TypeVarContext((0, typeUtils_1.getTypeVarScopeId)(overrideMethod)),
17135
+ /* srcTypeVarContext */ undefined, 8 /* SkipSolveTypeVars */)) {
17136
+ diag === null || diag === void 0 ? void 0 : diag.addMessage(localize_1.Localizer.DiagnosticAddendum.overrideParamKeywordType().format({
17137
+ name: (_b = overrideParamDetails.params[overrideParamDetails.argsIndex].param.name) !== null && _b !== void 0 ? _b : '?',
17138
+ baseType: printType(baseParamType),
17139
+ overrideType: printType(overrideParamType),
18341
17140
  }));
18342
17141
  canOverride = false;
18343
17142
  }
18344
17143
  }
18345
17144
  }
18346
- });
18347
- // Verify that any keyword-only parameters added by the overload are compatible
18348
- // with the **kwargs in the base.
18349
- overrideWkOnlyParams.forEach((paramInfo) => {
18350
- var _a;
18351
- const baseParamInfo = baseKwOnlyParams.find((pi) => paramInfo.param.name === pi.param.name);
18352
- if (!baseParamInfo) {
18353
- if (baseParamDetails.kwargsIndex === undefined) {
18354
- if (!paramInfo.param.hasDefault) {
18355
- diag === null || diag === void 0 ? void 0 : diag.addMessage(localize_1.Localizer.DiagnosticAddendum.overrideParamNameExtra().format({
18356
- name: (_a = paramInfo.param.name) !== null && _a !== void 0 ? _a : '?',
17145
+ // Now check any keyword-only parameters.
17146
+ const baseKwOnlyParams = baseParamDetails.params.filter((paramInfo) => paramInfo.source === parameterUtils_1.ParameterSource.KeywordOnly &&
17147
+ paramInfo.param.category === 0 /* Simple */);
17148
+ const overrideWkOnlyParams = overrideParamDetails.params.filter((paramInfo) => paramInfo.source === parameterUtils_1.ParameterSource.KeywordOnly &&
17149
+ paramInfo.param.category === 0 /* Simple */);
17150
+ baseKwOnlyParams.forEach((paramInfo) => {
17151
+ var _a, _b, _c;
17152
+ const overrideParamInfo = overrideWkOnlyParams.find((pi) => paramInfo.param.name === pi.param.name);
17153
+ if (!overrideParamInfo && overrideParamDetails.kwargsIndex === undefined) {
17154
+ diag === null || diag === void 0 ? void 0 : diag.addMessage(localize_1.Localizer.DiagnosticAddendum.overrideParamNameMissing().format({
17155
+ name: (_a = paramInfo.param.name) !== null && _a !== void 0 ? _a : '?',
17156
+ }));
17157
+ canOverride = false;
17158
+ }
17159
+ else {
17160
+ let targetParamType = overrideParamInfo === null || overrideParamInfo === void 0 ? void 0 : overrideParamInfo.type;
17161
+ if (!targetParamType) {
17162
+ targetParamType = overrideParamDetails.params[overrideParamDetails.kwargsIndex].type;
17163
+ }
17164
+ if (!assignType(targetParamType, paramInfo.type, diag === null || diag === void 0 ? void 0 : diag.createAddendum(), new typeVarContext_1.TypeVarContext((0, typeUtils_1.getTypeVarScopeId)(overrideMethod)),
17165
+ /* srcTypeVarContext */ undefined, 8 /* SkipSolveTypeVars */)) {
17166
+ diag === null || diag === void 0 ? void 0 : diag.addMessage(localize_1.Localizer.DiagnosticAddendum.overrideParamKeywordType().format({
17167
+ name: (_b = paramInfo.param.name) !== null && _b !== void 0 ? _b : '?',
17168
+ baseType: printType(paramInfo.type),
17169
+ overrideType: printType(targetParamType),
18357
17170
  }));
18358
17171
  canOverride = false;
18359
17172
  }
17173
+ if (overrideParamInfo) {
17174
+ if (paramInfo.param.hasDefault && !overrideParamInfo.param.hasDefault) {
17175
+ diag === null || diag === void 0 ? void 0 : diag.addMessage(localize_1.Localizer.DiagnosticAddendum.overrideParamKeywordNoDefault().format({
17176
+ name: (_c = overrideParamInfo.param.name) !== null && _c !== void 0 ? _c : '?',
17177
+ }));
17178
+ canOverride = false;
17179
+ }
17180
+ }
18360
17181
  }
17182
+ });
17183
+ // Verify that any keyword-only parameters added by the overload are compatible
17184
+ // with the **kwargs in the base.
17185
+ overrideWkOnlyParams.forEach((paramInfo) => {
17186
+ var _a;
17187
+ const baseParamInfo = baseKwOnlyParams.find((pi) => paramInfo.param.name === pi.param.name);
17188
+ if (!baseParamInfo) {
17189
+ if (baseParamDetails.kwargsIndex === undefined) {
17190
+ if (!paramInfo.param.hasDefault) {
17191
+ diag === null || diag === void 0 ? void 0 : diag.addMessage(localize_1.Localizer.DiagnosticAddendum.overrideParamNameExtra().format({
17192
+ name: (_a = paramInfo.param.name) !== null && _a !== void 0 ? _a : '?',
17193
+ }));
17194
+ canOverride = false;
17195
+ }
17196
+ }
17197
+ }
17198
+ });
17199
+ // Verify that if the base method has a **kwargs parameter, the override does too.
17200
+ if (baseParamDetails.kwargsIndex !== undefined && overrideParamDetails.kwargsIndex === undefined) {
17201
+ diag === null || diag === void 0 ? void 0 : diag.addMessage(localize_1.Localizer.DiagnosticAddendum.kwargsParamMissing().format({
17202
+ paramName: baseParamDetails.params[baseParamDetails.kwargsIndex].param.name,
17203
+ }));
17204
+ canOverride = false;
18361
17205
  }
18362
- });
17206
+ }
18363
17207
  // Now check the return type.
18364
17208
  const baseReturnType = getFunctionEffectiveReturnType(baseMethod);
18365
17209
  const overrideReturnType = getFunctionEffectiveReturnType(overrideMethod);
@@ -18808,7 +17652,6 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
18808
17652
  getGetterTypeFromProperty,
18809
17653
  getTypeOfArgument,
18810
17654
  markNamesAccessed,
18811
- getScopeIdForNode,
18812
17655
  makeTopLevelTypeVarsConcrete,
18813
17656
  mapSubtypesExpandTypeVars,
18814
17657
  lookUpSymbolRecursive,
@@ -18823,6 +17666,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
18823
17666
  getBuiltInType,
18824
17667
  getTypeOfMember,
18825
17668
  getTypeOfObjectMember,
17669
+ getTypeOfClassMemberName,
18826
17670
  getBoundMethod,
18827
17671
  getTypeOfMagicMethodReturn,
18828
17672
  bindFunctionToClassOrObject,
@@ -18831,6 +17675,8 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
18831
17675
  narrowConstrainedTypeVar,
18832
17676
  assignType,
18833
17677
  validateOverrideMethod,
17678
+ validateCallArguments,
17679
+ validateTypeArg,
18834
17680
  assignTypeToExpression,
18835
17681
  assignClassToSelf,
18836
17682
  getTypedDictClassType,
@@ -18857,6 +17703,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
18857
17703
  getTypeCacheEntryCount,
18858
17704
  disposeEvaluator,
18859
17705
  useSpeculativeMode,
17706
+ isSpeculativeModeInUse,
18860
17707
  setTypeForNode,
18861
17708
  checkForCancellation,
18862
17709
  printControlFlowGraph,