@zzzen/pyright-internal 1.2.0-dev.20250209 → 1.2.0-dev.20250223
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.
- package/dist/analyzer/backgroundAnalysisProgram.d.ts +4 -4
- package/dist/analyzer/backgroundAnalysisProgram.js.map +1 -1
- package/dist/analyzer/cacheManager.d.ts +5 -2
- package/dist/analyzer/cacheManager.js +1 -0
- package/dist/analyzer/cacheManager.js.map +1 -1
- package/dist/analyzer/checker.d.ts +1 -1
- package/dist/analyzer/checker.js +200 -247
- package/dist/analyzer/checker.js.map +1 -1
- package/dist/analyzer/constraintTracker.d.ts +2 -2
- package/dist/analyzer/constraintTracker.js +11 -5
- package/dist/analyzer/constraintTracker.js.map +1 -1
- package/dist/analyzer/constructorTransform.js +1 -1
- package/dist/analyzer/constructorTransform.js.map +1 -1
- package/dist/analyzer/constructors.js +3 -3
- package/dist/analyzer/constructors.js.map +1 -1
- package/dist/analyzer/importResolver.d.ts +1 -1
- package/dist/analyzer/parseTreeUtils.d.ts +2 -1
- package/dist/analyzer/parseTreeUtils.js +12 -0
- package/dist/analyzer/parseTreeUtils.js.map +1 -1
- package/dist/analyzer/program.d.ts +1 -1
- package/dist/analyzer/program.js +17 -30
- package/dist/analyzer/program.js.map +1 -1
- package/dist/analyzer/protocols.js +26 -11
- package/dist/analyzer/protocols.js.map +1 -1
- package/dist/analyzer/service.d.ts +4 -3
- package/dist/analyzer/service.js +3 -1
- package/dist/analyzer/service.js.map +1 -1
- package/dist/analyzer/sourceFile.d.ts +11 -1
- package/dist/analyzer/sourceFile.js +6 -1
- package/dist/analyzer/sourceFile.js.map +1 -1
- package/dist/analyzer/sourceFileInfoUtils.d.ts +1 -0
- package/dist/analyzer/sourceFileInfoUtils.js +12 -11
- package/dist/analyzer/sourceFileInfoUtils.js.map +1 -1
- package/dist/analyzer/tracePrinter.d.ts +1 -1
- package/dist/analyzer/tracePrinter.js +3 -2
- package/dist/analyzer/tracePrinter.js.map +1 -1
- package/dist/analyzer/typeEvaluator.js +248 -98
- package/dist/analyzer/typeEvaluator.js.map +1 -1
- package/dist/analyzer/typeEvaluatorTypes.d.ts +2 -0
- package/dist/analyzer/typeGuards.js +20 -3
- package/dist/analyzer/typeGuards.js.map +1 -1
- package/dist/analyzer/typePrinter.d.ts +2 -0
- package/dist/analyzer/typePrinter.js +20 -0
- package/dist/analyzer/typePrinter.js.map +1 -1
- package/dist/analyzer/typeUtils.js +3 -3
- package/dist/analyzer/typeUtils.js.map +1 -1
- package/dist/analyzer/typeWalker.js +1 -1
- package/dist/analyzer/typeWalker.js.map +1 -1
- package/dist/analyzer/typedDicts.js +6 -7
- package/dist/analyzer/typedDicts.js.map +1 -1
- package/dist/analyzer/types.d.ts +4 -1
- package/dist/analyzer/types.js +9 -4
- package/dist/analyzer/types.js.map +1 -1
- package/dist/backgroundAnalysisBase.d.ts +26 -4
- package/dist/backgroundAnalysisBase.js +14 -13
- package/dist/backgroundAnalysisBase.js.map +1 -1
- package/dist/backgroundThreadBase.d.ts +6 -2
- package/dist/backgroundThreadBase.js +7 -1
- package/dist/backgroundThreadBase.js.map +1 -1
- package/dist/common/cancellationUtils.d.ts +2 -0
- package/dist/common/cancellationUtils.js +19 -1
- package/dist/common/cancellationUtils.js.map +1 -1
- package/dist/common/fileSystem.d.ts +2 -0
- package/dist/common/fileSystem.js.map +1 -1
- package/dist/common/languageServerInterface.d.ts +3 -27
- package/dist/common/languageServerInterface.js.map +1 -1
- package/dist/common/realFileSystem.d.ts +2 -0
- package/dist/common/realFileSystem.js +8 -0
- package/dist/common/realFileSystem.js.map +1 -1
- package/dist/common/serviceKeys.d.ts +1 -1
- package/dist/common/serviceProviderExtensions.d.ts +1 -1
- package/dist/common/serviceProviderExtensions.js +2 -2
- package/dist/common/serviceProviderExtensions.js.map +1 -1
- package/dist/common/uri/uriMap.d.ts +17 -0
- package/dist/common/uri/uriMap.js +76 -0
- package/dist/common/uri/uriMap.js.map +1 -0
- package/dist/languageServerBase.d.ts +5 -4
- package/dist/languageServerBase.js +2 -0
- package/dist/languageServerBase.js.map +1 -1
- package/dist/languageService/completionProvider.js +1 -1
- package/dist/languageService/completionProvider.js.map +1 -1
- package/dist/languageService/referencesProvider.js +9 -2
- package/dist/languageService/referencesProvider.js.map +1 -1
- package/dist/localization/localize.d.ts +4 -4
- package/dist/localization/localize.js +2 -1
- package/dist/localization/localize.js.map +1 -1
- package/dist/localization/package.nls.cs.json +7 -7
- package/dist/localization/package.nls.de.json +7 -7
- package/dist/localization/package.nls.en-us.json +5 -4
- package/dist/localization/package.nls.es.json +7 -7
- package/dist/localization/package.nls.fr.json +7 -7
- package/dist/localization/package.nls.it.json +7 -7
- package/dist/localization/package.nls.ja.json +7 -7
- package/dist/localization/package.nls.ko.json +7 -7
- package/dist/localization/package.nls.pl.json +7 -7
- package/dist/localization/package.nls.pt-br.json +7 -7
- package/dist/localization/package.nls.qps-ploc.json +3 -3
- package/dist/localization/package.nls.ru.json +7 -7
- package/dist/localization/package.nls.tr.json +7 -7
- package/dist/localization/package.nls.zh-cn.json +7 -7
- package/dist/localization/package.nls.zh-tw.json +7 -7
- package/dist/partialStubService.d.ts +26 -0
- package/dist/partialStubService.js +138 -0
- package/dist/partialStubService.js.map +1 -0
- package/dist/pyrightFileSystem.d.ts +1 -21
- package/dist/pyrightFileSystem.js +7 -137
- package/dist/pyrightFileSystem.js.map +1 -1
- package/dist/readonlyAugmentedFileSystem.d.ts +7 -4
- package/dist/readonlyAugmentedFileSystem.js +124 -60
- package/dist/readonlyAugmentedFileSystem.js.map +1 -1
- package/dist/server.d.ts +2 -2
- package/dist/server.js +3 -1
- package/dist/server.js.map +1 -1
- package/dist/tests/completions.test.js +23 -0
- package/dist/tests/completions.test.js.map +1 -1
- package/dist/tests/fourslash/completions.autoimport.shadow.fourslash.js +2 -2
- package/dist/tests/fourslash/completions.autoimport.shadow.fourslash.js.map +1 -1
- package/dist/tests/fourslash/completions.wildcardimports.fourslash.js +2 -2
- package/dist/tests/fourslash/completions.wildcardimports.fourslash.js.map +1 -1
- package/dist/tests/fourslash/hover.wildcardimports.fourslash.js +2 -2
- package/dist/tests/fourslash/hover.wildcardimports.fourslash.js.map +1 -1
- package/dist/tests/fourslash/rename.typeParams.fourslash.d.ts +1 -0
- package/dist/tests/fourslash/rename.typeParams.fourslash.js +27 -0
- package/dist/tests/fourslash/rename.typeParams.fourslash.js.map +1 -0
- package/dist/tests/fourslash/signature.docstrings.wildcardimports.fourslash.js +2 -2
- package/dist/tests/fourslash/signature.docstrings.wildcardimports.fourslash.js.map +1 -1
- package/dist/tests/harness/fourslash/testLanguageService.d.ts +2 -2
- package/dist/tests/harness/fourslash/testLanguageService.js.map +1 -1
- package/dist/tests/harness/fourslash/testState.js +3 -1
- package/dist/tests/harness/fourslash/testState.js.map +1 -1
- package/dist/tests/harness/vfs/filesystem.d.ts +2 -0
- package/dist/tests/harness/vfs/filesystem.js +5 -2
- package/dist/tests/harness/vfs/filesystem.js.map +1 -1
- package/dist/tests/importResolver.test.js +8 -2
- package/dist/tests/importResolver.test.js.map +1 -1
- package/dist/tests/pyrightFileSystem.test.js +15 -8
- package/dist/tests/pyrightFileSystem.test.js.map +1 -1
- package/dist/tests/typeEvaluator4.test.js +3 -3
- package/dist/tests/typeEvaluator5.test.js +1 -1
- package/dist/tests/typeEvaluator6.test.js +4 -0
- package/dist/tests/typeEvaluator6.test.js.map +1 -1
- package/dist/tests/typeEvaluator7.test.js +1 -1
- package/dist/tests/typeEvaluator8.test.js +2 -2
- package/dist/tests/typeEvaluator8.test.js.map +1 -1
- package/dist/types.d.ts +26 -0
- package/dist/types.js +3 -0
- package/dist/types.js.map +1 -0
- package/package.json +1 -1
package/dist/analyzer/checker.js
CHANGED
@@ -1382,7 +1382,7 @@ class Checker extends parseTreeWalker_1.ParseTreeWalker {
|
|
1382
1382
|
if (isComparable) {
|
1383
1383
|
return;
|
1384
1384
|
}
|
1385
|
-
if (this.
|
1385
|
+
if (this._evaluator.isTypeComparable(leftSubtype, rightSubtype)) {
|
1386
1386
|
isComparable = true;
|
1387
1387
|
}
|
1388
1388
|
return rightSubtype;
|
@@ -1399,71 +1399,6 @@ class Checker extends parseTreeWalker_1.ParseTreeWalker {
|
|
1399
1399
|
}
|
1400
1400
|
}
|
1401
1401
|
}
|
1402
|
-
// Determines whether the two types are potentially comparable -- i.e.
|
1403
|
-
// their types overlap in such a way that it makes sense for them to
|
1404
|
-
// be compared with an == or != operator.
|
1405
|
-
_isTypeComparable(leftType, rightType) {
|
1406
|
-
if ((0, types_1.isAnyOrUnknown)(leftType) || (0, types_1.isAnyOrUnknown)(rightType)) {
|
1407
|
-
return true;
|
1408
|
-
}
|
1409
|
-
if ((0, types_1.isNever)(leftType) || (0, types_1.isNever)(rightType)) {
|
1410
|
-
return false;
|
1411
|
-
}
|
1412
|
-
if ((0, types_1.isModule)(leftType) || (0, types_1.isModule)(rightType)) {
|
1413
|
-
return (0, types_1.isTypeSame)(leftType, rightType, { ignoreConditions: true });
|
1414
|
-
}
|
1415
|
-
const isLeftCallable = (0, types_1.isFunction)(leftType) || (0, types_1.isOverloaded)(leftType);
|
1416
|
-
const isRightCallable = (0, types_1.isFunction)(rightType) || (0, types_1.isOverloaded)(rightType);
|
1417
|
-
if (isLeftCallable !== isRightCallable) {
|
1418
|
-
return false;
|
1419
|
-
}
|
1420
|
-
if ((0, types_1.isInstantiableClass)(leftType) || ((0, types_1.isClassInstance)(leftType) && types_1.ClassType.isBuiltIn(leftType, 'type'))) {
|
1421
|
-
if ((0, types_1.isInstantiableClass)(rightType) ||
|
1422
|
-
((0, types_1.isClassInstance)(rightType) && types_1.ClassType.isBuiltIn(rightType, 'type'))) {
|
1423
|
-
const genericLeftType = types_1.ClassType.specialize(leftType, /* typeArgs */ undefined);
|
1424
|
-
const genericRightType = types_1.ClassType.specialize(rightType, /* typeArgs */ undefined);
|
1425
|
-
if (this._evaluator.assignType(genericLeftType, genericRightType) ||
|
1426
|
-
this._evaluator.assignType(genericRightType, genericLeftType)) {
|
1427
|
-
return true;
|
1428
|
-
}
|
1429
|
-
}
|
1430
|
-
// Does the class have an operator overload for eq?
|
1431
|
-
const metaclass = leftType.shared.effectiveMetaclass;
|
1432
|
-
if (metaclass && (0, types_1.isClass)(metaclass)) {
|
1433
|
-
if ((0, typeUtils_1.lookUpClassMember)(metaclass, '__eq__', 4 /* MemberAccessFlags.SkipObjectBaseClass */)) {
|
1434
|
-
return true;
|
1435
|
-
}
|
1436
|
-
}
|
1437
|
-
return false;
|
1438
|
-
}
|
1439
|
-
if ((0, types_1.isClassInstance)(leftType)) {
|
1440
|
-
if ((0, types_1.isClass)(rightType)) {
|
1441
|
-
const genericLeftType = types_1.ClassType.specialize(leftType, /* typeArgs */ undefined);
|
1442
|
-
const genericRightType = types_1.ClassType.specialize(rightType, /* typeArgs */ undefined);
|
1443
|
-
if (this._evaluator.assignType(genericLeftType, genericRightType) ||
|
1444
|
-
this._evaluator.assignType(genericRightType, genericLeftType)) {
|
1445
|
-
return true;
|
1446
|
-
}
|
1447
|
-
// Assume that if the types are disjoint and built-in classes that they
|
1448
|
-
// will never be comparable.
|
1449
|
-
if (types_1.ClassType.isBuiltIn(leftType) && types_1.ClassType.isBuiltIn(rightType) && types_1.TypeBase.isInstance(rightType)) {
|
1450
|
-
return false;
|
1451
|
-
}
|
1452
|
-
}
|
1453
|
-
// Does the class have an operator overload for eq?
|
1454
|
-
const eqMethod = (0, typeUtils_1.lookUpClassMember)(types_1.ClassType.cloneAsInstantiable(leftType), '__eq__', 4 /* MemberAccessFlags.SkipObjectBaseClass */);
|
1455
|
-
if (eqMethod) {
|
1456
|
-
// If this is a synthesized method for a dataclass, we can assume
|
1457
|
-
// that other dataclass types will not be comparable.
|
1458
|
-
if (types_1.ClassType.isDataClass(leftType) && eqMethod.symbol.getSynthesizedType()) {
|
1459
|
-
return false;
|
1460
|
-
}
|
1461
|
-
return true;
|
1462
|
-
}
|
1463
|
-
return false;
|
1464
|
-
}
|
1465
|
-
return true;
|
1466
|
-
}
|
1467
1402
|
// If the function is a generator, validates that its annotated return type
|
1468
1403
|
// is appropriate for a generator.
|
1469
1404
|
_validateGeneratorReturnType(node, functionType) {
|
@@ -4631,24 +4566,7 @@ class Checker extends parseTreeWalker_1.ParseTreeWalker {
|
|
4631
4566
|
if ((0, types_1.isFunction)(baseType) || (0, types_1.isOverloaded)(baseType)) {
|
4632
4567
|
const diagAddendum = new diagnostic_1.DiagnosticAddendum();
|
4633
4568
|
// Determine whether this is an attempt to override a method marked @final.
|
4634
|
-
|
4635
|
-
// Private names (starting with double underscore) are exempt from this check.
|
4636
|
-
if (!SymbolNameUtils.isPrivateName(memberName)) {
|
4637
|
-
if ((0, types_1.isFunction)(baseType) && types_1.FunctionType.isFinal(baseType)) {
|
4638
|
-
reportFinalMethodOverride = true;
|
4639
|
-
}
|
4640
|
-
else if ((0, types_1.isOverloaded)(baseType)) {
|
4641
|
-
const overloads = types_1.OverloadedType.getOverloads(baseType);
|
4642
|
-
const impl = types_1.OverloadedType.getImplementation(baseType);
|
4643
|
-
if (overloads.some((overload) => types_1.FunctionType.isFinal(overload))) {
|
4644
|
-
reportFinalMethodOverride = true;
|
4645
|
-
}
|
4646
|
-
if (impl && (0, types_1.isFunction)(impl) && types_1.FunctionType.isFinal(impl)) {
|
4647
|
-
reportFinalMethodOverride = true;
|
4648
|
-
}
|
4649
|
-
}
|
4650
|
-
}
|
4651
|
-
if (reportFinalMethodOverride) {
|
4569
|
+
if (this._isFinalFunction(memberName, baseType)) {
|
4652
4570
|
const decl = (0, symbolUtils_1.getLastTypedDeclarationForSymbol)(overrideSymbol);
|
4653
4571
|
if (decl && decl.type === 5 /* DeclarationType.Function */) {
|
4654
4572
|
const diag = this._evaluator.addDiagnostic(diagnosticRules_1.DiagnosticRule.reportIncompatibleMethodOverride, localize_1.LocMessage.finalMethodOverride().format({
|
@@ -4661,55 +4579,62 @@ class Checker extends parseTreeWalker_1.ParseTreeWalker {
|
|
4661
4579
|
}
|
4662
4580
|
}
|
4663
4581
|
}
|
4582
|
+
// Don't check certain magic functions or private symbols.
|
4583
|
+
// Also, skip this check if the class is a TypedDict. The methods for a TypedDict
|
4584
|
+
// are synthesized, and they can result in many overloads. We assume they
|
4585
|
+
// are correct and will not produce any errors.
|
4586
|
+
if (this._isMethodExemptFromLsp(memberName) ||
|
4587
|
+
SymbolNameUtils.isPrivateName(memberName) ||
|
4588
|
+
types_1.ClassType.isTypedDictClass(childClassType)) {
|
4589
|
+
return;
|
4590
|
+
}
|
4664
4591
|
if ((0, types_1.isFunction)(overrideType) || (0, types_1.isOverloaded)(overrideType)) {
|
4665
4592
|
// Don't enforce parameter names for dundered methods. Many of them
|
4666
4593
|
// are misnamed in typeshed stubs, so this would result in many
|
4667
4594
|
// false positives.
|
4668
4595
|
const enforceParamNameMatch = !SymbolNameUtils.isDunderName(memberName);
|
4669
|
-
|
4670
|
-
|
4671
|
-
|
4672
|
-
|
4673
|
-
if (!
|
4674
|
-
|
4675
|
-
|
4676
|
-
|
4677
|
-
|
4678
|
-
|
4679
|
-
|
4680
|
-
|
4681
|
-
|
4682
|
-
|
4683
|
-
const origDecl = (0, symbolUtils_1.getLastTypedDeclarationForSymbol)(baseClassAndSymbol.symbol);
|
4684
|
-
if (diag && origDecl) {
|
4685
|
-
diag.addRelatedInfo(localize_1.LocAddendum.overriddenMethod(), origDecl.uri, origDecl.range);
|
4686
|
-
}
|
4687
|
-
}
|
4688
|
-
}
|
4596
|
+
if (this._evaluator.validateOverrideMethod(baseType, overrideType, childClassType, diagAddendum, enforceParamNameMatch)) {
|
4597
|
+
return;
|
4598
|
+
}
|
4599
|
+
const decl = (0, symbolUtils_1.getLastTypedDeclarationForSymbol)(overrideSymbol);
|
4600
|
+
if (!decl) {
|
4601
|
+
return;
|
4602
|
+
}
|
4603
|
+
const diag = this._evaluator.addDiagnostic(diagnosticRules_1.DiagnosticRule.reportIncompatibleMethodOverride, localize_1.LocMessage.incompatibleMethodOverride().format({
|
4604
|
+
name: memberName,
|
4605
|
+
className: baseClass.shared.name,
|
4606
|
+
}) + diagAddendum.getString(), (0, declarationUtils_1.getNameNodeForDeclaration)(decl) ?? decl.node);
|
4607
|
+
const origDecl = (0, symbolUtils_1.getLastTypedDeclarationForSymbol)(baseClassAndSymbol.symbol);
|
4608
|
+
if (diag && origDecl) {
|
4609
|
+
diag.addRelatedInfo(localize_1.LocAddendum.overriddenMethod(), origDecl.uri, origDecl.range);
|
4689
4610
|
}
|
4611
|
+
return;
|
4690
4612
|
}
|
4691
|
-
|
4613
|
+
if (!(0, types_1.isAnyOrUnknown)(overrideType)) {
|
4692
4614
|
// Special-case overrides of methods in '_TypedDict', since
|
4693
4615
|
// TypedDict attributes aren't manifest as attributes but rather
|
4694
4616
|
// as named keys.
|
4695
|
-
if (
|
4696
|
-
|
4697
|
-
|
4698
|
-
|
4699
|
-
|
4700
|
-
|
4701
|
-
|
4702
|
-
|
4703
|
-
|
4704
|
-
|
4705
|
-
|
4706
|
-
|
4707
|
-
|
4708
|
-
|
4617
|
+
if (types_1.ClassType.isBuiltIn(baseClass, '_TypedDict')) {
|
4618
|
+
return;
|
4619
|
+
}
|
4620
|
+
const decls = overrideSymbol.getDeclarations();
|
4621
|
+
if (decls.length === 0) {
|
4622
|
+
return;
|
4623
|
+
}
|
4624
|
+
const lastDecl = decls[decls.length - 1];
|
4625
|
+
const diag = this._evaluator.addDiagnostic(diagnosticRules_1.DiagnosticRule.reportIncompatibleMethodOverride, localize_1.LocMessage.methodOverridden().format({
|
4626
|
+
name: memberName,
|
4627
|
+
className: baseClass.shared.name,
|
4628
|
+
type: this._evaluator.printType(overrideType),
|
4629
|
+
}), (0, declarationUtils_1.getNameNodeForDeclaration)(lastDecl) ?? lastDecl.node);
|
4630
|
+
const origDecl = (0, symbolUtils_1.getLastTypedDeclarationForSymbol)(baseClassAndSymbol.symbol);
|
4631
|
+
if (diag && origDecl) {
|
4632
|
+
diag.addRelatedInfo(localize_1.LocAddendum.overriddenMethod(), origDecl.uri, origDecl.range);
|
4709
4633
|
}
|
4710
4634
|
}
|
4635
|
+
return;
|
4711
4636
|
}
|
4712
|
-
|
4637
|
+
if ((0, typeUtils_1.isProperty)(baseType)) {
|
4713
4638
|
// Handle properties specially.
|
4714
4639
|
if (!(0, typeUtils_1.isProperty)(overrideType)) {
|
4715
4640
|
const decls = overrideSymbol.getDeclarations();
|
@@ -4724,139 +4649,158 @@ class Checker extends parseTreeWalker_1.ParseTreeWalker {
|
|
4724
4649
|
else {
|
4725
4650
|
this._validatePropertyOverride(baseClass, childClassType, baseType, overrideType, overrideSymbol, memberName);
|
4726
4651
|
}
|
4652
|
+
return;
|
4727
4653
|
}
|
4728
|
-
|
4729
|
-
|
4730
|
-
|
4731
|
-
|
4732
|
-
|
4733
|
-
|
4734
|
-
|
4735
|
-
|
4736
|
-
|
4737
|
-
|
4738
|
-
|
4739
|
-
|
4740
|
-
|
4741
|
-
|
4742
|
-
|
4743
|
-
|
4744
|
-
|
4745
|
-
|
4746
|
-
|
4747
|
-
|
4748
|
-
|
4749
|
-
|
4750
|
-
|
4751
|
-
|
4752
|
-
|
4753
|
-
|
4754
|
-
|
4755
|
-
|
4756
|
-
|
4757
|
-
|
4758
|
-
}
|
4759
|
-
if (childClassType.shared.typedDictEntries) {
|
4760
|
-
overrideTDEntry =
|
4761
|
-
childClassType.shared.typedDictEntries.knownItems.get(memberName) ??
|
4762
|
-
childClassType.shared.typedDictEntries.extraItems ??
|
4763
|
-
(0, typedDicts_1.getEffectiveExtraItemsEntryType)(this._evaluator, childClassType);
|
4764
|
-
}
|
4765
|
-
}
|
4766
|
-
let diagAddendum = new diagnostic_1.DiagnosticAddendum();
|
4767
|
-
if (!this._evaluator.assignType(baseType, overrideType, diagAddendum,
|
4768
|
-
/* constraints */ undefined, isInvariant ? 1 /* AssignTypeFlags.Invariant */ : 0 /* AssignTypeFlags.Default */)) {
|
4769
|
-
if (isInvariant) {
|
4770
|
-
diagAddendum = new diagnostic_1.DiagnosticAddendum();
|
4771
|
-
diagAddendum.addMessage(localize_1.LocAddendum.overrideIsInvariant());
|
4772
|
-
diagAddendum.createAddendum().addMessage(localize_1.LocAddendum.overrideInvariantMismatch().format({
|
4773
|
-
overrideType: this._evaluator.printType(overrideType),
|
4774
|
-
baseType: this._evaluator.printType(baseType),
|
4775
|
-
}));
|
4776
|
-
}
|
4777
|
-
const diag = this._evaluator.addDiagnostic(diagnosticRules_1.DiagnosticRule.reportIncompatibleVariableOverride, localize_1.LocMessage.symbolOverridden().format({
|
4778
|
-
name: memberName,
|
4779
|
-
className: baseClass.shared.name,
|
4780
|
-
}) + diagAddendum.getString(), (0, declarationUtils_1.getNameNodeForDeclaration)(lastDecl) ?? lastDecl.node);
|
4781
|
-
const origDecl = (0, symbolUtils_1.getLastTypedDeclarationForSymbol)(baseClassAndSymbol.symbol);
|
4782
|
-
if (diag && origDecl) {
|
4783
|
-
diag.addRelatedInfo(localize_1.LocAddendum.overriddenSymbol(), origDecl.uri, origDecl.range);
|
4784
|
-
}
|
4785
|
-
}
|
4786
|
-
else if (overriddenTDEntry && overrideTDEntry) {
|
4787
|
-
// Make sure the required/not-required attribute is compatible.
|
4788
|
-
let isRequiredCompatible = true;
|
4789
|
-
if (overriddenTDEntry.isReadOnly) {
|
4790
|
-
// If the read-only flag is set, a not-required field can be overridden
|
4791
|
-
// by a required field, but not vice versa.
|
4792
|
-
isRequiredCompatible = overrideTDEntry.isRequired || !overriddenTDEntry.isRequired;
|
4793
|
-
}
|
4794
|
-
else {
|
4795
|
-
isRequiredCompatible = overrideTDEntry.isRequired === overriddenTDEntry.isRequired;
|
4796
|
-
}
|
4797
|
-
if (!isRequiredCompatible) {
|
4798
|
-
const message = overrideTDEntry.isRequired
|
4799
|
-
? localize_1.LocMessage.typedDictFieldRequiredRedefinition
|
4800
|
-
: localize_1.LocMessage.typedDictFieldNotRequiredRedefinition;
|
4801
|
-
this._evaluator.addDiagnostic(diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, message().format({ name: memberName }), (0, declarationUtils_1.getNameNodeForDeclaration)(lastDecl) ?? lastDecl.node);
|
4802
|
-
}
|
4803
|
-
// Make sure that the derived class isn't marking a previously writable
|
4804
|
-
// entry as read-only.
|
4805
|
-
if (!overriddenTDEntry.isReadOnly && overrideTDEntry.isReadOnly) {
|
4806
|
-
this._evaluator.addDiagnostic(diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.LocMessage.typedDictFieldReadOnlyRedefinition().format({
|
4807
|
-
name: memberName,
|
4808
|
-
}), (0, declarationUtils_1.getNameNodeForDeclaration)(lastDecl) ?? lastDecl.node);
|
4809
|
-
}
|
4810
|
-
}
|
4811
|
-
// Verify that there is not a Final mismatch.
|
4812
|
-
const isBaseVarFinal = this._evaluator.isFinalVariable(baseClassAndSymbol.symbol);
|
4813
|
-
const overrideFinalVarDecl = decls.find((d) => this._evaluator.isFinalVariableDeclaration(d));
|
4814
|
-
if (!isBaseVarFinal && overrideFinalVarDecl) {
|
4815
|
-
const diag = this._evaluator.addDiagnostic(diagnosticRules_1.DiagnosticRule.reportIncompatibleVariableOverride, localize_1.LocMessage.variableFinalOverride().format({
|
4816
|
-
name: memberName,
|
4817
|
-
className: baseClass.shared.name,
|
4818
|
-
}), (0, declarationUtils_1.getNameNodeForDeclaration)(lastDecl) ?? lastDecl.node);
|
4819
|
-
if (diag) {
|
4820
|
-
diag.addRelatedInfo(localize_1.LocAddendum.overriddenSymbol(), overrideFinalVarDecl.uri, overrideFinalVarDecl.range);
|
4821
|
-
}
|
4822
|
-
}
|
4823
|
-
// Verify that a class variable isn't overriding an instance
|
4824
|
-
// variable or vice versa.
|
4825
|
-
const isBaseClassVar = baseClassAndSymbol.symbol.isClassVar();
|
4826
|
-
let isClassVar = overrideSymbol.isClassVar();
|
4827
|
-
if (isBaseClassVar && !isClassVar) {
|
4828
|
-
// If the subclass doesn't redeclare the type but simply assigns
|
4829
|
-
// it without declaring its type, we won't consider it an instance
|
4830
|
-
// variable.
|
4831
|
-
if (!overrideSymbol.hasTypedDeclarations()) {
|
4832
|
-
isClassVar = true;
|
4833
|
-
}
|
4834
|
-
// If the subclass is declaring an inner class, we'll consider that
|
4835
|
-
// to be a ClassVar.
|
4836
|
-
if (overrideSymbol.getTypedDeclarations().every((decl) => decl.type === 6 /* DeclarationType.Class */)) {
|
4837
|
-
isClassVar = true;
|
4838
|
-
}
|
4839
|
-
}
|
4840
|
-
// Allow TypedDict members to have the same name as class variables in the
|
4841
|
-
// base class because TypedDict members are not really instance members.
|
4842
|
-
const ignoreTypedDictOverride = types_1.ClassType.isTypedDictClass(childClassType) && !isClassVar;
|
4843
|
-
if (isBaseClassVar !== isClassVar && !ignoreTypedDictOverride) {
|
4844
|
-
const unformattedMessage = overrideSymbol.isClassVar()
|
4845
|
-
? localize_1.LocMessage.classVarOverridesInstanceVar()
|
4846
|
-
: localize_1.LocMessage.instanceVarOverridesClassVar();
|
4847
|
-
const diag = this._evaluator.addDiagnostic(diagnosticRules_1.DiagnosticRule.reportIncompatibleVariableOverride, unformattedMessage.format({
|
4848
|
-
name: memberName,
|
4849
|
-
className: baseClass.shared.name,
|
4850
|
-
}), (0, declarationUtils_1.getNameNodeForDeclaration)(lastDecl) ?? lastDecl.node);
|
4851
|
-
const origDecl = (0, symbolUtils_1.getLastTypedDeclarationForSymbol)(baseClassAndSymbol.symbol);
|
4852
|
-
if (diag && origDecl) {
|
4853
|
-
diag.addRelatedInfo(localize_1.LocAddendum.overriddenSymbol(), origDecl.uri, origDecl.range);
|
4854
|
-
}
|
4654
|
+
// This check can be expensive, so don't perform it if the corresponding
|
4655
|
+
// rule is disabled.
|
4656
|
+
if (this._fileInfo.diagnosticRuleSet.reportIncompatibleVariableOverride !== 'none') {
|
4657
|
+
const decls = overrideSymbol.getDeclarations();
|
4658
|
+
if (decls.length === 0) {
|
4659
|
+
return;
|
4660
|
+
}
|
4661
|
+
const lastDecl = decls[decls.length - 1];
|
4662
|
+
const primaryDecl = decls[0];
|
4663
|
+
// Verify that the override type is assignable to (same or narrower than)
|
4664
|
+
// the declared type of the base symbol.
|
4665
|
+
let isInvariant = primaryDecl?.type === 1 /* DeclarationType.Variable */ && !primaryDecl.isFinal;
|
4666
|
+
// If the entry is a member of a frozen dataclass, it is immutable,
|
4667
|
+
// so it does not need to be invariant.
|
4668
|
+
if (types_1.ClassType.isDataClassFrozen(baseClass) && baseClass.shared.dataClassEntries) {
|
4669
|
+
const dataclassEntry = baseClass.shared.dataClassEntries.find((entry) => entry.name === memberName);
|
4670
|
+
if (dataclassEntry) {
|
4671
|
+
isInvariant = false;
|
4672
|
+
}
|
4673
|
+
}
|
4674
|
+
let overriddenTDEntry;
|
4675
|
+
let overrideTDEntry;
|
4676
|
+
if (!overrideSymbol.isIgnoredForProtocolMatch()) {
|
4677
|
+
if (baseClass.shared.typedDictEntries) {
|
4678
|
+
overriddenTDEntry =
|
4679
|
+
baseClass.shared.typedDictEntries.knownItems.get(memberName) ??
|
4680
|
+
baseClass.shared.typedDictEntries.extraItems ??
|
4681
|
+
(0, typedDicts_1.getEffectiveExtraItemsEntryType)(this._evaluator, baseClass);
|
4682
|
+
if (overriddenTDEntry?.isReadOnly) {
|
4683
|
+
isInvariant = false;
|
4855
4684
|
}
|
4856
4685
|
}
|
4686
|
+
if (childClassType.shared.typedDictEntries) {
|
4687
|
+
overrideTDEntry =
|
4688
|
+
childClassType.shared.typedDictEntries.knownItems.get(memberName) ??
|
4689
|
+
childClassType.shared.typedDictEntries.extraItems ??
|
4690
|
+
(0, typedDicts_1.getEffectiveExtraItemsEntryType)(this._evaluator, childClassType);
|
4691
|
+
}
|
4692
|
+
}
|
4693
|
+
let diagAddendum = new diagnostic_1.DiagnosticAddendum();
|
4694
|
+
if (!this._evaluator.assignType(baseType, overrideType, diagAddendum,
|
4695
|
+
/* constraints */ undefined, isInvariant ? 1 /* AssignTypeFlags.Invariant */ : 0 /* AssignTypeFlags.Default */)) {
|
4696
|
+
if (isInvariant) {
|
4697
|
+
diagAddendum = new diagnostic_1.DiagnosticAddendum();
|
4698
|
+
diagAddendum.addMessage(localize_1.LocAddendum.overrideIsInvariant());
|
4699
|
+
diagAddendum.createAddendum().addMessage(localize_1.LocAddendum.overrideInvariantMismatch().format({
|
4700
|
+
overrideType: this._evaluator.printType(overrideType),
|
4701
|
+
baseType: this._evaluator.printType(baseType),
|
4702
|
+
}));
|
4703
|
+
}
|
4704
|
+
const diag = this._evaluator.addDiagnostic(diagnosticRules_1.DiagnosticRule.reportIncompatibleVariableOverride, localize_1.LocMessage.symbolOverridden().format({
|
4705
|
+
name: memberName,
|
4706
|
+
className: baseClass.shared.name,
|
4707
|
+
}) + diagAddendum.getString(), (0, declarationUtils_1.getNameNodeForDeclaration)(lastDecl) ?? lastDecl.node);
|
4708
|
+
const origDecl = (0, symbolUtils_1.getLastTypedDeclarationForSymbol)(baseClassAndSymbol.symbol);
|
4709
|
+
if (diag && origDecl) {
|
4710
|
+
diag.addRelatedInfo(localize_1.LocAddendum.overriddenSymbol(), origDecl.uri, origDecl.range);
|
4711
|
+
}
|
4712
|
+
}
|
4713
|
+
else if (overriddenTDEntry && overrideTDEntry) {
|
4714
|
+
// Make sure the required/not-required attribute is compatible.
|
4715
|
+
let isRequiredCompatible = true;
|
4716
|
+
if (overriddenTDEntry.isReadOnly) {
|
4717
|
+
// If the read-only flag is set, a not-required field can be overridden
|
4718
|
+
// by a required field, but not vice versa.
|
4719
|
+
isRequiredCompatible = overrideTDEntry.isRequired || !overriddenTDEntry.isRequired;
|
4720
|
+
}
|
4721
|
+
else {
|
4722
|
+
isRequiredCompatible = overrideTDEntry.isRequired === overriddenTDEntry.isRequired;
|
4723
|
+
}
|
4724
|
+
if (!isRequiredCompatible) {
|
4725
|
+
const message = overrideTDEntry.isRequired
|
4726
|
+
? localize_1.LocMessage.typedDictFieldRequiredRedefinition
|
4727
|
+
: localize_1.LocMessage.typedDictFieldNotRequiredRedefinition;
|
4728
|
+
this._evaluator.addDiagnostic(diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, message().format({ name: memberName }), (0, declarationUtils_1.getNameNodeForDeclaration)(lastDecl) ?? lastDecl.node);
|
4729
|
+
}
|
4730
|
+
// Make sure that the derived class isn't marking a previously writable
|
4731
|
+
// entry as read-only.
|
4732
|
+
if (!overriddenTDEntry.isReadOnly && overrideTDEntry.isReadOnly) {
|
4733
|
+
this._evaluator.addDiagnostic(diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.LocMessage.typedDictFieldReadOnlyRedefinition().format({
|
4734
|
+
name: memberName,
|
4735
|
+
}), (0, declarationUtils_1.getNameNodeForDeclaration)(lastDecl) ?? lastDecl.node);
|
4736
|
+
}
|
4737
|
+
}
|
4738
|
+
// Verify that there is not a Final mismatch.
|
4739
|
+
const isBaseVarFinal = this._evaluator.isFinalVariable(baseClassAndSymbol.symbol);
|
4740
|
+
const overrideFinalVarDecl = decls.find((d) => this._evaluator.isFinalVariableDeclaration(d));
|
4741
|
+
if (!isBaseVarFinal && overrideFinalVarDecl) {
|
4742
|
+
const diag = this._evaluator.addDiagnostic(diagnosticRules_1.DiagnosticRule.reportIncompatibleVariableOverride, localize_1.LocMessage.variableFinalOverride().format({
|
4743
|
+
name: memberName,
|
4744
|
+
className: baseClass.shared.name,
|
4745
|
+
}), (0, declarationUtils_1.getNameNodeForDeclaration)(lastDecl) ?? lastDecl.node);
|
4746
|
+
if (diag) {
|
4747
|
+
diag.addRelatedInfo(localize_1.LocAddendum.overriddenSymbol(), overrideFinalVarDecl.uri, overrideFinalVarDecl.range);
|
4748
|
+
}
|
4749
|
+
}
|
4750
|
+
// Verify that a class variable isn't overriding an instance
|
4751
|
+
// variable or vice versa.
|
4752
|
+
const isBaseClassVar = baseClassAndSymbol.symbol.isClassVar();
|
4753
|
+
let isClassVar = overrideSymbol.isClassVar();
|
4754
|
+
if (isBaseClassVar && !isClassVar) {
|
4755
|
+
// If the subclass doesn't redeclare the type but simply assigns
|
4756
|
+
// it without declaring its type, we won't consider it an instance
|
4757
|
+
// variable.
|
4758
|
+
if (!overrideSymbol.hasTypedDeclarations()) {
|
4759
|
+
isClassVar = true;
|
4760
|
+
}
|
4761
|
+
// If the subclass is declaring an inner class, we'll consider that
|
4762
|
+
// to be a ClassVar.
|
4763
|
+
if (overrideSymbol.getTypedDeclarations().every((decl) => decl.type === 6 /* DeclarationType.Class */)) {
|
4764
|
+
isClassVar = true;
|
4765
|
+
}
|
4766
|
+
}
|
4767
|
+
// Allow TypedDict members to have the same name as class variables in the
|
4768
|
+
// base class because TypedDict members are not really instance members.
|
4769
|
+
const ignoreTypedDictOverride = types_1.ClassType.isTypedDictClass(childClassType) && !isClassVar;
|
4770
|
+
if (isBaseClassVar !== isClassVar && !ignoreTypedDictOverride) {
|
4771
|
+
const unformattedMessage = overrideSymbol.isClassVar()
|
4772
|
+
? localize_1.LocMessage.classVarOverridesInstanceVar()
|
4773
|
+
: localize_1.LocMessage.instanceVarOverridesClassVar();
|
4774
|
+
const diag = this._evaluator.addDiagnostic(diagnosticRules_1.DiagnosticRule.reportIncompatibleVariableOverride, unformattedMessage.format({
|
4775
|
+
name: memberName,
|
4776
|
+
className: baseClass.shared.name,
|
4777
|
+
}), (0, declarationUtils_1.getNameNodeForDeclaration)(lastDecl) ?? lastDecl.node);
|
4778
|
+
const origDecl = (0, symbolUtils_1.getLastTypedDeclarationForSymbol)(baseClassAndSymbol.symbol);
|
4779
|
+
if (diag && origDecl) {
|
4780
|
+
diag.addRelatedInfo(localize_1.LocAddendum.overriddenSymbol(), origDecl.uri, origDecl.range);
|
4781
|
+
}
|
4857
4782
|
}
|
4858
4783
|
}
|
4859
4784
|
}
|
4785
|
+
_isFinalFunction(name, type) {
|
4786
|
+
if (SymbolNameUtils.isPrivateName(name)) {
|
4787
|
+
return false;
|
4788
|
+
}
|
4789
|
+
if ((0, types_1.isFunction)(type) && types_1.FunctionType.isFinal(type)) {
|
4790
|
+
return true;
|
4791
|
+
}
|
4792
|
+
if ((0, types_1.isOverloaded)(type)) {
|
4793
|
+
const overloads = types_1.OverloadedType.getOverloads(type);
|
4794
|
+
const impl = types_1.OverloadedType.getImplementation(type);
|
4795
|
+
if (overloads.some((overload) => types_1.FunctionType.isFinal(overload))) {
|
4796
|
+
return true;
|
4797
|
+
}
|
4798
|
+
if (impl && (0, types_1.isFunction)(impl) && types_1.FunctionType.isFinal(impl)) {
|
4799
|
+
return true;
|
4800
|
+
}
|
4801
|
+
}
|
4802
|
+
return false;
|
4803
|
+
}
|
4860
4804
|
_validatePropertyOverride(baseClassType, childClassType, baseType, childType, overrideSymbol, memberName) {
|
4861
4805
|
const propMethodInfo = [
|
4862
4806
|
['fget', (c) => c.priv.fgetInfo?.methodType],
|
@@ -4893,6 +4837,15 @@ class Checker extends parseTreeWalker_1.ParseTreeWalker {
|
|
4893
4837
|
}
|
4894
4838
|
return;
|
4895
4839
|
}
|
4840
|
+
else if (this._isFinalFunction(methodName, baseClassPropMethod)) {
|
4841
|
+
const decl = (0, symbolUtils_1.getLastTypedDeclarationForSymbol)(overrideSymbol);
|
4842
|
+
if (decl && decl.type === 5 /* DeclarationType.Function */) {
|
4843
|
+
this._evaluator.addDiagnostic(diagnosticRules_1.DiagnosticRule.reportIncompatibleMethodOverride, localize_1.LocMessage.finalMethodOverride().format({
|
4844
|
+
name: memberName,
|
4845
|
+
className: baseClassType.shared.name,
|
4846
|
+
}), decl.node.d.name);
|
4847
|
+
}
|
4848
|
+
}
|
4896
4849
|
const subclassMethodType = (0, typeUtils_1.partiallySpecializeType)(subclassPropMethod, childClassType, this._evaluator.getTypeClassType());
|
4897
4850
|
if (!(0, types_1.isFunction)(subclassMethodType)) {
|
4898
4851
|
return;
|