-
-
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 |
That's a pretty awesome hack, IMO. But let's see if the maintainers agree. |
The current stub for
copy.replaceaccepts arbitrary keyword arguments. We can useParamSpecto 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.replacein the pyright playground: