Skip to content

Commit e182161

Browse files
committed
PEP 702 (@deprecated): consider type hints in function signatures
1 parent 0c10dc3 commit e182161

File tree

2 files changed

+67
-1
lines changed

2 files changed

+67
-1
lines changed

mypy/checker.py

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -290,12 +290,17 @@ class PartialTypeScope(NamedTuple):
290290
class InstanceDeprecatedVisitor(TypeTraverserVisitor):
291291
"""Visitor that recursively checks for deprecations in nested instances."""
292292

293-
def __init__(self, typechecker: TypeChecker, context: Context) -> None:
293+
def __init__(
294+
self, typechecker: TypeChecker, context: Context, ignore: TypeInfo | None = None
295+
) -> None:
294296
self.typechecker = typechecker
295297
self.context = context
298+
self.ignore = ignore
296299

297300
def visit_instance(self, t: Instance) -> None:
298301
super().visit_instance(t)
302+
if self.ignore and (t.type.fullname == self.ignore.fullname):
303+
return
299304
self.typechecker.check_deprecated(t.type, self.context)
300305

301306

@@ -1056,6 +1061,10 @@ def visit_func_def(self, defn: FuncDef) -> None:
10561061
return
10571062
with self.tscope.function_scope(defn):
10581063
self._visit_func_def(defn)
1064+
if (typ := defn.type) is not None:
1065+
typ.accept(
1066+
InstanceDeprecatedVisitor(typechecker=self, context=defn, ignore=defn.info)
1067+
)
10591068

10601069
def _visit_func_def(self, defn: FuncDef) -> None:
10611070
"""Type check a function definition."""

test-data/unit/check-deprecated.test

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,63 @@ x13: A3[C] # N: class __main__.C is deprecated: use C2 instead
152152
[builtins fixtures/tuple.pyi]
153153

154154

155+
[case testDeprecatedInstanceInFunctionDefinition]
156+
157+
from typing import Generic, List, Optional, TypeVar
158+
from typing_extensions import deprecated
159+
160+
@deprecated("use C2 instead")
161+
class C: ...
162+
163+
def f1(c: C) -> None: # N: class __main__.C is deprecated: use C2 instead
164+
def g1() -> None: ...
165+
166+
def f2(c: List[Optional[C]]) -> None: # N: class __main__.C is deprecated: use C2 instead
167+
def g2() -> None: ...
168+
169+
def f3() -> C: # N: class __main__.C is deprecated: use C2 instead
170+
def g3() -> None: ...
171+
return C() # N: class __main__.C is deprecated: use C2 instead
172+
173+
def f4() -> List[Optional[C]]: # N: class __main__.C is deprecated: use C2 instead
174+
def g4() -> None: ...
175+
return []
176+
177+
def f5() -> None:
178+
def g5(c: C) -> None: ... # N: class __main__.C is deprecated: use C2 instead
179+
180+
def f6() -> None:
181+
def g6() -> C: ... # N: class __main__.C is deprecated: use C2 instead
182+
183+
184+
@deprecated("use D2 instead")
185+
class D:
186+
187+
def f1(self, c: C) -> None: # N: class __main__.C is deprecated: use C2 instead
188+
def g1() -> None: ...
189+
190+
def f2(self, c: List[Optional[C]]) -> None: # N: class __main__.C is deprecated: use C2 instead
191+
def g2() -> None: ...
192+
193+
def f3(self) -> None:
194+
def g3(c: C) -> None: ... # N: class __main__.C is deprecated: use C2 instead
195+
196+
def f4(self) -> None:
197+
def g4() -> C: ... # N: class __main__.C is deprecated: use C2 instead
198+
199+
T = TypeVar("T")
200+
201+
@deprecated("use E2 instead")
202+
class E(Generic[T]):
203+
204+
def f1(self: E[C]) -> None: ... # N: class __main__.C is deprecated: use C2 instead
205+
def f2(self, e: E[C]) -> None: ... # N: class __main__.C is deprecated: use C2 instead
206+
def f3(self) -> E[C]: ... # N: class __main__.C is deprecated: use C2 instead
207+
208+
209+
[builtins fixtures/tuple.pyi]
210+
211+
155212
[case testDeprecatedClassDifferentModule]
156213

157214
import m

0 commit comments

Comments
 (0)