-
-
Notifications
You must be signed in to change notification settings - Fork 2.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
List possible overload variants when none match #5296
Changes from 5 commits
3ebeee4
67d8e7d
c363f62
2f73a18
83f0275
873521b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -749,7 +749,10 @@ def deleted_as_lvalue(self, typ: DeletedType, context: Context) -> None: | |
s = " '{}'".format(typ.source) | ||
self.fail('Assignment to variable{} outside except: block'.format(s), context) | ||
|
||
def no_variant_matches_arguments(self, overload: Overloaded, arg_types: List[Type], | ||
def no_variant_matches_arguments(self, | ||
plausible_targets: List[CallableType], | ||
overload: Overloaded, | ||
arg_types: List[Type], | ||
context: Context) -> None: | ||
name = callable_name(overload) | ||
if name: | ||
|
@@ -768,6 +771,8 @@ def no_variant_matches_arguments(self, overload: Overloaded, arg_types: List[Typ | |
self.fail('No overload variant{} matches argument types {}' | ||
.format(name_str, arg_types_str), context) | ||
|
||
self.pretty_overload_matches(plausible_targets, overload, context, offset=2, max_items=2) | ||
|
||
def wrong_number_values_to_unpack(self, provided: int, expected: int, | ||
context: Context) -> None: | ||
if provided < expected: | ||
|
@@ -1233,14 +1238,49 @@ def report_protocol_problems(self, subtype: Union[Instance, TupleType, TypedDict | |
.format(supertype.type.name(), name), context) | ||
self.print_more(conflict_flags, context, OFFSET, MAX_ITEMS) | ||
|
||
def pretty_overload(self, tp: Overloaded, context: Context, | ||
def pretty_overload(self, func: Overloaded, context: Context, | ||
offset: int, max_items: int) -> None: | ||
for item in tp.items()[:max_items]: | ||
targets = func.items() | ||
for item in targets[:max_items]: | ||
self.note('@overload', context, offset=2 * offset) | ||
self.note(self.pretty_callable(item), context, offset=2 * offset) | ||
if len(tp.items()) > max_items: | ||
self.note('<{} more overload(s) not shown>'.format(len(tp.items()) - max_items), | ||
context, offset=2 * offset) | ||
|
||
max_available = len(targets) | ||
shown = min(max_items, max_available) | ||
if shown < max_available: | ||
left = max_available - shown | ||
msg = '<{} more overload{} not shown>'.format(left, plural_s(left)) | ||
self.note(msg, context, offset=2 * offset) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. All changes in this function are unnecessary now, except |
||
|
||
def pretty_overload_matches(self, | ||
targets: List[CallableType], | ||
func: Overloaded, | ||
context: Context, | ||
offset: int, | ||
max_items: int) -> None: | ||
if not targets: | ||
targets = func.items() | ||
|
||
shown = min(max_items, len(targets)) | ||
max_matching = len(targets) | ||
max_available = len(func.items()) | ||
|
||
self.note('Possible overload variant{}:'.format(plural_s(shown)), context) | ||
for item in targets[:max_items]: | ||
self.note(self.pretty_callable(item), context, offset=2 * offset) | ||
|
||
assert shown <= max_matching <= max_available | ||
if shown < max_matching <= max_available: | ||
left = max_matching - shown | ||
msg = '<{} more matching overload{} not shown, out of {} total overloads>'.format( | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I would rather say this as |
||
left, plural_s(left), max_available) | ||
self.note(msg, context, offset=2 * offset) | ||
elif shown == max_matching < max_available: | ||
left = max_available - shown | ||
msg = '<{} more non-matching overload{} not shown>'.format(left, plural_s(left)) | ||
self.note(msg, context, offset=2 * offset) | ||
else: | ||
assert shown == max_matching == max_available | ||
|
||
def print_more(self, conflicts: Sequence[Any], context: Context, | ||
offset: int, max_items: int) -> None: | ||
|
@@ -1405,8 +1445,9 @@ def strip_quotes(s: str) -> str: | |
return s | ||
|
||
|
||
def plural_s(s: Sequence[Any]) -> str: | ||
if len(s) > 1: | ||
def plural_s(s: Union[int, Sequence[Any]]) -> str: | ||
count = s if isinstance(s, int) else len(s) | ||
if count > 1: | ||
return 's' | ||
else: | ||
return '' | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The extra line with
@overload
just doubles the verbosity without adding any information. I think it's okay to leave it out.