Skip to content

Commit 42df023

Browse files
Make copy.replace more strongly typed
1 parent 6547ec1 commit 42df023

File tree

1 file changed

+10
-4
lines changed

1 file changed

+10
-4
lines changed

stdlib/copy.pyi

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,17 @@
11
import sys
22
from typing import Any, Protocol, TypeVar, type_check_only
3+
from typing_extensions import ParamSpec
34

45
__all__ = ["Error", "copy", "deepcopy"]
56

67
_T = TypeVar("_T")
78
_RT_co = TypeVar("_RT_co", covariant=True)
9+
_P = ParamSpec("_P")
810

911
@type_check_only
10-
class _SupportsReplace(Protocol[_RT_co]):
12+
class _SupportsReplace(Protocol[_P, _RT_co]):
1113
# In reality doesn't support args, but there's no great way to express this.
12-
def __replace__(self, /, *_: Any, **changes: Any) -> _RT_co: ...
14+
def __replace__(self, /, *_: _P.args, **changes: _P.kwargs) -> _RT_co: ...
1315

1416
# None in CPython but non-None in Jython
1517
PyStringMap: Any
@@ -20,8 +22,12 @@ def copy(x: _T) -> _T: ...
2022

2123
if sys.version_info >= (3, 13):
2224
__all__ += ["replace"]
23-
# The types accepted by `**changes` match those of `obj.__replace__`.
24-
def replace(obj: _SupportsReplace[_RT_co], /, **changes: Any) -> _RT_co: ...
25+
26+
def replace(
27+
obj: _SupportsReplace[_P, _RT_co], /,
28+
*_: _P.args, # does not accept positional arguments at runtime
29+
**changes: _P.kwargs,
30+
) -> _RT_co: ...
2531

2632
class Error(Exception): ...
2733

0 commit comments

Comments
 (0)