Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 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
9 changes: 8 additions & 1 deletion mypy/checker.py
Original file line number Diff line number Diff line change
Expand Up @@ -290,12 +290,17 @@ class PartialTypeScope(NamedTuple):
class InstanceDeprecatedVisitor(TypeTraverserVisitor):
"""Visitor that recursively checks for deprecations in nested instances."""

def __init__(self, typechecker: TypeChecker, context: Context) -> None:
def __init__(
self, typechecker: TypeChecker, context: Context, ignore: TypeInfo | None = None
) -> None:
self.typechecker = typechecker
self.context = context
self.ignore = ignore

def visit_instance(self, t: Instance) -> None:
super().visit_instance(t)
if self.ignore and (t.type.fullname == self.ignore.fullname):
return
self.typechecker.check_deprecated(t.type, self.context)


Expand Down Expand Up @@ -1056,6 +1061,8 @@ def visit_func_def(self, defn: FuncDef) -> None:
return
with self.tscope.function_scope(defn):
self._visit_func_def(defn)
if (typ := defn.type) is not None:
typ.accept(InstanceDeprecatedVisitor(typechecker=self, context=defn, ignore=defn.info))

def _visit_func_def(self, defn: FuncDef) -> None:
"""Type check a function definition."""
Expand Down
57 changes: 57 additions & 0 deletions test-data/unit/check-deprecated.test
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,63 @@ x13: A3[C] # N: class __main__.C is deprecated: use C2 instead
[builtins fixtures/tuple.pyi]


[case testDeprecatedInstanceInFunctionDefinition]

from typing import Generic, List, Optional, TypeVar
from typing_extensions import deprecated

@deprecated("use C2 instead")
class C: ...

def f1(c: C) -> None: # N: class __main__.C is deprecated: use C2 instead
def g1() -> None: ...

def f2(c: List[Optional[C]]) -> None: # N: class __main__.C is deprecated: use C2 instead
def g2() -> None: ...

def f3() -> C: # N: class __main__.C is deprecated: use C2 instead
def g3() -> None: ...
return C() # N: class __main__.C is deprecated: use C2 instead

def f4() -> List[Optional[C]]: # N: class __main__.C is deprecated: use C2 instead
def g4() -> None: ...
return []

def f5() -> None:
def g5(c: C) -> None: ... # N: class __main__.C is deprecated: use C2 instead

def f6() -> None:
def g6() -> C: ... # N: class __main__.C is deprecated: use C2 instead


@deprecated("use D2 instead")
class D:

def f1(self, c: C) -> None: # N: class __main__.C is deprecated: use C2 instead
def g1() -> None: ...

def f2(self, c: List[Optional[C]]) -> None: # N: class __main__.C is deprecated: use C2 instead
def g2() -> None: ...

def f3(self) -> None:
def g3(c: C) -> None: ... # N: class __main__.C is deprecated: use C2 instead

def f4(self) -> None:
def g4() -> C: ... # N: class __main__.C is deprecated: use C2 instead

T = TypeVar("T")

@deprecated("use E2 instead")
class E(Generic[T]):

def f1(self: E[C]) -> None: ... # N: class __main__.C is deprecated: use C2 instead
def f2(self, e: E[C]) -> None: ... # N: class __main__.C is deprecated: use C2 instead
def f3(self) -> E[C]: ... # N: class __main__.C is deprecated: use C2 instead


[builtins fixtures/tuple.pyi]


[case testDeprecatedClassDifferentModule]

import m
Expand Down