Python's dataclasses module offers a replace() which allows for a theoretically safe interface to update frozen structs
import copy, dataclasses
@dataclasses.dataclass(frozen=True)
class Struc:
a: int = 3
b: str = "string"
data = Struc()
data2 = dataclasses.replace(data, a="word") # Runs, but should lint regardless
data3 = copy.replace(data, c=False) # Does not run, should lint
So while replace has a sig of **changes: Any, since we know in practice that it will TypeError if the wrong data is provided, to me it makes sense to have static checks for the args of replace against the field of the object provided, similar to standard assignment. The same could likely be applied to 3.13's copy.replace.
The reason I think this function in particular is suited to pyright unlike setattr or similar is that replace isn't intended for runtime reflection but rather a means for working with immutable classes.
Python's
dataclassesmodule offers areplace()which allows for a theoretically safe interface to update frozen structsSo while replace has a sig of
**changes: Any, since we know in practice that it willTypeErrorif the wrong data is provided, to me it makes sense to have static checks for the args ofreplaceagainst the field of the object provided, similar to standard assignment. The same could likely be applied to 3.13'scopy.replace.The reason I think this function in particular is suited to pyright unlike
setattror similar is thatreplaceisn't intended for runtime reflection but rather a means for working with immutable classes.