`structseq_repr` mislabels unnamed `PyStructSequence` fields (e.g. `os.stat_result` slots 7–9)
Dieses Issue hat noch niemand übernommen.
- Vorherrschende Sprache
- Python
- Sterne
- 77.2k
- Forks
- 35.9k
- PR-Merge-Kennzahlen
- PR-Kennzahlen ausstehend
Beschreibung
Bug report
Bug description:
structseq_repr() indexes tp_members by visible sequence position, but tp_members is built with every PyStructSequence_UnnamedField entry skipped (packed). As a result, every visible slot at or after the first unnamed field is labeled with the name of a later (hidden) field. For os.stat_result, the unnamed integer time slots 7–9 borrow the names of the hidden st_atime/st_mtime/st_ctime float fields.
Real-world case — a plain os.stat(). The repr prints st_atime=<integer seconds>, but the st_atime attribute is the float with sub-second precision — they are different fields:
>>> import os
>>> st = os.stat(os.curdir)
>>> st
os.stat_result(st_mode=16877, st_ino=1367263, st_dev=16777232, st_nlink=43,
st_uid=501, st_gid=20, st_size=1376,
st_atime=1784619363, st_mtime=1784619363, st_ctime=1784619363)
>>> st[7] # sequence slot 7 — the integer atime
1784619363
>>> st.st_atime # the .st_atime attribute — a different, hidden float field
1784619363.4590902
Synthetic case, isolating the mechanism with distinct values per field:
>>> # The repr always labels sequence slot 7 "st_atime", printing slot 7's value:
>>> st = os.stat_result(range(22))
>>> st
os.stat_result(st_mode=0, st_ino=1, st_dev=2, st_nlink=3, st_uid=4, st_gid=5,
st_size=6, st_atime=7, st_mtime=8, st_ctime=9)
>>> st[7]
7
>>> # But the .st_atime ATTRIBUTE is the hidden field at index 10:
>>> st.st_atime # field 10 supplied -> 10
10 # surprise! differs from the repr above
>>> os.stat_result(range(11)).st_atime # field 10 supplied -> 10
10
>>> os.stat_result(range(10)).st_atime # field 10 NOT supplied -> falls back to slot 7 -> 7
7 # surprise! # **UPDATE**: this is an intentional behavior in overrided `statresult_new`
>>> os.stat_result.n_sequence_fields, os.stat_result.n_unnamed_fields
(10, 3)
>>> os.stat_result.__match_args__ # correctly excludes the 3 unnamed slots
('st_mode', 'st_ino', 'st_dev', 'st_nlink', 'st_uid', 'st_gid', 'st_size')
The mislabel is easy to miss: when only the 10 sequence fields are supplied (range(10)), the hidden float st_atime (index 10) is unset and derives from the integer slot 7, so the repr and the attribute coincidentally agree. Supplying field 10 (range(11) or more, or a real os.stat()) makes them disagree.
CPython versions tested on:
3.14
Operating systems tested on:
macOS
Linked PRs
- gh-154434
- gh-154684
- gh-154687
Beitragsleitfaden
Erste Schritte
- Lies das ganze Issue und danach den Beitragsleitfaden des Projekts.
- Schreib ins Issue, dass du es übernimmst — das erspart doppelte Arbeit.
- Forke das Repository und arbeite in einem Branch.
- Öffne einen Pull Request, der die Issue-Nummer nennt.
Rechercherichtung
Beginne bei structseq_repr und reproduziere die Abweichung anhand der os.stat_result-Beispiele im Issue, einschließlich der übergebenen versteckten Felder. Prüfe, dass sichtbare Sequenz-Slots unabhängig von unbenannten Feldern beschriftet werden, während versteckte Attribute ihre Werte behalten, und verifiziere anschließend das Verhalten anhand der verknüpften PRs und der dokumentierten Beispiele.
Vom Indexierungsmodell aus dem Issue-Text verfasst.
Bewertung
- Tech-Stack
- python
- Bereich
- backend
- Issue-Typ
- Bug
- Schwierigkeit
- 3/5
- Geschätzter Aufwand
- 1-2 Tage
- Aktivitätsstatus
- Veraltet
- Klarheit
- Klar beschrieben
- Anfängerfreundlichkeit
- 35/100