Repository navigation
Conversation
…dict__ (#2003) Info listed its fields in __dict__ iteration order, which on PyPy is the attribute layout of the first instance of the class, so to_dict(), iteration, repr and str could reorder a later instance's fields. - Info.__update__ records each key in a per-instance __order__ dict as it is first set; __iter__, __len__, __str__, __repr__, items(multi=True) and to_dict read the order from there, and a repeated key anchors on the last recorded key. __copy__ copies the record; pickles carry it in the state. - __order__ joins the bookkeeping names, so a field of that name is mangled. - The multi-mapping subclasses keep their own storage and are unaffected. CPython output is unchanged; the three PyPy 8.0.1 failures now pass.
|
The order of Info and Schema's attributes are not required i think. Nothing depends on them. |
|
Understood: order isn't required, so I've stopped the order-recording work here and on #2008. I've also held this PR's review findings, the old-pickle bug among them. Before closing #2003 and #2008, I'm checking the three PyPy failures #2003 cites, one by one. |
|
Something does depend on the order: rebuilding from
Option 1 (recommended): keep #2009. |
|
Coverage: 91.54% (unit tier, Python 3.15,
Per-file detail: the |
|
Closing as superseded: per the ruling on #2003, payload lookup will go by the protocol's name instead of recording |
make pylint,make mypy,make isort)make testpasses, and a test case covers the changeWhat is the purpose of your pull request?
fix— corrects a defectDescription of your pull request and other information
Infofield order no longer depends on the interpreter's attribute layout.Before:
Inforead its order fromself.__dict__. On PyPy, an instance's attributes follow the layout of an earlier instance of the same class. That reordered__iter__,__len__,__str__,__repr__,items(multi=True)andto_dict. It also moved the anchor for a repeated key.Now:
__update__records each key the first time it is set, in a per-instance__order__, and every one of those methods reads from it.__copy__and pickling carry the record.__order__joins the reserved names, so a field with that name is renamed like the others.On CPython the recorded order always equals
__dict__order, so output is unchanged there.Tests.
test_info_field_order_2003_unit.pysimulates PyPy on CPython by reordering an instance's__dict__. It fails without the fix on CPython (8 failed) and on PyPy 8.0.1. With the fix, the three PyPy failures named in #2003 pass. Thetests/corekit, top-leveltests/protocols,tests/foundationandtests/dumpkitfiles pass on CPython.Found separately: #2008 covers
Schema, which has the same__dict__-order dependence in its display and iteration.Closes #2003