Skip to content

Commit 0d791b2

Browse files
authored
PEP 702 (@deprecated): consider overloads in snapshot descriptions (#19613)
This change is taken from #18682. The tests are unmodified. The code is simplified [as suggested by Ivan](#18682 (comment)).
1 parent a3eb219 commit 0d791b2

File tree

2 files changed

+318
-1
lines changed

2 files changed

+318
-1
lines changed

mypy/server/astdiff.py

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -252,6 +252,15 @@ def snapshot_definition(node: SymbolNode | None, common: SymbolSnapshot) -> Symb
252252
setter_type = snapshot_optional_type(first_item.var.setter_type)
253253
is_trivial_body = impl.is_trivial_body if impl else False
254254
dataclass_transform_spec = find_dataclass_transform_spec(node)
255+
256+
deprecated: str | list[str | None] | None = None
257+
if isinstance(node, FuncDef):
258+
deprecated = node.deprecated
259+
elif isinstance(node, OverloadedFuncDef):
260+
deprecated = [node.deprecated] + [
261+
i.func.deprecated for i in node.items if isinstance(i, Decorator)
262+
]
263+
255264
return (
256265
"Func",
257266
common,
@@ -262,7 +271,7 @@ def snapshot_definition(node: SymbolNode | None, common: SymbolSnapshot) -> Symb
262271
signature,
263272
is_trivial_body,
264273
dataclass_transform_spec.serialize() if dataclass_transform_spec is not None else None,
265-
node.deprecated if isinstance(node, FuncDef) else None,
274+
deprecated,
266275
setter_type, # multi-part properties are stored as OverloadedFuncDef
267276
)
268277
elif isinstance(node, Var):

test-data/unit/fine-grained.test

Lines changed: 308 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11033,6 +11033,314 @@ b.py:1: error: class a.C is deprecated: use C2 instead
1103311033
b.py:2: error: class a.D is deprecated: use D2 instead
1103411034

1103511035

11036+
[case testDeprecatedAddKeepChangeAndRemoveOverloadedFunctionDeprecation]
11037+
# flags: --enable-error-code=deprecated
11038+
11039+
from a import f
11040+
f(1)
11041+
f("y")
11042+
import a
11043+
a.f(1)
11044+
a.f("y")
11045+
11046+
[file a.py]
11047+
from typing import overload, Union
11048+
@overload
11049+
def f(x: int) -> int: ...
11050+
@overload
11051+
def f(x: str) -> str: ...
11052+
def f(x: Union[int, str]) -> Union[int, str]: ...
11053+
11054+
[file a.py.2]
11055+
from typing import overload, Union
11056+
from typing_extensions import deprecated
11057+
@overload
11058+
def f(x: int) -> int: ...
11059+
@overload
11060+
@deprecated("pass int")
11061+
def f(x: str) -> str: ...
11062+
def f(x: Union[int, str]) -> Union[int, str]: ...
11063+
11064+
[file a.py.3]
11065+
from typing import overload, Union
11066+
from typing_extensions import deprecated
11067+
@overload
11068+
def f(x: int) -> int: ...
11069+
@overload
11070+
@deprecated("pass int")
11071+
def f(x: str) -> str: ...
11072+
def f(x: Union[int, str]) -> Union[int, str]: ...
11073+
11074+
[file a.py.4]
11075+
from typing import overload, Union
11076+
from typing_extensions import deprecated
11077+
@overload
11078+
def f(x: int) -> int: ...
11079+
@overload
11080+
@deprecated("pass int, please")
11081+
def f(x: str) -> str: ...
11082+
def f(x: Union[int, str]) -> Union[int, str]: ...
11083+
11084+
[file a.py.5]
11085+
from typing import overload, Union
11086+
@overload
11087+
def f(x: int) -> int: ...
11088+
@overload
11089+
def f(x: str) -> str: ...
11090+
def f(x: Union[int, str]) -> Union[int, str]: ...
11091+
11092+
[builtins fixtures/tuple.pyi]
11093+
[out]
11094+
==
11095+
main:5: error: overload def (x: builtins.str) -> builtins.str of function a.f is deprecated: pass int
11096+
main:8: error: overload def (x: builtins.str) -> builtins.str of function a.f is deprecated: pass int
11097+
==
11098+
main:5: error: overload def (x: builtins.str) -> builtins.str of function a.f is deprecated: pass int
11099+
main:8: error: overload def (x: builtins.str) -> builtins.str of function a.f is deprecated: pass int
11100+
==
11101+
main:5: error: overload def (x: builtins.str) -> builtins.str of function a.f is deprecated: pass int, please
11102+
main:8: error: overload def (x: builtins.str) -> builtins.str of function a.f is deprecated: pass int, please
11103+
==
11104+
11105+
11106+
[case testDeprecatedRemoveOverloadedFunctionDeprecation]
11107+
# flags: --enable-error-code=deprecated
11108+
11109+
from a import f
11110+
f(1)
11111+
f("y")
11112+
import a
11113+
a.f(1)
11114+
a.f("y")
11115+
11116+
[file a.py]
11117+
from typing import overload, Union
11118+
from typing_extensions import deprecated
11119+
@overload
11120+
def f(x: int) -> int: ...
11121+
@overload
11122+
@deprecated("pass int")
11123+
def f(x: str) -> str: ...
11124+
def f(x: Union[int, str]) -> Union[int, str]: ...
11125+
11126+
[file a.py.2]
11127+
from typing import overload, Union
11128+
@overload
11129+
def f(x: int) -> int: ...
11130+
@overload
11131+
def f(x: str) -> str: ...
11132+
def f(x: Union[int, str]) -> Union[int, str]: ...
11133+
11134+
[builtins fixtures/tuple.pyi]
11135+
[out]
11136+
main:5: error: overload def (x: builtins.str) -> builtins.str of function a.f is deprecated: pass int
11137+
main:8: error: overload def (x: builtins.str) -> builtins.str of function a.f is deprecated: pass int
11138+
==
11139+
11140+
11141+
[case testDeprecatedKeepOverloadedFunctionDeprecation]
11142+
# flags: --enable-error-code=deprecated
11143+
11144+
from a import f
11145+
f(1)
11146+
f("y")
11147+
import a
11148+
a.f(1)
11149+
a.f("y")
11150+
11151+
[file a.py]
11152+
from typing import overload, Union
11153+
from typing_extensions import deprecated
11154+
@overload
11155+
def f(x: int) -> int: ...
11156+
@overload
11157+
@deprecated("pass int")
11158+
def f(x: str) -> str: ...
11159+
def f(x: Union[int, str]) -> Union[int, str]: ...
11160+
11161+
[file a.py.2]
11162+
from typing import overload, Union
11163+
from typing_extensions import deprecated
11164+
@overload
11165+
def f(x: int) -> int: ...
11166+
@overload
11167+
@deprecated("pass int")
11168+
def f(x: str) -> str: ...
11169+
def f(x: Union[int, str]) -> Union[int, str]: ...
11170+
11171+
[builtins fixtures/tuple.pyi]
11172+
[out]
11173+
main:5: error: overload def (x: builtins.str) -> builtins.str of function a.f is deprecated: pass int
11174+
main:8: error: overload def (x: builtins.str) -> builtins.str of function a.f is deprecated: pass int
11175+
==
11176+
main:5: error: overload def (x: builtins.str) -> builtins.str of function a.f is deprecated: pass int
11177+
main:8: error: overload def (x: builtins.str) -> builtins.str of function a.f is deprecated: pass int
11178+
11179+
11180+
[case testDeprecatedAddOverloadedFunctionDeprecationIndirectImport]
11181+
# flags: --enable-error-code=deprecated
11182+
11183+
from b import f
11184+
f(1)
11185+
f("y")
11186+
import b
11187+
b.f(1)
11188+
b.f("y")
11189+
11190+
[file b.py]
11191+
from a import f
11192+
11193+
[file a.py]
11194+
from typing import overload, Union
11195+
@overload
11196+
def f(x: int) -> int: ...
11197+
@overload
11198+
def f(x: str) -> str: ...
11199+
def f(x: Union[int, str]) -> Union[int, str]: ...
11200+
11201+
[file a.py.2]
11202+
from typing import overload, Union
11203+
from typing_extensions import deprecated
11204+
@overload
11205+
def f(x: int) -> int: ...
11206+
@overload
11207+
@deprecated("pass int")
11208+
def f(x: str) -> str: ...
11209+
def f(x: Union[int, str]) -> Union[int, str]: ...
11210+
11211+
[builtins fixtures/tuple.pyi]
11212+
[out]
11213+
==
11214+
main:5: error: overload def (x: builtins.str) -> builtins.str of function a.f is deprecated: pass int
11215+
main:8: error: overload def (x: builtins.str) -> builtins.str of function a.f is deprecated: pass int
11216+
11217+
11218+
[case testDeprecatedChangeOverloadedFunctionDeprecationIndirectImport]
11219+
# flags: --enable-error-code=deprecated
11220+
11221+
from b import f
11222+
f(1)
11223+
f("y")
11224+
import b
11225+
b.f(1)
11226+
b.f("y")
11227+
11228+
[file b.py]
11229+
from a import f
11230+
11231+
[file a.py]
11232+
from typing import overload, Union
11233+
from typing_extensions import deprecated
11234+
@overload
11235+
def f(x: int) -> int: ...
11236+
@overload
11237+
@deprecated("pass int")
11238+
def f(x: str) -> str: ...
11239+
def f(x: Union[int, str]) -> Union[int, str]: ...
11240+
11241+
[file a.py.2]
11242+
from typing import overload, Union
11243+
from typing_extensions import deprecated
11244+
@overload
11245+
def f(x: int) -> int: ...
11246+
@overload
11247+
@deprecated("pass int, please")
11248+
def f(x: str) -> str: ...
11249+
def f(x: Union[int, str]) -> Union[int, str]: ...
11250+
11251+
[builtins fixtures/tuple.pyi]
11252+
[out]
11253+
main:5: error: overload def (x: builtins.str) -> builtins.str of function a.f is deprecated: pass int
11254+
main:8: error: overload def (x: builtins.str) -> builtins.str of function a.f is deprecated: pass int
11255+
==
11256+
main:5: error: overload def (x: builtins.str) -> builtins.str of function a.f is deprecated: pass int, please
11257+
main:8: error: overload def (x: builtins.str) -> builtins.str of function a.f is deprecated: pass int, please
11258+
11259+
11260+
[case testDeprecatedRemoveOverloadedFunctionDeprecationIndirectImport]
11261+
# flags: --enable-error-code=deprecated
11262+
11263+
from b import f
11264+
f(1)
11265+
f("y")
11266+
import b
11267+
b.f(1)
11268+
b.f("y")
11269+
11270+
[file b.py]
11271+
from a import f
11272+
11273+
[file a.py]
11274+
from typing import overload, Union
11275+
from typing_extensions import deprecated
11276+
@overload
11277+
def f(x: int) -> int: ...
11278+
@overload
11279+
@deprecated("pass int")
11280+
def f(x: str) -> str: ...
11281+
def f(x: Union[int, str]) -> Union[int, str]: ...
11282+
11283+
[file a.py.2]
11284+
from typing import overload, Union
11285+
@overload
11286+
def f(x: int) -> int: ...
11287+
@overload
11288+
def f(x: str) -> str: ...
11289+
def f(x: Union[int, str]) -> Union[int, str]: ...
11290+
11291+
[builtins fixtures/tuple.pyi]
11292+
[out]
11293+
main:5: error: overload def (x: builtins.str) -> builtins.str of function a.f is deprecated: pass int
11294+
main:8: error: overload def (x: builtins.str) -> builtins.str of function a.f is deprecated: pass int
11295+
==
11296+
11297+
11298+
[case testDeprecatedOverloadedFunctionAlreadyDecorated]
11299+
# flags: --enable-error-code=deprecated
11300+
11301+
from b import f
11302+
f(1)
11303+
f("y")
11304+
import b
11305+
b.f(1)
11306+
b.f("y")
11307+
11308+
[file b.py]
11309+
from a import f
11310+
11311+
[file a.py]
11312+
from typing import Callable, overload, Union
11313+
11314+
def d(t: Callable[[str], str]) -> Callable[[str], str]: ...
11315+
11316+
@overload
11317+
def f(x: int) -> int: ...
11318+
@overload
11319+
@d
11320+
def f(x: str) -> str: ...
11321+
def f(x: Union[int, str]) -> Union[int, str]: ...
11322+
11323+
[file a.py.2]
11324+
from typing import Callable, overload, Union
11325+
from typing_extensions import deprecated
11326+
11327+
def d(t: Callable[[str], str]) -> Callable[[str], str]: ...
11328+
11329+
@overload
11330+
def f(x: int) -> int: ...
11331+
@overload
11332+
@deprecated("deprecated decorated overload")
11333+
@d
11334+
def f(x: str) -> str: ...
11335+
def f(x: Union[int, str]) -> Union[int, str]: ...
11336+
11337+
[builtins fixtures/tuple.pyi]
11338+
[out]
11339+
==
11340+
main:5: error: overload def (x: builtins.str) -> builtins.str of function a.f is deprecated: deprecated decorated overload
11341+
main:8: error: overload def (x: builtins.str) -> builtins.str of function a.f is deprecated: deprecated decorated overload
11342+
11343+
1103611344
[case testDeprecatedChangeClassDeprecationIndirectImport]
1103711345
# flags: --enable-error-code=deprecated
1103811346
from b import C

0 commit comments

Comments
 (0)