@zzzen/pyright-internal 1.2.0-dev.20260712 → 1.2.0-dev.20260719
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/checker.d.ts +2 -0
- package/dist/analyzer/checker.js +89 -4
- package/dist/analyzer/checker.js.map +1 -1
- package/dist/analyzer/functionTransform.js +188 -0
- package/dist/analyzer/functionTransform.js.map +1 -1
- package/dist/analyzer/packageTypeVerifier.js +11 -1
- package/dist/analyzer/packageTypeVerifier.js.map +1 -1
- package/dist/analyzer/properties.js +73 -8
- package/dist/analyzer/properties.js.map +1 -1
- package/dist/analyzer/typeEvaluator.js +7 -1
- package/dist/analyzer/typeEvaluator.js.map +1 -1
- package/dist/analyzer/typeGuards.js +1 -1
- package/dist/analyzer/typeGuards.js.map +1 -1
- package/dist/analyzer/typeUtils.js.map +1 -1
- package/dist/analyzer/types.d.ts +1 -1
- package/dist/analyzer/types.js.map +1 -1
- package/dist/tests/typeEvaluator3.test.js +6 -0
- package/dist/tests/typeEvaluator3.test.js.map +1 -1
- package/dist/tests/typeEvaluator8.test.js +38 -0
- package/dist/tests/typeEvaluator8.test.js.map +1 -1
- package/package.json +1 -1
|
@@ -145,6 +145,8 @@ export declare class Checker extends ParseTreeWalker {
|
|
|
145
145
|
private _validateOverrideDecoratorPresent;
|
|
146
146
|
private _isMethodExemptFromLsp;
|
|
147
147
|
private _validateOverrideDecoratorNotPresent;
|
|
148
|
+
private _getCallableVariableOverrideComparison;
|
|
149
|
+
private _markFunctionStatic;
|
|
148
150
|
private _validateBaseClassOverride;
|
|
149
151
|
private _isFinalFunction;
|
|
150
152
|
private _validatePropertyOverride;
|
package/dist/analyzer/checker.js
CHANGED
|
@@ -4121,7 +4121,17 @@ class Checker extends parseTreeWalker_1.ParseTreeWalker {
|
|
|
4121
4121
|
if ((0, types_1.isFunctionOrOverloaded)(overriddenType)) {
|
|
4122
4122
|
const diagAddendum = new diagnostic_1.DiagnosticAddendum();
|
|
4123
4123
|
if ((0, types_1.isFunctionOrOverloaded)(overrideType)) {
|
|
4124
|
-
|
|
4124
|
+
// If one base defines the member as a plain callable variable and a
|
|
4125
|
+
// sibling base overrides it with a real method, bind the method's "self"
|
|
4126
|
+
// so the two are compared as plain callables (mirrors the single-base
|
|
4127
|
+
// override handling in `_validateBaseClassOverride`). This is
|
|
4128
|
+
// load-bearing for parametered callables (e.g. `Callable[[int], None]`
|
|
4129
|
+
// vs `def cb(self, value: int)`): without binding, the method's extra
|
|
4130
|
+
// "self" causes a spurious arity mismatch. See the `DiamondParam*`
|
|
4131
|
+
// samples in methodOverride7.py.
|
|
4132
|
+
const childClassSelf = types_1.ClassType.cloneAsInstance((0, typeUtils_1.selfSpecializeClass)(childClassType, { useBoundTypeVars: true }));
|
|
4133
|
+
const { baseType: overriddenTypeForComparison, overrideType: overrideTypeForComparison } = this._getCallableVariableOverrideComparison(overriddenClassAndSymbol.symbol, overrideClassAndSymbol.symbol, overriddenType, overrideType, childClassType, childClassSelf);
|
|
4134
|
+
if (!this._evaluator.validateOverrideMethod(overriddenTypeForComparison, overrideTypeForComparison,
|
|
4125
4135
|
/* baseClass */ undefined, diagAddendum,
|
|
4126
4136
|
/* enforceParamNameMatch */ true)) {
|
|
4127
4137
|
if (overrideDecl && overrideDecl.type === 5 /* DeclarationType.Function */) {
|
|
@@ -4242,6 +4252,10 @@ class Checker extends parseTreeWalker_1.ParseTreeWalker {
|
|
|
4242
4252
|
// Is the method present on the base class but missing in the subclass?
|
|
4243
4253
|
if (baseClassPropMethod) {
|
|
4244
4254
|
const baseClassMethodType = (0, typeUtils_1.partiallySpecializeType)(baseClassPropMethod, overriddenClassType, this._evaluator.getTypeClassType());
|
|
4255
|
+
// Overloaded accessors (e.g. overloaded property setters) are
|
|
4256
|
+
// represented as an OverloadedType rather than a FunctionType.
|
|
4257
|
+
// Override-compatibility checking for overloaded accessors is not
|
|
4258
|
+
// yet performed; only single-function accessors are validated here.
|
|
4245
4259
|
if ((0, types_1.isFunction)(baseClassMethodType)) {
|
|
4246
4260
|
if (!subclassPropMethod) {
|
|
4247
4261
|
// The method is missing.
|
|
@@ -4513,7 +4527,7 @@ class Checker extends parseTreeWalker_1.ParseTreeWalker {
|
|
|
4513
4527
|
}
|
|
4514
4528
|
}
|
|
4515
4529
|
else if ((0, types_1.isClassInstance)(overrideType) && types_1.ClassType.isPropertyClass(overrideType)) {
|
|
4516
|
-
if (overrideType.priv.fgetInfo) {
|
|
4530
|
+
if (overrideType.priv.fgetInfo && (0, types_1.isFunction)(overrideType.priv.fgetInfo.methodType)) {
|
|
4517
4531
|
overrideFunction = overrideType.priv.fgetInfo.methodType;
|
|
4518
4532
|
}
|
|
4519
4533
|
}
|
|
@@ -4566,7 +4580,7 @@ class Checker extends parseTreeWalker_1.ParseTreeWalker {
|
|
|
4566
4580
|
}
|
|
4567
4581
|
}
|
|
4568
4582
|
else if ((0, types_1.isClassInstance)(overrideType) && types_1.ClassType.isPropertyClass(overrideType)) {
|
|
4569
|
-
if (overrideType.priv.fgetInfo) {
|
|
4583
|
+
if (overrideType.priv.fgetInfo && (0, types_1.isFunction)(overrideType.priv.fgetInfo.methodType)) {
|
|
4570
4584
|
overrideFunction = overrideType.priv.fgetInfo.methodType;
|
|
4571
4585
|
}
|
|
4572
4586
|
}
|
|
@@ -4581,6 +4595,65 @@ class Checker extends parseTreeWalker_1.ParseTreeWalker {
|
|
|
4581
4595
|
const funcNode = overrideFunction.shared.declaration.node;
|
|
4582
4596
|
this._evaluator.addDiagnostic(diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.LocMessage.overriddenMethodNotFound().format({ name: funcNode.d.name.d.value }), funcNode.d.name);
|
|
4583
4597
|
}
|
|
4598
|
+
// If a base class member is a plain callable variable (e.g. `x: Callable[..., None]`)
|
|
4599
|
+
// and the override is a real method, accessing the override on an instance binds its
|
|
4600
|
+
// "self" parameter, leaving a signature that should be compared against the base
|
|
4601
|
+
// callable. This helper detects that asymmetry and returns adjusted types: the bound
|
|
4602
|
+
// override and the base callable, both marked static so the override comparison does
|
|
4603
|
+
// not skip the first parameter as an unbound "self". All other cases are returned
|
|
4604
|
+
// unchanged. This matches the behavior of other type checkers, which allow overriding
|
|
4605
|
+
// a callable attribute with a method.
|
|
4606
|
+
//
|
|
4607
|
+
// Note: this validates only the read direction (the bound override is compatible with
|
|
4608
|
+
// the base callable). A method is effectively read-only, so this intentionally does not
|
|
4609
|
+
// attempt to preserve assignability of the mutable callable attribute; that asymmetry
|
|
4610
|
+
// matches other type checkers and does not trigger `reportIncompatibleVariableOverride`
|
|
4611
|
+
// because the override is a function, not a variable.
|
|
4612
|
+
_getCallableVariableOverrideComparison(baseSymbol, overrideSymbol, baseType, overrideType, childClassType, childClassSelf) {
|
|
4613
|
+
const baseDecls = baseSymbol.getDeclarations();
|
|
4614
|
+
const baseIsCallableVariable = baseDecls.length > 0 && baseDecls.every((decl) => decl.type === 1 /* DeclarationType.Variable */);
|
|
4615
|
+
const overrideIsMethod = overrideSymbol
|
|
4616
|
+
.getDeclarations()
|
|
4617
|
+
.some((decl) => decl.type === 5 /* DeclarationType.Function */);
|
|
4618
|
+
if (!baseIsCallableVariable || !overrideIsMethod) {
|
|
4619
|
+
return { baseType, overrideType };
|
|
4620
|
+
}
|
|
4621
|
+
const boundOverrideType = this._evaluator.bindFunctionToClassOrObject(childClassSelf, overrideType, childClassType);
|
|
4622
|
+
if (!boundOverrideType) {
|
|
4623
|
+
return { baseType, overrideType };
|
|
4624
|
+
}
|
|
4625
|
+
// Mark both the base callable and the bound override as static so the
|
|
4626
|
+
// override comparison does not skip the first parameter as an unbound
|
|
4627
|
+
// "self" (see the `i === 0` self/cls skip in typeEvaluator's
|
|
4628
|
+
// `validateOverrideMethodInternal`). Without this, the bound override
|
|
4629
|
+
// keeps its instance-method flag and its first real parameter would be
|
|
4630
|
+
// silently dropped during the comparison.
|
|
4631
|
+
const staticBaseType = (0, types_1.isFunction)(baseType) ? this._markFunctionStatic(baseType) : baseType;
|
|
4632
|
+
if ((0, types_1.isFunction)(boundOverrideType)) {
|
|
4633
|
+
return {
|
|
4634
|
+
baseType: staticBaseType,
|
|
4635
|
+
overrideType: this._markFunctionStatic(boundOverrideType),
|
|
4636
|
+
};
|
|
4637
|
+
}
|
|
4638
|
+
if ((0, types_1.isOverloaded)(boundOverrideType)) {
|
|
4639
|
+
// An overloaded method binds to an overloaded callable. Apply the
|
|
4640
|
+
// same static normalization to every overload (and the
|
|
4641
|
+
// implementation, if present) so an incompatible first parameter in
|
|
4642
|
+
// an overloaded override is still caught rather than skipped as
|
|
4643
|
+
// "self".
|
|
4644
|
+
const staticOverloads = types_1.OverloadedType.getOverloads(boundOverrideType).map((overload) => this._markFunctionStatic(overload));
|
|
4645
|
+
const impl = types_1.OverloadedType.getImplementation(boundOverrideType);
|
|
4646
|
+
const staticImpl = impl && (0, types_1.isFunction)(impl) ? this._markFunctionStatic(impl) : impl;
|
|
4647
|
+
return {
|
|
4648
|
+
baseType: staticBaseType,
|
|
4649
|
+
overrideType: types_1.OverloadedType.create(staticOverloads, staticImpl),
|
|
4650
|
+
};
|
|
4651
|
+
}
|
|
4652
|
+
return { baseType, overrideType: boundOverrideType };
|
|
4653
|
+
}
|
|
4654
|
+
_markFunctionStatic(functionType) {
|
|
4655
|
+
return types_1.FunctionType.cloneWithNewFlags(functionType, functionType.shared.flags | 4 /* FunctionTypeFlags.StaticMethod */);
|
|
4656
|
+
}
|
|
4584
4657
|
_validateBaseClassOverride(baseClassAndSymbol, overrideSymbol, overrideType, childClassType, memberName) {
|
|
4585
4658
|
if (!(0, types_1.isInstantiableClass)(baseClassAndSymbol.classType)) {
|
|
4586
4659
|
return;
|
|
@@ -4643,7 +4716,15 @@ class Checker extends parseTreeWalker_1.ParseTreeWalker {
|
|
|
4643
4716
|
// are misnamed in typeshed stubs, so this would result in many
|
|
4644
4717
|
// false positives.
|
|
4645
4718
|
const enforceParamNameMatch = !SymbolNameUtils.isDunderName(memberName);
|
|
4646
|
-
|
|
4719
|
+
// If the base class member is a plain callable variable
|
|
4720
|
+
// (e.g. `x: Callable[..., None]`) rather than an actual method,
|
|
4721
|
+
// bind the override method's "self" so the two are compared as
|
|
4722
|
+
// plain callables. The declaration scans needed to detect this
|
|
4723
|
+
// are computed inside this helper, so the common method-vs-method
|
|
4724
|
+
// path and the exempt/private/TypedDict early-returns above pay
|
|
4725
|
+
// nothing extra.
|
|
4726
|
+
const { baseType: baseTypeForComparison, overrideType: overrideTypeForComparison } = this._getCallableVariableOverrideComparison(baseClassAndSymbol.symbol, overrideSymbol, baseType, overrideType, childClassType, childClassSelf);
|
|
4727
|
+
if (this._evaluator.validateOverrideMethod(baseTypeForComparison, overrideTypeForComparison, childClassType, diagAddendum, enforceParamNameMatch)) {
|
|
4647
4728
|
return;
|
|
4648
4729
|
}
|
|
4649
4730
|
const decl = (0, symbolUtils_1.getLastTypedDeclarationForSymbol)(overrideSymbol);
|
|
@@ -4867,6 +4948,10 @@ class Checker extends parseTreeWalker_1.ParseTreeWalker {
|
|
|
4867
4948
|
// Is the method present on the base class but missing in the subclass?
|
|
4868
4949
|
if (baseClassPropMethod) {
|
|
4869
4950
|
const baseClassMethodType = (0, typeUtils_1.partiallySpecializeType)(baseClassPropMethod, baseClassType, this._evaluator.getTypeClassType());
|
|
4951
|
+
// Overloaded accessors (e.g. overloaded property setters) are
|
|
4952
|
+
// represented as an OverloadedType rather than a FunctionType.
|
|
4953
|
+
// Override-compatibility checking for overloaded accessors is not
|
|
4954
|
+
// yet performed; skip them rather than misreporting.
|
|
4870
4955
|
if (!(0, types_1.isFunction)(baseClassMethodType)) {
|
|
4871
4956
|
return;
|
|
4872
4957
|
}
|