Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 16 additions & 8 deletions conformance/results/mypy/overloads_evaluation.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,14 @@ notes = """
Does not expand boolean arguments to `Literal[True]` and `Literal[False]`.
Does not expand enum arguments to literal variants.
Does not expand tuple arguments to possible combinations.
<<<<<<< HEAD
Does not handle unpacked arguments when checking for parameter type equivalence.
Does not evaluate Any in some cases where overload is ambiguous.
Evaluates Any in some cases where overload is not ambiguous.
=======
Does not evaluate `Any` in some cases where overload is ambiguous.
Evaluates `Any` in some cases where overload is not ambiguous.
>>>>>>> main
"""
conformance_automated = "Fail"
errors_diff = """
Expand All @@ -14,10 +20,11 @@ Line 161: Unexpected errors ['overloads_evaluation.py:161: error: No overload va
Line 162: Unexpected errors ['overloads_evaluation.py:162: error: Expression is of type "Any", not "Literal[0, 1]" [assert-type]']
Line 205: Unexpected errors ['overloads_evaluation.py:205: error: Argument 1 to "expand_tuple" has incompatible type "tuple[int, int | str]"; expected "tuple[int, int]" [arg-type]']
Line 206: Unexpected errors ['overloads_evaluation.py:206: error: Expression is of type "int", not "int | str" [assert-type]']
Line 265: Unexpected errors ['overloads_evaluation.py:265: error: Expression is of type "list[Any]", not "Any" [assert-type]']
Line 281: Unexpected errors ['overloads_evaluation.py:281: error: Expression is of type "list[Any]", not "Any" [assert-type]']
Line 303: Unexpected errors ['overloads_evaluation.py:303: error: Expression is of type "Any", not "float" [assert-type]']
Line 347: Unexpected errors ['overloads_evaluation.py:347: error: Expression is of type "list[Any]", not "Any" [assert-type]']
Line 268: Unexpected errors ['overloads_evaluation.py:268: error: Expression is of type "list[Any]", not "Any" [assert-type]']
Line 284: Unexpected errors ['overloads_evaluation.py:284: error: Expression is of type "list[Any]", not "Any" [assert-type]']
Line 306: Unexpected errors ['overloads_evaluation.py:306: error: Expression is of type "Any", not "float" [assert-type]']
Line 350: Unexpected errors ['overloads_evaluation.py:350: error: Expression is of type "list[Any]", not "Any" [assert-type]']
Line 439: Unexpected errors ['overloads_evaluation.py:439: error: Expression is of type "Any", not "bool" [assert-type]']
"""
output = """
overloads_evaluation.py:38: error: All overload variants of "example1_1" require at least one argument [call-overload]
Expand Down Expand Up @@ -46,8 +53,9 @@ overloads_evaluation.py:161: note: def expand_enum(x: Literal[Color.BLUE]) -
overloads_evaluation.py:162: error: Expression is of type "Any", not "Literal[0, 1]" [assert-type]
overloads_evaluation.py:205: error: Argument 1 to "expand_tuple" has incompatible type "tuple[int, int | str]"; expected "tuple[int, int]" [arg-type]
overloads_evaluation.py:206: error: Expression is of type "int", not "int | str" [assert-type]
overloads_evaluation.py:265: error: Expression is of type "list[Any]", not "Any" [assert-type]
overloads_evaluation.py:281: error: Expression is of type "list[Any]", not "Any" [assert-type]
overloads_evaluation.py:303: error: Expression is of type "Any", not "float" [assert-type]
overloads_evaluation.py:347: error: Expression is of type "list[Any]", not "Any" [assert-type]
overloads_evaluation.py:268: error: Expression is of type "list[Any]", not "Any" [assert-type]
overloads_evaluation.py:284: error: Expression is of type "list[Any]", not "Any" [assert-type]
overloads_evaluation.py:306: error: Expression is of type "Any", not "float" [assert-type]
overloads_evaluation.py:350: error: Expression is of type "list[Any]", not "Any" [assert-type]
overloads_evaluation.py:439: error: Expression is of type "Any", not "bool" [assert-type]
"""
14 changes: 13 additions & 1 deletion conformance/results/pycroscope/overloads_evaluation.toml
Original file line number Diff line number Diff line change
@@ -1,9 +1,21 @@
conformance_automated = "Pass"
conformance_automated = "Fail"
errors_diff = """
Line 371: Unexpected errors ['./overloads_evaluation.py:371:16: Any[multiple_overload_matches] is not equivalent to bool']
Line 400: Unexpected errors ['./overloads_evaluation.py:400:16: Any[multiple_overload_matches] is not equivalent to bool']
Line 420: Unexpected errors ['./overloads_evaluation.py:420:16: Any[multiple_overload_matches] is not equivalent to bool']
Line 439: Unexpected errors ['./overloads_evaluation.py:439:16: Any[multiple_overload_matches] is not equivalent to bool']
Line 441: Unexpected errors ['./overloads_evaluation.py:441:16: Any[multiple_overload_matches] is not equivalent to bool']
Line 468: Unexpected errors ['./overloads_evaluation.py:468:16: Any[multiple_overload_matches] is not equivalent to ./overloads_evaluation.py.A[Any[explicit]]']
"""
output = """
./overloads_evaluation.py:38:0: Cannot call overloaded function [incompatible_call]
./overloads_evaluation.py:46:0: Cannot call overloaded function [incompatible_argument]
./overloads_evaluation.py:51:0: Cannot call overloaded function [incompatible_argument]
./overloads_evaluation.py:116:4: Cannot call overloaded function [incompatible_argument]
./overloads_evaluation.py:371:16: Any[multiple_overload_matches] is not equivalent to bool
./overloads_evaluation.py:400:16: Any[multiple_overload_matches] is not equivalent to bool
./overloads_evaluation.py:420:16: Any[multiple_overload_matches] is not equivalent to bool
./overloads_evaluation.py:439:16: Any[multiple_overload_matches] is not equivalent to bool
./overloads_evaluation.py:441:16: Any[multiple_overload_matches] is not equivalent to bool
./overloads_evaluation.py:468:16: Any[multiple_overload_matches] is not equivalent to ./overloads_evaluation.py.A[Any[explicit]]
"""
4 changes: 3 additions & 1 deletion conformance/results/pyrefly/overloads_evaluation.toml
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
conformant = "Pass"
conformance_automated = "Pass"
conformance_automated = "Fail"
errors_diff = """
Line 395: Unexpected errors ['assert_type(int, Any) failed [assert-type]']
"""
output = """
ERROR overloads_evaluation.py:38:11-13: No matching overload found for function `example1_1` called with arguments: () [no-matching-overload]
ERROR overloads_evaluation.py:46:15-16: Argument `Literal[1]` is not assignable to parameter `y` with type `str` in function `example1_1` [bad-argument-type]
ERROR overloads_evaluation.py:51:12-13: Argument `Literal[1]` is not assignable to parameter `x` with type `str` in function `example1_1` [bad-argument-type]
ERROR overloads_evaluation.py:116:13-22: No matching overload found for function `example2` called with arguments: (int | str, int | str, Literal[1]) [no-matching-overload]
ERROR overloads_evaluation.py:395:16-27: assert_type(int, Any) failed [assert-type]
"""
13 changes: 11 additions & 2 deletions conformance/results/pyright/overloads_evaluation.toml
Original file line number Diff line number Diff line change
@@ -1,10 +1,17 @@
conformant = "Partial"
notes = """
<<<<<<< HEAD
Does not evaluate Any in some cases where overload is ambiguous.
Picks first overload instead of most general return type in some cases where overload is ambiguous.
=======
Does not evaluate `Any` in some cases where overload is ambiguous.
>>>>>>> main
"""
conformance_automated = "Fail"
errors_diff = """
Line 281: Unexpected errors ['overloads_evaluation.py:281:17 - error: "assert_type" mismatch: expected "Any" but received "list[int]" (reportAssertTypeFailure)']
Line 284: Unexpected errors ['overloads_evaluation.py:284:17 - error: "assert_type" mismatch: expected "Any" but received "list[int]" (reportAssertTypeFailure)']
Line 395: Unexpected errors ['overloads_evaluation.py:395:17 - error: "assert_type" mismatch: expected "Any" but received "int" (reportAssertTypeFailure)']
Line 468: Unexpected errors ['overloads_evaluation.py:468:17 - error: "assert_type" mismatch: expected "A[Any]" but received "A[None]" (reportAssertTypeFailure)']
"""
output = """
overloads_evaluation.py:38:1 - error: No overloads for "example1_1" match the provided arguments
Expand All @@ -20,5 +27,7 @@ overloads_evaluation.py:116:14 - error: Argument of type "int | str" cannot be a
overloads_evaluation.py:116:17 - error: Argument of type "int | str" cannot be assigned to parameter "y" of type "int" in function "example2"
  Type "int | str" is not assignable to type "int"
    "str" is not assignable to "int" (reportArgumentType)
overloads_evaluation.py:281:17 - error: "assert_type" mismatch: expected "Any" but received "list[int]" (reportAssertTypeFailure)
overloads_evaluation.py:284:17 - error: "assert_type" mismatch: expected "Any" but received "list[int]" (reportAssertTypeFailure)
overloads_evaluation.py:395:17 - error: "assert_type" mismatch: expected "Any" but received "int" (reportAssertTypeFailure)
overloads_evaluation.py:468:17 - error: "assert_type" mismatch: expected "A[Any]" but received "A[None]" (reportAssertTypeFailure)
"""
68 changes: 59 additions & 9 deletions conformance/results/results.html

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 7 additions & 1 deletion conformance/results/ty/overloads_evaluation.toml
Original file line number Diff line number Diff line change
@@ -1,9 +1,15 @@
conformance_automated = "Pass"
conformant = "Partial"
notes = """
Returns Any instead of most general return type for ambiguous calls.
"""
conformance_automated = "Fail"
errors_diff = """
Line 468: Unexpected errors ['overloads_evaluation.py:468:5: error[type-assertion-failure] Type `Unknown` does not match asserted type `A[Any]`']
"""
output = """
overloads_evaluation.py:38:1: error[no-matching-overload] No overload of function `example1_1` matches arguments
overloads_evaluation.py:46:15: error[invalid-argument-type] Argument to function `example1_1` is incorrect: Expected `str`, found `Literal[1]`
overloads_evaluation.py:51:12: error[invalid-argument-type] Argument to function `example1_1` is incorrect: Expected `str`, found `Literal[1]`
overloads_evaluation.py:116:5: error[no-matching-overload] No overload of function `example2` matches arguments
overloads_evaluation.py:468:5: error[type-assertion-failure] Type `Unknown` does not match asserted type `A[Any]`
"""
11 changes: 10 additions & 1 deletion conformance/results/zuban/overloads_evaluation.toml
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
conformance_automated = "Pass"
conformant = "Partial"
notes = """
Does not handle unpacked arguments when checking for parameter type equivalence.
Returns Any instead of most general return type for ambiguous calls.
"""
conformance_automated = "Fail"
errors_diff = """
Line 439: Unexpected errors ['overloads_evaluation.py:439: error: Expression is of type "Any", not "bool" [misc]']
Line 468: Unexpected errors ['overloads_evaluation.py:468: error: Expression is of type "Any", not "A[Any]" [misc]']
"""
output = """
overloads_evaluation.py:38: error: All overload variants of "example1_1" require at least one argument [call-overload]
Expand All @@ -16,4 +23,6 @@ overloads_evaluation.py:51: note: def example1_1(x: int, y: str) -> int
overloads_evaluation.py:51: note: def example1_1(x: str) -> str
overloads_evaluation.py:116: error: Argument 1 to "example2" has incompatible type "int | str"; expected "int" [arg-type]
overloads_evaluation.py:116: error: Argument 2 to "example2" has incompatible type "int | str"; expected "str" [arg-type]
overloads_evaluation.py:439: error: Expression is of type "Any", not "bool" [misc]
overloads_evaluation.py:468: error: Expression is of type "Any", not "A[Any]" [misc]
"""
129 changes: 125 additions & 4 deletions conformance/tests/overloads_evaluation.py
Original file line number Diff line number Diff line change
Expand Up @@ -235,10 +235,13 @@ def check_variadic(v: list[int]) -> None:
assert_type(ret1, int)


# > Step 5: For all arguments, determine whether all possible
# > :term:`materializations <materialize>` of the argument's type are assignable to
# > the corresponding parameter type for each of the remaining overloads. If so,
# > eliminate all of the subsequent remaining overloads.
# > Step 5: For each of the remaining overloads, determine whether all
# > arguments satisfy at least one of the following conditions:
# > - All possible :term:`materializations <materialize>` of the argument's type are
# > assignable to the corresponding parameter type, or
# > - The parameter types corresponding to this argument in all of the remaining overloads
# > are :term:`equivalent`.
# > If so, eliminate all of the subsequent remaining overloads.


@overload
Expand Down Expand Up @@ -345,3 +348,121 @@ def check_example7(v1: list[Any], v2: Any) -> None:

ret3 = example7(v1, v2)
assert_type(ret3, Any)


@overload
def example8(x: str, y: Literal['o1']) -> bool: ...


@overload
def example8(x: str, y: str) -> int: ...


def example8(x: str, y: str) -> bool | int:
return True


def check_example8(x: Any):
# The parameter type corresponding to argument `x` is `str` in both
# overloads, and all materializations of argument `y`'s type of
# `Literal['o1']` match the first overload, so the second overload can be
# eliminated.
ret = example8(x, 'o1')
assert_type(ret, bool)


@overload
def example9(x: str, y: Literal['o1']) -> bool: ...


@overload
def example9(x: bytes, y: Literal['o1', 'o2']) -> bool: ...


@overload
def example9(x: bytes, y: str) -> int: ...


def example9(x: str | bytes, y: str) -> bool | int:
return True


def check_example9(x: Any):
# All three overloads are candidates. The parameter types corresponding to
# argument `x` are `str` and `bytes`, which are not equivalent, so none of
# the overloads can be eliminated. We fall back to `Any`.
ret1 = example9(x, 'o1')
assert_type(ret1, Any)
# The second and third overload are candidates. The parameter type
# corresponding to argument `x` is `bytes` in both candidates, so we can
# eliminate the third overload.
ret2 = example9(x, 'o2')
assert_type(ret2, bool)


@overload
def example10(x: int) -> bool: ...


@overload
def example10(*args: int) -> int: ...


def example10(*args: int, **kwargs: int) -> int:
return 0


def check_example10(x: Any):
# The parameters corresponding to argument `x` (`x` in the first overload
# and `*args` in the second) both have type `int`, so the second overload
# can be eliminated.
ret = example10(x)
assert_type(ret, bool)


@overload
def example11(x: Literal['o1'], y: int, z: str) -> bool: ...


@overload
def example11(x: str, y: int, z: str) -> int: ...


def example11(x: str, y: int, z: str) -> bool | int:
return True


def check_example11(x: Any):
# `*x` maps to `(y: int, z: str)` in both overloads, so the second overload
# can be eliminated.
ret1 = example11('o1', *x)
assert_type(ret1, bool)
ret2 = example11('o1', x, x)
assert_type(ret2, bool)


class A[T]:
x: T

def f(self) -> T:
return self.x


@overload
def example12(x: A[None]) -> A[None]: ...


@overload
def example12(x: A[Any]) -> A[Any]: ...


def example12(x: A[Any]) -> A[Any]:
return x


def check_example12(x: Any):
# Step 5 eliminates the first overload because there exists a
# materialization of `A[Any]` that is not assignable to `A[None]`. Step 6
# picks the second overload.
ret = example12(x)
assert_type(ret, A[Any])
Loading
Loading