Skip to content

Commit

Permalink
Improved reportUnnecessaryCast so it works with types other than cl… (
Browse files Browse the repository at this point in the history
microsoft#5336)

Improved `reportUnnecessaryCast` so it works with types other than class instances. This addresses microsoft#5333.
  • Loading branch information
erictraut authored Jun 18, 2023
1 parent 52c8cac commit 8ce23eb
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 8 deletions.
4 changes: 2 additions & 2 deletions packages/pyright-internal/src/analyzer/typeEvaluator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8913,9 +8913,9 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions
// Verify that the cast is necessary.
const castToType = getTypeOfArgumentExpectingType(argList[0]).type;
const castFromType = getTypeOfArgument(argList[1]).type;
if (isInstantiableClass(castToType) && isClassInstance(castFromType)) {
if (TypeBase.isInstantiable(castToType) && !isUnknown(castToType)) {
if (
isTypeSame(castToType, ClassType.cloneAsInstantiable(castFromType), {
isTypeSame(convertToInstance(castToType), castFromType, {
ignorePseudoGeneric: true,
})
) {
Expand Down
2 changes: 1 addition & 1 deletion packages/pyright-internal/src/tests/checker.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -261,7 +261,7 @@ test('UnnecessaryCast1', () => {
// Turn on errors.
configOptions.diagnosticRuleSet.reportUnnecessaryCast = 'error';
analysisResults = TestUtils.typeAnalyzeSampleFiles(['unnecessaryCast1.py'], configOptions);
TestUtils.validateResults(analysisResults, 1);
TestUtils.validateResults(analysisResults, 6);
});

test('UnnecessaryContains1', () => {
Expand Down
51 changes: 46 additions & 5 deletions packages/pyright-internal/src/tests/samples/unnecessaryCast1.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,54 @@
# This sample tests the type checker's reportUnnecessaryCast feature.

from typing import cast, Union
from typing import Never, NoReturn, TypeVar, cast


def foo(a: int):
def func1(a: int):
# This should generate an error if
# reportUnnecessaryCast is enabled.
b = cast(int, a)
v1 = cast(int, a)


c: Union[int, str] = "hello"
d = cast(int, c)
def func2(a: int | str):
v1 = cast(int, a)

b: str = "hello"
v2 = cast(int, b)


def func3(a: int | None):
v1 = cast(int, a)

# This should generate an error if
# reportUnnecessaryCast is enabled.
v2 = cast(int | None, a)


T = TypeVar("T")


def func4(a: list[T]) -> list[T]:
# This should generate an error if
# reportUnnecessaryCast is enabled.
v1 = cast(list[T], a)

return a


def func5(a: Never):
# This should generate an error if
# reportUnnecessaryCast is enabled.
v1 = cast(NoReturn, a)


def func6(a: type[int], b: int):
v1 = cast(int, a)
v2 = cast(type[int], b)

# This should generate an error if
# reportUnnecessaryCast is enabled.
v3 = cast(type[int], a)

# This should generate an error if
# reportUnnecessaryCast is enabled.
v4 = cast(int, b)

0 comments on commit 8ce23eb

Please sign in to comment.