This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

Author methane
Recipients mbussonn, methane, python-dev, vstinner, xiang.zhang
Date 2016-09-12.18:03:18
SpamBayes Score -1.0
Marked as misclassified Yes
Message-id <1473703398.99.0.845418624102.issue28040@psf.upfronthosting.co.za>
In-reply-to
Content
Xiang:
Preserving insertion order in shared-key dict is possible, but it's hard.
If we allow it, we should add tons of test for shared-key dict.

I'll describe why it's harder than you think.

Current implementation allow insertion to split table only when:

    /* When insertion order is different from shared key, we can't share
     * the key anymore.  Convert this instance to combine table.
     */
    if (_PyDict_HasSplitTable(mp) &&
        ((ix >= 0 && *value_addr == NULL && mp->ma_used != ix) ||
         (ix == DKIX_EMPTY && mp->ma_used != mp->ma_keys->dk_nentries))) {
        if (insertion_resize(mp) < 0) {

`ix >= 0 && *value_addr == NULL` means it's pending slot.
`mp->ma_used == ix` ensure insertion order.  And if we allow deletion, this check will be broken.

For example:

a, b = C()
a.a, a.b, a.c = 1, 2, 3  # shared-key order
b.a, b.b, b.c = 1, 2, 3  # same order, no problem

del b.a  # mp->ma_used = 2
del b.b  # mp->ma_used = 1

b.b = 42  # It's OK because mp->ma_used == ix == 1. Keep sharing.

assert(list(b.__dict__.keys()) == ["c", "b"])  # AssertionError! Actual order is [(PENDING "a",) "b", "c"]
History
Date User Action Args
2016-09-12 18:03:19methanesetrecipients: + methane, vstinner, python-dev, xiang.zhang, mbussonn
2016-09-12 18:03:18methanesetmessageid: <1473703398.99.0.845418624102.issue28040@psf.upfronthosting.co.za>
2016-09-12 18:03:18methanelinkissue28040 messages
2016-09-12 18:03:18methanecreate