Skip to content

Commit

Permalink
Added support for evaluating the slice class type arguments for sli…
Browse files Browse the repository at this point in the history
…ce expressions. This addresses #9533.
  • Loading branch information
erictraut committed Dec 2, 2024
1 parent 099c43f commit f8e444b
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 9 deletions.
40 changes: 31 additions & 9 deletions packages/pyright-internal/src/analyzer/typeEvaluator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15015,23 +15015,45 @@ export function createTypeEvaluator(
}

function getTypeOfSlice(node: SliceNode): TypeResult {
const noneType = getNoneType();
let startType = noneType;
let endType = noneType;
let stepType = noneType;
let isIncomplete = false;

// Evaluate the expressions to report errors and record symbol
// references. We can skip this if we're executing speculatively.
if (!isSpeculativeModeInUse(node)) {
if (node.d.startValue) {
getTypeOfExpression(node.d.startValue);
// references.
if (node.d.startValue) {
const startTypeResult = getTypeOfExpression(node.d.startValue);
startType = startTypeResult.type;
if (startTypeResult.isIncomplete) {
isIncomplete = true;
}
}

if (node.d.endValue) {
getTypeOfExpression(node.d.endValue);
if (node.d.endValue) {
const endTypeResult = getTypeOfExpression(node.d.endValue);
endType = endTypeResult.type;
if (endTypeResult.isIncomplete) {
isIncomplete = true;
}
}

if (node.d.stepValue) {
getTypeOfExpression(node.d.stepValue);
if (node.d.stepValue) {
const stepTypeResult = getTypeOfExpression(node.d.stepValue);
stepType = stepTypeResult.type;
if (stepTypeResult.isIncomplete) {
isIncomplete = true;
}
}

return { type: getBuiltInObject(node, 'slice') };
const sliceType = getBuiltInObject(node, 'slice');

if (!isClassInstance(sliceType)) {
return { type: sliceType };
}

return { type: ClassType.specialize(sliceType, [startType, endType, stepType]), isIncomplete };
}

// Verifies that a type argument's type is not disallowed.
Expand Down
10 changes: 10 additions & 0 deletions packages/pyright-internal/src/tests/samples/slice1.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# This sample tests the evaluation of slice types.

class ClassA:
def __getitem__[T](self, item: T) -> T:
return item
a1 = ClassA()

reveal_type(a1[::], expected_text="slice[None, None, None]")
reveal_type(a1[1:'a':False], expected_text="slice[Literal[1], Literal['a'], Literal[False]]")
reveal_type(a1[:3:5.0], expected_text="slice[None, Literal[3], float]")
5 changes: 5 additions & 0 deletions packages/pyright-internal/src/tests/typeEvaluator4.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -851,3 +851,8 @@ test('ParamSpec53', () => {
const results = TestUtils.typeAnalyzeSampleFiles(['paramSpec53.py']);
TestUtils.validateResults(results, 0);
});

test('Slice1', () => {
const results = TestUtils.typeAnalyzeSampleFiles(['slice1.py']);
TestUtils.validateResults(results, 0);
});

0 comments on commit f8e444b

Please sign in to comment.