Skip to content

Commit

Permalink
mention the affected overload
Browse files Browse the repository at this point in the history
  • Loading branch information
tyralla committed Jul 4, 2024
1 parent 978b1a2 commit b0ced07
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 10 deletions.
20 changes: 14 additions & 6 deletions mypy/checker.py
Original file line number Diff line number Diff line change
Expand Up @@ -639,7 +639,7 @@ def _visit_overloaded_func_def(self, defn: OverloadedFuncDef) -> None:

for item in defn.items:
if isinstance(item, Decorator) and isinstance(ct := item.func.type, CallableType):
ct.deprecated = self.get_deprecation_warning(item.decorators)
ct.deprecated = self.get_deprecation_warning(item.decorators, ct)

if defn.is_property:
# HACK: Infer the type of the property.
Expand Down Expand Up @@ -5028,8 +5028,8 @@ def visit_del_stmt(self, s: DelStmt) -> None:
)

def visit_decorator(self, e: Decorator) -> None:
if isinstance(co := e.func.type, (CallableType, Overloaded)):
co.deprecated = self.get_deprecation_warning(e.decorators)
if isinstance(ct := e.func.type, CallableType):
ct.deprecated = self.get_deprecation_warning(e.decorators, ct)
for d in e.decorators:
if isinstance(d, RefExpr):
if d.fullname == "typing.no_type_check":
Expand Down Expand Up @@ -7557,10 +7557,14 @@ def has_valid_attribute(self, typ: Type, name: str) -> bool:
def get_expression_type(self, node: Expression, type_context: Type | None = None) -> Type:
return self.expr_checker.accept(node, type_context=type_context)

def get_deprecation_warning(self, decorators: Iterable[Expression]) -> str | None:
def get_deprecation_warning(
self, decorators: Iterable[Expression], callable: CallableType | None = None
) -> str | None:
overload = False
deprecation = None
for decorator in decorators:
if (isinstance(decorator, NameExpr) and (decorator.fullname in OVERLOAD_NAMES)):
overload = True
if deprecation is not None:
self.msg.note("@overload should be placed before @deprecated", decorator)
elif (
Expand All @@ -7572,7 +7576,11 @@ def get_deprecation_warning(self, decorators: Iterable[Expression]) -> str | Non
and ((value := arg.value) is not None)
):
deprecation = value
return deprecation
if deprecation is None:
return None
if not overload:
return f": {deprecation}"
return f" [overload {callable}]: {deprecation}"

def check_deprecated_function(self, typ: Type, context: Context, memberaccess: bool) -> None:
if isinstance(typ := get_proper_type(typ), (CallableType, Overloaded)):
Expand Down Expand Up @@ -7607,7 +7615,7 @@ def warn_deprecated(
else:
name = type_.fullname
warn = self.msg.fail if self.options.report_deprecated_as_error else self.msg.note
warn(f"{name} is deprecated: {deprecated}", context, code=codes.DEPRECATED)
warn(f"{name} is deprecated{deprecated}", context, code=codes.DEPRECATED)


class CollectArgTypeVarTypes(TypeTraverserVisitor):
Expand Down
8 changes: 4 additions & 4 deletions test-data/unit/check-deprecated.test
Original file line number Diff line number Diff line change
Expand Up @@ -248,10 +248,10 @@ class A:
def __iadd__(self, v: Union[int, str]) -> A: ...

a = A()
a + 1 # N: __main__.A.__add__ is deprecated: no A + int
a + 1 # N: __main__.A.__add__ is deprecated [overload def (__main__.A, builtins.int)]: no A + int
a + "x"
1 + a
"x" + a # N: __main__.A.__radd__ is deprecated: no str + A
"x" + a # N: __main__.A.__radd__ is deprecated [overload def (__main__.A, builtins.str)]: no str + A
a += 1 # N: __main__.A.__iadd__ is deprecated: no A += Any
a += "x" # N: __main__.A.__iadd__ is deprecated: no A += Any

Expand Down Expand Up @@ -370,7 +370,7 @@ def g(x: str) -> str: ...
def g(x: Union[int, str]) -> Union[int, str]: ...

g
g(1) # N: __main__.g is deprecated: work with str instead
g(1) # N: __main__.g is deprecated [overload def (x: builtins.int) -> builtins.int]: work with str instead
g("x")
g(1.0) # E: No overload variant of "g" matches argument type "float" \
# N: Possible overload variants: \
Expand All @@ -386,7 +386,7 @@ def h(x: Union[int, str]) -> Union[int, str]: ...

h
h(1)
h("x") # N: __main__.h is deprecated: work with int instead
h("x") # N: __main__.h is deprecated [overload def (x: builtins.str) -> builtins.str]: work with int instead
h(1.0) # E: No overload variant of "h" matches argument type "float" \
# N: Possible overload variants: \
# N: def h(x: int) -> int \
Expand Down

0 comments on commit b0ced07

Please sign in to comment.