You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Add support of PyStructSequence in copy.replace() #110222
PyStructSequence with unnamed fields is a special case. Currently the only such structure is os.stat_result. Accessible by name fields st_atime, st_mtime and st_ctime are float values. Corresponding unnamed fields 7-9 are integer values. It is an old trick for compatibility. __replace__() can replace named fields, but unnamed fields will keep the old value. Integer and float value will be de-synchronized, and the code that reads unnamed fields will work incorrectly.
The simplest solution is to disable __replace__() for PyStructSequence with unnamed fields. Such structures can even be deprecated, but this is a different issue.
There may be a special implementation of __replace__() for os.stat_result, which derives values for unnamed fields from corresponding values for named fields. But float value can be less precise than integer value, because it has limited precision. So it needs to take into account *_ns fields. It is separate very complex issue.
PyStructSequence with unnamed fields is a special case. Currently the only such structure is os.stat_result. Accessible by name fields st_atime, st_mtime and st_ctime are float values. Corresponding unnamed fields 7-9 are integer values. It is an old trick for compatibility. __replace__() can replace named fields, but unnamed fields will keep the old value. Integer and float value will be de-synchronized, and the code that reads unnamed fields will work incorrectly.
I can confirm this is a bug for PyStructSequence with unnamed fields if we rely on __reduce__(). But I'm not sure why pickle.loads(pickle.dumps(stat)) works fine for os.stat_result.
The simplest solution is to disable __replace__() for PyStructSequence with unnamed fields. Such structures can even be deprecated, but this is a different issue.
I agree to raise an error for this (e.g., TypeError) since os.stat_result is the only case to have unnamed fields.
There may be a special implementation of __replace__() for os.stat_result, which derives values for unnamed fields from corresponding values for named fields. But float value can be less precise than integer value, because it has limited precision. So it needs to take into account *_ns fields. It is separate very complex issue.
I think it's better to disable __replace__() for PyStructSequence with unnamed fields.
Activity
AlexWaygood commentedon Oct 2, 2023
cc. @serhiy-storchaka
XuehaiPan commentedon Oct 2, 2023
I created a PR to resolve this.
serhiy-storchaka commentedon Oct 2, 2023
PyStructSequence with unnamed fields is a special case. Currently the only such structure is
os.stat_result. Accessible by name fieldsst_atime,st_mtimeandst_ctimeare float values. Corresponding unnamed fields 7-9 are integer values. It is an old trick for compatibility.__replace__()can replace named fields, but unnamed fields will keep the old value. Integer and float value will be de-synchronized, and the code that reads unnamed fields will work incorrectly.The simplest solution is to disable
__replace__()for PyStructSequence with unnamed fields. Such structures can even be deprecated, but this is a different issue.There may be a special implementation of
__replace__()foros.stat_result, which derives values for unnamed fields from corresponding values for named fields. But float value can be less precise than integer value, because it has limited precision. So it needs to take into account*_nsfields. It is separate very complex issue.XuehaiPan commentedon Oct 2, 2023
I can confirm this is a bug for PyStructSequence with unnamed fields if we rely on
__reduce__(). But I'm not sure whypickle.loads(pickle.dumps(stat))works fine foros.stat_result.I agree to raise an error for this (e.g.,
TypeError) sinceos.stat_resultis the only case to have unnamed fields.I think it's better to disable
__replace__()for PyStructSequence with unnamed fields.gh-110222: Add support of PyStructSequence in copy.replace() (GH-110223)
pythongh-110222: Add support of PyStructSequence in copy.replace() (p…