-
-
Notifications
You must be signed in to change notification settings - Fork 1.9k
Make copy.replace
more strongly typed
#14819
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
base: main
Are you sure you want to change the base?
Make copy.replace
more strongly typed
#14819
Conversation
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
1 similar comment
According to mypy_primer, this change has no effect on the checked open source code. 🤖🎉 |
LSP-wise, a |
@jorenham Yes, unfortunately there's a tradeoff here
Pyright currently synthesizes a Another consideration: if you call @dataclass
class Fruit:
name: str
apple = Fruit("apple")
banana = copy.replace(apple, name=None) it's not going to complain. So accepting positional arguments while catching kwargs with incorrect types can find bugs that don't cause an immediate runtime error. I'm not sure if a good survey can be taken since |
Hack suggestion: add an optional positional argument with an unsatisfiable type. def replace(
obj: _SupportsReplace[_P, _RT_co],
_hack: Never = ..., # HACK: disallow positional arguments
/, *_: _P.args, **changes: _P.kwargs,
) -> _RT_co: ... With this change, calling Downsides: the error and the signature will have a confusing |
The current stub for
copy.replace
accepts arbitrary keyword arguments. We can useParamSpec
to link the signature ofobj.__replace__
to the supplied keyword arguments.This allows passing positional arguments to
copy.replace
, but I think it's fine, given that__replace__
isn't supposed to contain positional arguments in the signature anyway (docs forobject.__replace__
)Demo of the proposed stub for
copy.replace
in the pyright playground: