Skip to content

PEP 702 (@deprecated): consider all possible type positions #17926

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
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
Loading