Skip to content

Function compatibility rewrite #2521

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

Merged
merged 18 commits into from
Dec 22, 2016
Merged
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
10 changes: 5 additions & 5 deletions mypy/checker.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,8 @@
from mypy.checkmember import map_type_from_supertype, bind_self, erase_to_bound
from mypy import messages
from mypy.subtypes import (
is_subtype, is_equivalent, is_proper_subtype, is_more_precise, restrict_subtype_away,
is_subtype_ignoring_tvars
is_subtype, is_equivalent, is_proper_subtype, is_more_precise,
restrict_subtype_away, is_subtype_ignoring_tvars
)
from mypy.maptype import map_instance_to_supertype
from mypy.semanal import fill_typevars, set_callable_name, refers_to_fullname
Expand Down Expand Up @@ -835,7 +835,7 @@ def check_inplace_operator_method(self, defn: FuncBase) -> None:
def check_getattr_method(self, typ: CallableType, context: Context) -> None:
method_type = CallableType([AnyType(), self.named_type('builtins.str')],
[nodes.ARG_POS, nodes.ARG_POS],
[None],
[None, None],
AnyType(),
self.named_type('builtins.function'))
if not is_subtype(typ, method_type):
Expand Down Expand Up @@ -936,7 +936,7 @@ def check_override(self, override: FunctionLike, original: FunctionLike,
"""
# Use boolean variable to clarify code.
fail = False
if not is_subtype(override, original):
if not is_subtype(override, original, ignore_pos_arg_names=True):
fail = True
elif (not isinstance(original, Overloaded) and
isinstance(override, Overloaded) and
Expand Down Expand Up @@ -1043,7 +1043,7 @@ def check_compatibility(self, name: str, base1: TypeInfo,
# Method override
first_sig = bind_self(first_type)
second_sig = bind_self(second_type)
ok = is_subtype(first_sig, second_sig)
ok = is_subtype(first_sig, second_sig, ignore_pos_arg_names=True)
elif first_type and second_type:
ok = is_equivalent(first_type, second_type)
else:
Expand Down
37 changes: 34 additions & 3 deletions mypy/messages.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
)
from mypy.nodes import (
TypeInfo, Context, MypyFile, op_methods, FuncDef, reverse_type_aliases,
ARG_STAR, ARG_STAR2
ARG_POS, ARG_OPT, ARG_NAMED, ARG_NAMED_OPT, ARG_STAR, ARG_STAR2
)


Expand Down Expand Up @@ -77,6 +77,15 @@
TYPEDDICT_ITEM_NAME_MUST_BE_STRING_LITERAL = \
'Expected TypedDict item name to be string literal'

ARG_CONSTRUCTOR_NAMES = {
ARG_POS: "Arg",
ARG_OPT: "DefaultArg",
ARG_NAMED: "NamedArg",
ARG_NAMED_OPT: "DefaultNamedArg",
ARG_STAR: "StarArg",
ARG_STAR2: "KwArg",
}


class MessageBuilder:
"""Helper class for reporting type checker error messages with parameters.
Expand Down Expand Up @@ -176,8 +185,30 @@ def format(self, typ: Type, verbosity: int = 0) -> str:
return_type = strip_quotes(self.format(func.ret_type))
if func.is_ellipsis_args:
return 'Callable[..., {}]'.format(return_type)
arg_types = [strip_quotes(self.format(t)) for t in func.arg_types]
return 'Callable[[{}], {}]'.format(", ".join(arg_types), return_type)
arg_strings = []
for arg_name, arg_type, arg_kind in zip(
func.arg_names, func.arg_types, func.arg_kinds):
if (arg_kind == ARG_POS and arg_name is None
or verbosity == 0 and arg_kind in (ARG_POS, ARG_OPT)):

arg_strings.append(
strip_quotes(
self.format(
arg_type,
verbosity = max(verbosity - 1, 0))))
else:
constructor = ARG_CONSTRUCTOR_NAMES[arg_kind]
if arg_kind in (ARG_STAR, ARG_STAR2):
arg_strings.append("{}({})".format(
constructor,
strip_quotes(self.format(arg_type))))
else:
arg_strings.append("{}('{}', {})".format(
constructor,
arg_name,
strip_quotes(self.format(arg_type))))

return 'Callable[[{}], {}]'.format(", ".join(arg_strings), return_type)
else:
# Use a simple representation for function types; proper
# function types may result in long and difficult-to-read
Expand Down
Loading