Skip to content

Commit

Permalink
Fixed regression that resulted in a false positive error when evaluat…
Browse files Browse the repository at this point in the history
…ing a call expression that targets an overloaded method and one of the arguments is an enum with more than 64 members. This addresses #9784.
  • Loading branch information
erictraut committed Feb 8, 2025
1 parent e08871e commit 4ac8baa
Show file tree
Hide file tree
Showing 2 changed files with 103 additions and 7 deletions.
12 changes: 8 additions & 4 deletions packages/pyright-internal/src/analyzer/typeEvaluator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -552,7 +552,11 @@ const maxEffectiveTypeEvaluationAttempts = 16;

// Maximum number of combinatoric argument type expansions allowed
// when resolving an overload.
const maxOverloadArgTypeExpansionCount = 64;
const maxTotalOverloadArgTypeExpansionCount = 256;

// Maximum size of an enum that will be expanded during overload
// argument type expansion.
const maxSingleOverloadArgTypeExpansionCount = 64;

// Maximum number of recursive function return type inference attempts
// that can be concurrently pending before we give up.
Expand Down Expand Up @@ -9614,7 +9618,7 @@ export function createTypeEvaluator(
expandedArgTypes = expandArgTypes(contextFreeArgTypes!, expandedArgTypes);

// Check for combinatoric explosion and break out of loop.
if (!expandedArgTypes || expandedArgTypes.length > maxOverloadArgTypeExpansionCount) {
if (!expandedArgTypes || expandedArgTypes.length > maxTotalOverloadArgTypeExpansionCount) {
break;
}
}
Expand Down Expand Up @@ -9702,13 +9706,13 @@ export function createTypeEvaluator(
if (isClassInstance(subtype)) {
// Expand any bool or Enum literals.
const expandedLiteralTypes = enumerateLiteralsForType(evaluatorInterface, subtype);
if (expandedLiteralTypes) {
if (expandedLiteralTypes && expandedLiteralTypes.length <= maxSingleOverloadArgTypeExpansionCount) {
appendArray(expandedTypes, expandedLiteralTypes);
return;
}

// Expand any fixed-size tuples.
const expandedTuples = expandTuple(subtype, maxOverloadArgTypeExpansionCount);
const expandedTuples = expandTuple(subtype, maxSingleOverloadArgTypeExpansionCount);
if (expandedTuples) {
appendArray(expandedTypes, expandedTuples);
return;
Expand Down
98 changes: 95 additions & 3 deletions packages/pyright-internal/src/tests/samples/overloadCall4.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,99 @@ def func1(a: A | B, b: A | B | C):
v2 = overloaded1(b)


LargeUnion = Literal["a", "b", "c", "d", "e", "f", "g", 1, 2, 3, 4, 5, 6, 7, 8]
class LargeEnum(Enum):
x00 = 0
x01 = 0
x02 = 0
x03 = 0
x04 = 0
x05 = 0
x06 = 0
x07 = 0
x08 = 0
x09 = 0
x10 = 0
x11 = 0
x12 = 0
x13 = 0
x14 = 0
x15 = 0
x16 = 0
x17 = 0
x18 = 0
x19 = 0
x20 = 0
x21 = 0
x22 = 0
x23 = 0
x24 = 0
x25 = 0
x26 = 0
x27 = 0
x28 = 0
x29 = 0
x30 = 0
x31 = 0
x32 = 0
x33 = 0
x34 = 0
x35 = 0
x36 = 0
x37 = 0
x38 = 0
x39 = 0
x40 = 0
x41 = 0
x42 = 0
x43 = 0
x44 = 0
x45 = 0
x46 = 0
x47 = 0
x48 = 0
x49 = 0
x50 = 0
x51 = 0
x52 = 0
x53 = 0
x54 = 0
x55 = 0
x56 = 0
x57 = 0
x58 = 0
x59 = 0
x60 = 0
x61 = 0
x62 = 0
x63 = 0
x64 = 0
x65 = 0
x66 = 0
x67 = 0
x68 = 0
x69 = 0


LargeUnion = (
Literal[
"a",
"b",
"c",
"d",
"e",
"f",
"g",
1,
2,
3,
4,
5,
6,
7,
8,
]
| LargeEnum
)


@overload
Expand All @@ -63,15 +155,15 @@ def overloaded2(a: LargeUnion, b: Literal[10]) -> float: ...
def overloaded2(a: LargeUnion, b: LargeUnion | Literal[9, 10]) -> str | float: ...


def func2(a: LargeUnion, b: Literal[2, 3, 4], c: Literal[2, 3, 4, 9, 10]):
def func2(a: LargeUnion, b: Literal[2, 3, 4], c: Literal[2, 3, 4, 9, 10] | LargeEnum):
v1 = overloaded2("a", 2)
reveal_type(v1, expected_text="str")

v2 = overloaded2(a, b)
reveal_type(v2, expected_text="str | float")

# This should generate an error because the expansion of union types
# will exceed the max number of expansions (64).
# will exceed the max number of expansions (256).
v3 = overloaded2(a, c)
reveal_type(v2, expected_text="str | float")

Expand Down

0 comments on commit 4ac8baa

Please sign in to comment.