@zzzen/pyright-internal 1.2.0-dev.20231126 → 1.2.0-dev.20231203

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 (95) hide show
  1. package/dist/analyzer/binder.js +3 -0
  2. package/dist/analyzer/binder.js.map +1 -1
  3. package/dist/analyzer/checker.d.ts +4 -1
  4. package/dist/analyzer/checker.js +146 -9
  5. package/dist/analyzer/checker.js.map +1 -1
  6. package/dist/analyzer/codeFlowEngine.js +7 -0
  7. package/dist/analyzer/codeFlowEngine.js.map +1 -1
  8. package/dist/analyzer/commentUtils.js +7 -0
  9. package/dist/analyzer/commentUtils.js.map +1 -1
  10. package/dist/analyzer/constraintSolver.js +11 -0
  11. package/dist/analyzer/constraintSolver.js.map +1 -1
  12. package/dist/analyzer/constructors.js +2 -1
  13. package/dist/analyzer/constructors.js.map +1 -1
  14. package/dist/analyzer/dataClasses.js +57 -46
  15. package/dist/analyzer/dataClasses.js.map +1 -1
  16. package/dist/analyzer/operations.js +16 -14
  17. package/dist/analyzer/operations.js.map +1 -1
  18. package/dist/analyzer/protocols.js +27 -13
  19. package/dist/analyzer/protocols.js.map +1 -1
  20. package/dist/analyzer/typeEvaluator.js +126 -129
  21. package/dist/analyzer/typeEvaluator.js.map +1 -1
  22. package/dist/analyzer/typeEvaluatorTypes.d.ts +1 -1
  23. package/dist/analyzer/typeEvaluatorTypes.js +1 -1
  24. package/dist/analyzer/typeEvaluatorTypes.js.map +1 -1
  25. package/dist/analyzer/typeUtils.d.ts +1 -1
  26. package/dist/analyzer/typeUtils.js +16 -12
  27. package/dist/analyzer/typeUtils.js.map +1 -1
  28. package/dist/analyzer/typeVarContext.d.ts +2 -0
  29. package/dist/analyzer/typeVarContext.js +27 -0
  30. package/dist/analyzer/typeVarContext.js.map +1 -1
  31. package/dist/analyzer/typedDicts.js +2 -32
  32. package/dist/analyzer/typedDicts.js.map +1 -1
  33. package/dist/analyzer/types.d.ts +3 -8
  34. package/dist/analyzer/types.js +9 -16
  35. package/dist/analyzer/types.js.map +1 -1
  36. package/dist/commands/commandController.js +1 -2
  37. package/dist/commands/commandController.js.map +1 -1
  38. package/dist/commands/commands.d.ts +0 -1
  39. package/dist/commands/commands.js +0 -1
  40. package/dist/commands/commands.js.map +1 -1
  41. package/dist/common/configOptions.d.ts +1 -0
  42. package/dist/common/configOptions.js +91 -3
  43. package/dist/common/configOptions.js.map +1 -1
  44. package/dist/common/diagnostic.d.ts +0 -4
  45. package/dist/common/diagnostic.js.map +1 -1
  46. package/dist/languageService/codeActionProvider.js +0 -14
  47. package/dist/languageService/codeActionProvider.js.map +1 -1
  48. package/dist/languageService/quickActions.d.ts +1 -2
  49. package/dist/languageService/quickActions.js +0 -80
  50. package/dist/languageService/quickActions.js.map +1 -1
  51. package/dist/localization/localize.d.ts +12 -9
  52. package/dist/localization/localize.js +6 -4
  53. package/dist/localization/localize.js.map +1 -1
  54. package/dist/localization/package.nls.cs.json +0 -4
  55. package/dist/localization/package.nls.de.json +0 -4
  56. package/dist/localization/package.nls.en-us.json +7 -5
  57. package/dist/localization/package.nls.es.json +2 -6
  58. package/dist/localization/package.nls.fr.json +0 -4
  59. package/dist/localization/package.nls.it.json +0 -4
  60. package/dist/localization/package.nls.ja.json +0 -4
  61. package/dist/localization/package.nls.ko.json +0 -4
  62. package/dist/localization/package.nls.pl.json +0 -4
  63. package/dist/localization/package.nls.pt-br.json +0 -4
  64. package/dist/localization/package.nls.qps-ploc.json +0 -4
  65. package/dist/localization/package.nls.ru.json +0 -4
  66. package/dist/localization/package.nls.tr.json +0 -4
  67. package/dist/localization/package.nls.zh-cn.json +0 -4
  68. package/dist/localization/package.nls.zh-tw.json +0 -4
  69. package/dist/pyrightFileSystem.js +1 -1
  70. package/dist/pyrightFileSystem.js.map +1 -1
  71. package/dist/readonlyAugmentedFileSystem.d.ts +1 -1
  72. package/dist/readonlyAugmentedFileSystem.js +15 -5
  73. package/dist/readonlyAugmentedFileSystem.js.map +1 -1
  74. package/dist/server.js +1 -1
  75. package/dist/server.js.map +1 -1
  76. package/dist/tests/checker.test.js +8 -0
  77. package/dist/tests/checker.test.js.map +1 -1
  78. package/dist/tests/fourslash/fourslash.d.ts +1 -2
  79. package/dist/tests/harness/fourslash/testState.Consts.d.ts +1 -2
  80. package/dist/tests/harness/fourslash/testState.Consts.js +0 -1
  81. package/dist/tests/harness/fourslash/testState.Consts.js.map +1 -1
  82. package/dist/tests/harness/fourslash/testState.js +1 -1
  83. package/dist/tests/harness/fourslash/testState.js.map +1 -1
  84. package/dist/tests/pyrightFileSystem.test.js +48 -1
  85. package/dist/tests/pyrightFileSystem.test.js.map +1 -1
  86. package/dist/tests/typeEvaluator1.test.js +8 -5
  87. package/dist/tests/typeEvaluator1.test.js.map +1 -1
  88. package/dist/tests/typeEvaluator2.test.js +3 -3
  89. package/dist/tests/typeEvaluator3.test.js +12 -9
  90. package/dist/tests/typeEvaluator3.test.js.map +1 -1
  91. package/dist/tests/typeEvaluator4.test.js +6 -2
  92. package/dist/tests/typeEvaluator4.test.js.map +1 -1
  93. package/dist/tests/typeEvaluator5.test.js +8 -4
  94. package/dist/tests/typeEvaluator5.test.js.map +1 -1
  95. package/package.json +1 -1
@@ -385,6 +385,7 @@ class Checker extends parseTreeWalker_1.ParseTreeWalker {
385
385
  this._validateTypeGuardFunction(node, functionTypeResult.functionType, containingClassNode !== undefined);
386
386
  this._validateFunctionTypeVarUsage(node, functionTypeResult);
387
387
  this._validateGeneratorReturnType(node, functionTypeResult.functionType);
388
+ this._reportDeprecatedClassProperty(node, functionTypeResult);
388
389
  }
389
390
  // If we're at the module level within a stub file, report a diagnostic
390
391
  // if there is a '__getattr__' function defined when in strict mode.
@@ -412,6 +413,7 @@ class Checker extends parseTreeWalker_1.ParseTreeWalker {
412
413
  }
413
414
  }
414
415
  }
416
+ this._validateOverloadAttributeConsistency(node, functionTypeResult.decoratedType);
415
417
  }
416
418
  return false;
417
419
  }
@@ -531,7 +533,7 @@ class Checker extends parseTreeWalker_1.ParseTreeWalker {
531
533
  return true;
532
534
  }
533
535
  visitReturn(node) {
534
- var _a, _b;
536
+ var _a, _b, _c, _d, _e;
535
537
  let returnTypeResult;
536
538
  const enclosingFunctionNode = ParseTreeUtils.getEnclosingFunction(node);
537
539
  const declaredReturnType = enclosingFunctionNode
@@ -600,17 +602,17 @@ class Checker extends parseTreeWalker_1.ParseTreeWalker {
600
602
  this._evaluator.addDiagnostic(this._fileInfo.diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.returnTypeMismatch().format({
601
603
  exprType: this._evaluator.printType(returnTypeResult.type),
602
604
  returnType: this._evaluator.printType(declaredReturnType),
603
- }) + diagAddendum.getString(), node.returnExpression ? node.returnExpression : node, (_b = returnTypeResult.expectedTypeDiagAddendum) === null || _b === void 0 ? void 0 : _b.getEffectiveTextRange());
605
+ }) + diagAddendum.getString(), (_b = node.returnExpression) !== null && _b !== void 0 ? _b : node, (_c = returnTypeResult.expectedTypeDiagAddendum) === null || _c === void 0 ? void 0 : _c.getEffectiveTextRange());
604
606
  }
605
607
  }
606
608
  }
607
609
  if ((0, types_1.isUnknown)(returnTypeResult.type)) {
608
- this._evaluator.addDiagnostic(this._fileInfo.diagnosticRuleSet.reportUnknownVariableType, diagnosticRules_1.DiagnosticRule.reportUnknownVariableType, localize_1.Localizer.Diagnostic.returnTypeUnknown(), node.returnExpression);
610
+ this._evaluator.addDiagnostic(this._fileInfo.diagnosticRuleSet.reportUnknownVariableType, diagnosticRules_1.DiagnosticRule.reportUnknownVariableType, localize_1.Localizer.Diagnostic.returnTypeUnknown(), (_d = node.returnExpression) !== null && _d !== void 0 ? _d : node);
609
611
  }
610
612
  else if ((0, typeUtils_1.isPartlyUnknown)(returnTypeResult.type)) {
611
613
  this._evaluator.addDiagnostic(this._fileInfo.diagnosticRuleSet.reportUnknownVariableType, diagnosticRules_1.DiagnosticRule.reportUnknownVariableType, localize_1.Localizer.Diagnostic.returnTypePartiallyUnknown().format({
612
614
  returnType: this._evaluator.printType(returnTypeResult.type, { expandTypeAlias: true }),
613
- }), node.returnExpression);
615
+ }), (_e = node.returnExpression) !== null && _e !== void 0 ? _e : node);
614
616
  }
615
617
  }
616
618
  return true;
@@ -1030,6 +1032,15 @@ class Checker extends parseTreeWalker_1.ParseTreeWalker {
1030
1032
  visitTypeParameter(node) {
1031
1033
  return false;
1032
1034
  }
1035
+ visitTypeAlias(node) {
1036
+ const scope = (0, scopeUtils_1.getScopeForNode)(node);
1037
+ if (scope) {
1038
+ if (scope.type !== 2 /* ScopeType.Class */ && scope.type !== 3 /* ScopeType.Module */ && scope.type !== 4 /* ScopeType.Builtin */) {
1039
+ this._evaluator.addError(localize_1.Localizer.Diagnostic.typeAliasStatementBadScope(), node.name);
1040
+ }
1041
+ }
1042
+ return true;
1043
+ }
1033
1044
  visitTypeAnnotation(node) {
1034
1045
  this._evaluator.getType(node.typeAnnotation);
1035
1046
  return true;
@@ -1691,6 +1702,31 @@ class Checker extends parseTreeWalker_1.ParseTreeWalker {
1691
1702
  }
1692
1703
  });
1693
1704
  }
1705
+ // Validates that overloads use @staticmethod and @classmethod consistently.
1706
+ _validateOverloadAttributeConsistency(node, functionType) {
1707
+ var _a, _b, _c, _d, _e, _f;
1708
+ let staticMethodCount = 0;
1709
+ let classMethodCount = 0;
1710
+ functionType.overloads.forEach((overload) => {
1711
+ if (types_1.FunctionType.isStaticMethod(overload)) {
1712
+ staticMethodCount++;
1713
+ }
1714
+ if (types_1.FunctionType.isClassMethod(overload)) {
1715
+ classMethodCount++;
1716
+ }
1717
+ });
1718
+ if (staticMethodCount > 0 && staticMethodCount < functionType.overloads.length) {
1719
+ this._evaluator.addDiagnostic(this._fileInfo.diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.overloadStaticMethodInconsistent().format({
1720
+ name: node.name.value,
1721
+ }), (_c = (_b = (_a = functionType.overloads[0]) === null || _a === void 0 ? void 0 : _a.details.declaration) === null || _b === void 0 ? void 0 : _b.node.name) !== null && _c !== void 0 ? _c : node.name);
1722
+ }
1723
+ if (classMethodCount > 0 && classMethodCount < functionType.overloads.length) {
1724
+ this._evaluator.addDiagnostic(this._fileInfo.diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.overloadClassMethodInconsistent().format({
1725
+ name: node.name.value,
1726
+ }), (_f = (_e = (_d = functionType.overloads[0]) === null || _d === void 0 ? void 0 : _d.details.declaration) === null || _e === void 0 ? void 0 : _e.node.name) !== null && _f !== void 0 ? _f : node.name);
1727
+ }
1728
+ }
1729
+ // Validates that overloads do not overlap with inconsistent return results.
1694
1730
  _validateOverloadConsistency(node, functionType, prevOverloads) {
1695
1731
  for (let i = 0; i < prevOverloads.length; i++) {
1696
1732
  const prevOverload = prevOverloads[i];
@@ -2725,6 +2761,13 @@ class Checker extends parseTreeWalker_1.ParseTreeWalker {
2725
2761
  }
2726
2762
  return false;
2727
2763
  }
2764
+ _reportDeprecatedClassProperty(node, functionTypeResult) {
2765
+ if (!(0, types_1.isClassInstance)(functionTypeResult.decoratedType) ||
2766
+ !types_1.ClassType.isClassProperty(functionTypeResult.decoratedType)) {
2767
+ return;
2768
+ }
2769
+ this._reportDeprecatedDiagnostic(node.name, localize_1.Localizer.Diagnostic.classPropertyDeprecated());
2770
+ }
2728
2771
  _reportDeprecatedUseForMemberAccess(node, info) {
2729
2772
  let errorMessage;
2730
2773
  if (info.accessType === 'property') {
@@ -3281,14 +3324,21 @@ class Checker extends parseTreeWalker_1.ParseTreeWalker {
3281
3324
  }
3282
3325
  });
3283
3326
  }
3284
- // If a non-protocol class explicitly inherits from a protocol class, this method
3285
- // verifies that any class or instance variables declared but not assigned
3286
- // in the protocol class are implemented in the subclass. It also checks that any
3287
- // empty functions declared in the protocol are implemented in the subclass.
3327
+ // If a non-protocol class explicitly inherits from a protocol class and does
3328
+ // not explicit derive from ABC, this method verifies that any class or instance
3329
+ // variables declared but not assigned in the protocol class are implemented in
3330
+ // the subclass. It also checks that any empty functions declared in the protocol
3331
+ // are implemented in the subclass.
3288
3332
  _validateProtocolCompatibility(classType, errorNode) {
3289
3333
  if (types_1.ClassType.isProtocolClass(classType)) {
3290
3334
  return;
3291
3335
  }
3336
+ // If a class derives from ABC, exempt it from this check. This is used for
3337
+ // mixins that derive from a protocol but do not directly implement all
3338
+ // of the protocol's methods.
3339
+ if (classType.details.mro.some((mroClass) => (0, types_1.isClass)(mroClass) && types_1.ClassType.isBuiltIn(mroClass, 'ABC'))) {
3340
+ return;
3341
+ }
3292
3342
  const diagAddendum = new diagnostic_1.DiagnosticAddendum();
3293
3343
  const isSymbolImplemented = (name) => {
3294
3344
  return classType.details.mro.some((mroClass) => {
@@ -3947,12 +3997,63 @@ class Checker extends parseTreeWalker_1.ParseTreeWalker {
3947
3997
  // If the child class overrides this symbol with its own type, make sure
3948
3998
  // the override is compatible with the overridden symbol. Otherwise use the
3949
3999
  // override type.
3950
- if (!this._evaluator.assignType(overriddenType, childOverrideType !== null && childOverrideType !== void 0 ? childOverrideType : overrideType)) {
4000
+ // Verify that the override type is assignable to (same or narrower than)
4001
+ // the declared type of the base symbol.
4002
+ const primaryDecl = (0, symbolUtils_1.getLastTypedDeclaredForSymbol)(overriddenClassAndSymbol.symbol);
4003
+ let isInvariant = (primaryDecl === null || primaryDecl === void 0 ? void 0 : primaryDecl.type) === 1 /* DeclarationType.Variable */ && !primaryDecl.isFinal;
4004
+ // If the entry is a member of a frozen dataclass, it is immutable,
4005
+ // so it does not need to be invariant.
4006
+ if (types_1.ClassType.isFrozenDataClass(overriddenClassAndSymbol.classType) &&
4007
+ overriddenClassAndSymbol.classType.details.dataClassEntries) {
4008
+ const dataclassEntry = overriddenClassAndSymbol.classType.details.dataClassEntries.find((entry) => entry.name === memberName);
4009
+ if (dataclassEntry) {
4010
+ isInvariant = false;
4011
+ }
4012
+ }
4013
+ let overriddenTDEntry;
4014
+ if (overriddenClassAndSymbol.classType.details.typedDictEntries) {
4015
+ overriddenTDEntry = overriddenClassAndSymbol.classType.details.typedDictEntries.get(memberName);
4016
+ if (overriddenTDEntry === null || overriddenTDEntry === void 0 ? void 0 : overriddenTDEntry.isReadOnly) {
4017
+ isInvariant = false;
4018
+ }
4019
+ }
4020
+ let overrideTDEntry;
4021
+ if (overrideClassAndSymbol.classType.details.typedDictEntries) {
4022
+ overrideTDEntry = overrideClassAndSymbol.classType.details.typedDictEntries.get(memberName);
4023
+ }
4024
+ if (!this._evaluator.assignType(overriddenType, childOverrideType !== null && childOverrideType !== void 0 ? childOverrideType : overrideType,
4025
+ /* diag */ undefined,
4026
+ /* destTypeVarContext */ undefined,
4027
+ /* srcTypeVarContext */ undefined, isInvariant ? 1 /* AssignTypeFlags.EnforceInvariance */ : 0 /* AssignTypeFlags.Default */)) {
3951
4028
  diag = this._evaluator.addDiagnostic(this._fileInfo.diagnosticRuleSet.reportIncompatibleVariableOverride, diagnosticRules_1.DiagnosticRule.reportIncompatibleVariableOverride, localize_1.Localizer.Diagnostic.baseClassVariableTypeIncompatible().format({
3952
4029
  classType: childClassType.details.name,
3953
4030
  name: memberName,
3954
4031
  }), errorNode);
3955
4032
  }
4033
+ else if (overriddenTDEntry && overrideTDEntry) {
4034
+ let isRequiredCompatible;
4035
+ let isReadOnlyCompatible = true;
4036
+ // If both classes are TypedDicts and they both define this field,
4037
+ // make sure the attributes are compatible.
4038
+ if (overriddenTDEntry.isReadOnly) {
4039
+ isRequiredCompatible = overrideTDEntry.isRequired || !overriddenTDEntry.isRequired;
4040
+ }
4041
+ else {
4042
+ isReadOnlyCompatible = !overrideTDEntry.isReadOnly;
4043
+ isRequiredCompatible = overrideTDEntry.isRequired === overriddenTDEntry.isRequired;
4044
+ }
4045
+ if (!isRequiredCompatible) {
4046
+ const message = overrideTDEntry.isRequired
4047
+ ? localize_1.Localizer.Diagnostic.typedDictFieldRequiredRedefinition
4048
+ : localize_1.Localizer.Diagnostic.typedDictFieldNotRequiredRedefinition;
4049
+ diag = this._evaluator.addDiagnostic(this._fileInfo.diagnosticRuleSet.reportIncompatibleVariableOverride, diagnosticRules_1.DiagnosticRule.reportIncompatibleVariableOverride, message().format({ name: memberName }), errorNode);
4050
+ }
4051
+ else if (!isReadOnlyCompatible) {
4052
+ diag = this._evaluator.addDiagnostic(this._fileInfo.diagnosticRuleSet.reportIncompatibleVariableOverride, diagnosticRules_1.DiagnosticRule.reportIncompatibleVariableOverride, localize_1.Localizer.Diagnostic.typedDictFieldReadOnlyRedefinition().format({
4053
+ name: memberName,
4054
+ }), errorNode);
4055
+ }
4056
+ }
3956
4057
  }
3957
4058
  }
3958
4059
  }
@@ -4261,6 +4362,17 @@ class Checker extends parseTreeWalker_1.ParseTreeWalker {
4261
4362
  isInvariant = false;
4262
4363
  }
4263
4364
  }
4365
+ let overriddenTDEntry;
4366
+ if (baseClass.details.typedDictEntries) {
4367
+ overriddenTDEntry = baseClass.details.typedDictEntries.get(memberName);
4368
+ if (overriddenTDEntry === null || overriddenTDEntry === void 0 ? void 0 : overriddenTDEntry.isReadOnly) {
4369
+ isInvariant = false;
4370
+ }
4371
+ }
4372
+ let overrideTDEntry;
4373
+ if (childClassType.details.typedDictEntries) {
4374
+ overrideTDEntry = childClassType.details.typedDictEntries.get(memberName);
4375
+ }
4264
4376
  let diagAddendum = new diagnostic_1.DiagnosticAddendum();
4265
4377
  if (!this._evaluator.assignType(baseType, overrideType, diagAddendum,
4266
4378
  /* destTypeVarContext */ undefined,
@@ -4282,6 +4394,31 @@ class Checker extends parseTreeWalker_1.ParseTreeWalker {
4282
4394
  diag.addRelatedInfo(localize_1.Localizer.DiagnosticAddendum.overriddenSymbol(), origDecl.path, origDecl.range);
4283
4395
  }
4284
4396
  }
4397
+ else if (overriddenTDEntry && overrideTDEntry) {
4398
+ // Make sure the required/not-required attribute is compatible.
4399
+ let isRequiredCompatible = true;
4400
+ if (overriddenTDEntry.isReadOnly) {
4401
+ // If the read-only flag is set, a not-required field can be overridden
4402
+ // by a required field, but not vice versa.
4403
+ isRequiredCompatible = overrideTDEntry.isRequired || !overriddenTDEntry.isRequired;
4404
+ }
4405
+ else {
4406
+ isRequiredCompatible = overrideTDEntry.isRequired === overriddenTDEntry.isRequired;
4407
+ }
4408
+ if (!isRequiredCompatible) {
4409
+ const message = overrideTDEntry.isRequired
4410
+ ? localize_1.Localizer.Diagnostic.typedDictFieldRequiredRedefinition
4411
+ : localize_1.Localizer.Diagnostic.typedDictFieldNotRequiredRedefinition;
4412
+ this._evaluator.addDiagnostic(AnalyzerNodeInfo.getFileInfo(lastDecl.node).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, message().format({ name: memberName }), lastDecl.node);
4413
+ }
4414
+ // Make sure that the derived class isn't marking a previously writable
4415
+ // entry as read-only.
4416
+ if (!overriddenTDEntry.isReadOnly && overrideTDEntry.isReadOnly) {
4417
+ this._evaluator.addDiagnostic(AnalyzerNodeInfo.getFileInfo(lastDecl.node).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.typedDictFieldReadOnlyRedefinition().format({
4418
+ name: memberName,
4419
+ }), lastDecl.node);
4420
+ }
4421
+ }
4285
4422
  // Verify that there is not a Final mismatch.
4286
4423
  const isBaseVarFinal = this._evaluator.isFinalVariable(baseClassAndSymbol.symbol);
4287
4424
  const overrideFinalVarDecl = decls.find((d) => this._evaluator.isFinalVariableDeclaration(d));