Skip to content

Commit 966ac8b

Browse files
committed
refactor: create the whole deprecation warning in one place
1 parent 63a725e commit 966ac8b

File tree

2 files changed

+43
-47
lines changed

2 files changed

+43
-47
lines changed

mypy/checker.py

Lines changed: 37 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -639,7 +639,7 @@ def _visit_overloaded_func_def(self, defn: OverloadedFuncDef) -> None:
639639

640640
for item in defn.items:
641641
if isinstance(item, Decorator) and isinstance(ct := item.func.type, CallableType):
642-
ct.deprecated = self.get_deprecation_warning(item.decorators, ct)
642+
ct.deprecated = self.get_deprecation_warning(ct, item.decorators)
643643

644644
if defn.is_property:
645645
# HACK: Infer the type of the property.
@@ -2422,7 +2422,7 @@ def check__exit__return_type(self, defn: FuncItem) -> None:
24222422
def visit_class_def(self, defn: ClassDef) -> None:
24232423
"""Type check a class definition."""
24242424
typ = defn.info
2425-
typ.deprecated = self.get_deprecation_warning(defn.decorators)
2425+
typ.deprecated = self.get_deprecation_warning(typ, defn.decorators)
24262426
for base in typ.mro[1:]:
24272427
if base.is_final:
24282428
self.fail(message_registry.CANNOT_INHERIT_FROM_FINAL.format(base.name), defn)
@@ -2854,12 +2854,10 @@ def check_metaclass_compatibility(self, typ: TypeInfo) -> None:
28542854
def visit_import_from(self, node: ImportFrom) -> None:
28552855
for name, _ in node.names:
28562856
if (sym := self.globals.get(name)) is not None:
2857-
if isinstance(sym.node, TypeInfo) and ((depr := sym.node.deprecated) is not None):
2858-
self.warn_deprecated(sym.node, depr, node)
2859-
elif isinstance(co := get_proper_type(sym.type), (CallableType, Overloaded)) and (
2860-
(depr := co.deprecated) is not None
2861-
):
2862-
self.warn_deprecated(co, depr, node)
2857+
if isinstance(sym.node, TypeInfo):
2858+
self.warn_deprecated(sym.node, node)
2859+
elif isinstance(co := get_proper_type(sym.type), (CallableType, Overloaded)):
2860+
self.warn_deprecated(co, node)
28632861
self.check_import(node)
28642862

28652863
def visit_import_all(self, node: ImportAll) -> None:
@@ -5029,7 +5027,7 @@ def visit_del_stmt(self, s: DelStmt) -> None:
50295027

50305028
def visit_decorator(self, e: Decorator) -> None:
50315029
if isinstance(ct := e.func.type, CallableType):
5032-
ct.deprecated = self.get_deprecation_warning(e.decorators, ct)
5030+
ct.deprecated = self.get_deprecation_warning(ct, e.decorators)
50335031
for d in e.decorators:
50345032
if isinstance(d, RefExpr):
50355033
if d.fullname == "typing.no_type_check":
@@ -7558,12 +7556,26 @@ def get_expression_type(self, node: Expression, type_context: Type | None = None
75587556
return self.expr_checker.accept(node, type_context=type_context)
75597557

75607558
def get_deprecation_warning(
7561-
self, decorators: Iterable[Expression], callable: CallableType | None = None
7559+
self, typ: CallableType | Overloaded | TypeInfo, decorators: Iterable[Expression]
75627560
) -> str | None:
7561+
7562+
name = typ.name
7563+
if isinstance(typ, CallableType):
7564+
if (defn := typ.definition) is not None:
7565+
name = defn.fullname
7566+
elif isinstance(typ, Overloaded):
7567+
if isinstance(func := typ.items[0].definition, FuncDef):
7568+
name = func.fullname
7569+
else:
7570+
name = typ.fullname
7571+
75637572
overload = False
75647573
deprecation: str | None = None
75657574
for decorator in decorators:
7566-
if isinstance(decorator, NameExpr) and (decorator.fullname in OVERLOAD_NAMES):
7575+
if (isinstance(typ, CallableType)
7576+
and isinstance(decorator, NameExpr)
7577+
and (decorator.fullname in OVERLOAD_NAMES)
7578+
):
75677579
overload = True
75687580
if deprecation is not None:
75697581
self.msg.note("@overload should be placed before @deprecated", decorator)
@@ -7576,11 +7588,12 @@ def get_deprecation_warning(
75767588
and ((value := arg.value) is not None)
75777589
):
75787590
deprecation = value
7591+
75797592
if deprecation is None:
75807593
return None
75817594
if not overload:
7582-
return f": {deprecation}"
7583-
return f" [overload {callable}]: {deprecation}"
7595+
return f"{name} is deprecated: {deprecation}"
7596+
return f"{name} is deprecated [overload {typ}]: {deprecation}"
75847597

75857598
def check_deprecated_function(self, typ: Type, context: Context, memberaccess: bool) -> None:
75867599
if isinstance(typ := get_proper_type(typ), (CallableType, Overloaded)):
@@ -7592,30 +7605,21 @@ def check_deprecated_class(self, typ: TypeInfo, context: Context, memberaccess:
75927605
def _check_deprecated(
75937606
self, typ: CallableType | Overloaded | TypeInfo, context: Context, memberaccess: bool
75947607
) -> None:
7595-
if (depr := typ.deprecated) is not None:
7596-
if memberaccess:
7597-
self.warn_deprecated(typ, depr, context)
7608+
if memberaccess:
7609+
self.warn_deprecated(typ, context)
7610+
elif typ.deprecated is not None:
7611+
for imp in self.tree.imports:
7612+
if isinstance(imp, ImportFrom) and any(typ.name == n[0] for n in imp.names):
7613+
break
75987614
else:
7599-
for imp in self.tree.imports:
7600-
if isinstance(imp, ImportFrom) and any(typ.name == n[0] for n in imp.names):
7601-
break
7602-
else:
7603-
self.warn_deprecated(typ, depr, context)
7615+
self.warn_deprecated(typ, context)
76047616

76057617
def warn_deprecated(
7606-
self, type_: CallableType | Overloaded | TypeInfo, deprecated: str, context: Context
7618+
self, typ: CallableType | Overloaded | TypeInfo, context: Context
76077619
) -> None:
7608-
name = type_.name
7609-
if isinstance(type_, CallableType):
7610-
if (defn := type_.definition) is not None:
7611-
name = defn.fullname
7612-
elif isinstance(type_, Overloaded):
7613-
if isinstance(func := type_.items[0].definition, FuncDef):
7614-
name = func.fullname
7615-
else:
7616-
name = type_.fullname
7617-
warn = self.msg.fail if self.options.report_deprecated_as_error else self.msg.note
7618-
warn(f"{name} is deprecated{deprecated}", context, code=codes.DEPRECATED)
7620+
if (deprecated := typ.deprecated) is not None:
7621+
warn = self.msg.fail if self.options.report_deprecated_as_error else self.msg.note
7622+
warn(deprecated, context, code=codes.DEPRECATED)
76197623

76207624

76217625
class CollectArgTypeVarTypes(TypeTraverserVisitor):

mypy/checkmember.py

Lines changed: 6 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -323,15 +323,11 @@ def analyze_instance_member_access(
323323
and (len(items := method.items) > 1)
324324
and isinstance(setter := items[1], Decorator)
325325
):
326-
if isinstance(co := setter.func.type, (CallableType, Overloaded)) and (
327-
(deprecated := co.deprecated) is not None
328-
):
329-
mx.chk.warn_deprecated(co, deprecated, mx.context)
326+
if isinstance(co := setter.func.type, (CallableType, Overloaded)):
327+
mx.chk.warn_deprecated(co, mx.context)
330328
return analyze_var(name, getter.var, typ, info, mx)
331-
elif isinstance(co := method.type, (CallableType, Overloaded)) and (
332-
(deprecated := co.deprecated) is not None
333-
):
334-
mx.chk.warn_deprecated(co, deprecated, mx.context)
329+
elif isinstance(co := method.type, (CallableType, Overloaded)):
330+
mx.chk.warn_deprecated(co, mx.context)
335331

336332
if mx.is_lvalue:
337333
mx.msg.cant_assign_to_method(mx.context)
@@ -787,12 +783,8 @@ def analyze_var(
787783
result = t
788784
typ = get_proper_type(typ)
789785

790-
if (
791-
var.is_property
792-
and isinstance(typ, CallableType)
793-
and ((deprecated := typ.deprecated) is not None)
794-
):
795-
mx.chk.warn_deprecated(typ, deprecated, mx.context)
786+
if var.is_property and isinstance(typ, CallableType):
787+
mx.chk.warn_deprecated(typ, mx.context)
796788

797789
call_type: ProperType | None = None
798790
if var.is_initialized_in_class and (not is_instance_var(var) or mx.is_operator):

0 commit comments

Comments
 (0)