mirror of
https://github.com/microsoft/pyright.git
synced 2024-11-09 13:35:59 +03:00
Added support for property getters, setters and deleters that have generic types for the "self" parameter.
This commit is contained in:
parent
d9ee01b95b
commit
576d327452
@ -2094,8 +2094,12 @@ export function createTypeEvaluator(importLookup: ImportLookup): TypeEvaluator {
|
||||
}
|
||||
|
||||
if (accessMethod) {
|
||||
const accessMethodType = getTypeOfMember(accessMethod);
|
||||
let accessMethodType = getTypeOfMember(accessMethod);
|
||||
if (accessMethodType.category === TypeCategory.Function) {
|
||||
// Bind the accessor to the base object type.
|
||||
accessMethodType = bindFunctionToClassOrObject(ObjectType.create(classType),
|
||||
accessMethodType) as FunctionType;
|
||||
|
||||
if (usage.method === 'get') {
|
||||
type = getFunctionEffectiveReturnType(accessMethodType);
|
||||
type = partiallySpecializeType(type, classType);
|
||||
@ -2104,7 +2108,7 @@ export function createTypeEvaluator(importLookup: ImportLookup): TypeEvaluator {
|
||||
// Verify that the setter's parameter type matches
|
||||
// the type of the value being assigned.
|
||||
if (accessMethodType.details.parameters.length >= 2) {
|
||||
const setValueType = accessMethodType.details.parameters[2].type;
|
||||
const setValueType = accessMethodType.details.parameters[1].type;
|
||||
if (!canAssignType(setValueType, usage.setType!, diag)) {
|
||||
return undefined;
|
||||
}
|
||||
@ -5916,7 +5920,7 @@ export function createTypeEvaluator(importLookup: ImportLookup): TypeEvaluator {
|
||||
getFunction.details.parameters.push({
|
||||
category: ParameterCategory.Simple,
|
||||
name: 'self',
|
||||
type: propertyObject
|
||||
type: fget.details.parameters.length > 0 ? fget.details.parameters[0].type : AnyType.create()
|
||||
});
|
||||
getFunction.details.parameters.push({
|
||||
category: ParameterCategory.Simple,
|
||||
@ -5976,7 +5980,7 @@ export function createTypeEvaluator(importLookup: ImportLookup): TypeEvaluator {
|
||||
setFunction.details.parameters.push({
|
||||
category: ParameterCategory.Simple,
|
||||
name: 'self',
|
||||
type: propertyObject
|
||||
type: fset.details.parameters.length > 0 ? fset.details.parameters[0].type : AnyType.create()
|
||||
});
|
||||
setFunction.details.parameters.push({
|
||||
category: ParameterCategory.Simple,
|
||||
@ -6029,7 +6033,7 @@ export function createTypeEvaluator(importLookup: ImportLookup): TypeEvaluator {
|
||||
delFunction.details.parameters.push({
|
||||
category: ParameterCategory.Simple,
|
||||
name: 'self',
|
||||
type: propertyObject
|
||||
type: fdel.details.parameters.length > 0 ? fdel.details.parameters[0].type : AnyType.create()
|
||||
});
|
||||
delFunction.details.parameters.push({
|
||||
category: ParameterCategory.Simple,
|
||||
|
@ -306,6 +306,12 @@ test('Properties3', () => {
|
||||
validateResults(analysisResults, 4);
|
||||
});
|
||||
|
||||
test('Properties4', () => {
|
||||
const analysisResults = TestUtils.typeAnalyzeSampleFiles(['properties4.py']);
|
||||
|
||||
validateResults(analysisResults, 0);
|
||||
});
|
||||
|
||||
test('Operators1', () => {
|
||||
const analysisResults = TestUtils.typeAnalyzeSampleFiles(['operators1.py']);
|
||||
|
||||
|
17
server/src/tests/samples/properties4.py
Normal file
17
server/src/tests/samples/properties4.py
Normal file
@ -0,0 +1,17 @@
|
||||
# This sample tests the handling of a property that's defined
|
||||
# with a generic type for the "self" parameter.
|
||||
|
||||
from typing import TypeVar
|
||||
|
||||
|
||||
_P = TypeVar('_P', bound=str)
|
||||
|
||||
class Foo(str):
|
||||
@property
|
||||
def parent(self: _P) -> _P: ...
|
||||
|
||||
def requires_foo(a: Foo):
|
||||
pass
|
||||
|
||||
p = Foo().parent
|
||||
requires_foo(p)
|
Loading…
Reference in New Issue
Block a user