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 kj
Recipients Mark.Shannon, kj, pablogsal, vstinner
Date 2021-08-14.15:17:09
SpamBayes Score -1.0
Marked as misclassified Yes
Message-id <1628954229.73.0.911721360588.issue44914@roundup.psfhosted.org>
In-reply-to
Content
tp_version_tag is supposed to be unique for different class objects. Under normal circumstances, everything works properly:

def good():
    class C:
        def __init__(self):  # Just to force `tp_version_tag` to update
            pass
    cls_id = hex(id(C))
    tp_version_tag_before = C.v   # v is tp_version_tag of C, exposed to Python
    x = C()                       # tp_new requires a _PyType_Lookup for `__init__`, updating `tp_version_tag`
    tp_version_tag_after = C.v
    print(f'C ID: {cls_id}, before: {tp_version_tag_before} after: {tp_version_tag_after}')

for _ in range(100):
    good()

Result:
C ID: 0x2920c2d58d0, before: 0 after: 115
C ID: 0x2920c2d6170, before: 0 after: 116
C ID: 0x2920c2d65c0, before: 0 after: 117
C ID: 0x2920c8f2800, before: 0 after: 118
C ID: 0x2920c8f7150, before: 0 after: 119
C ID: 0x2920c8f6010, before: 0 after: 120
C ID: 0x2920c8f6460, before: 0 after: 121
C ID: 0x2920c8f3d90, before: 0 after: 122
C ID: 0x2920c8f0e20, before: 0 after: 123
C ID: 0x2920c8f41e0, before: 0 after: 124
C ID: 0x2920c8f4a80, before: 0 after: 125
C ID: 0x2920c8f1270, before: 0 after: 126
C ID: 0x2920c8f16c0, before: 0 after: 127
C ID: 0x2920c8f34f0, before: 0 after: 128
C ID: 0x2920c8f5770, before: 0 after: 129
C ID: 0x2920c8f30a0, before: 0 after: 130
...

However, wrapping in a unittest and run under -R : suddenly changes things:

class BadTest(unittest.TestCase):
    def test_bad(self):
        class C:
            def __init__(self):
                pass

        cls_id = hex(id(C))
        tp_version_tag_before = C.v
        x = C()
        tp_version_tag_after = C.v
        print(f'C ID: {cls_id}, before: {tp_version_tag_before} after: {tp_version_tag_after}')

Result:
"python_d.exe" -m test test_bad -R 10:10
C ID: 0x1c4c59354b0, before: 0 after: 78
.C ID: 0x1c4c59372e0, before: 0 after: 82
.C ID: 0x1c4c5934370, before: 0 after: 82
.C ID: 0x1c4c5934370, before: 0 after: 82
.C ID: 0x1c4c5933680, before: 0 after: 82
.C ID: 0x1c4c5938cc0, before: 0 after: 82
.C ID: 0x1c4c59354b0, before: 0 after: 82
.C ID: 0x1c4c5935900, before: 0 after: 82
.C ID: 0x1c4c5933680, before: 0 after: 82
.C ID: 0x1c4c59354b0, before: 0 after: 82
.C ID: 0x1c4c59354b0, before: 0 after: 82
.C ID: 0x1c4c59361a0, before: 0 after: 82
.C ID: 0x1c4c5933680, before: 0 after: 82
.C ID: 0x1c4c5931400, before: 0 after: 82
.C ID: 0x1c4c5938cc0, before: 0 after: 82
.C ID: 0x1c4c5938cc0, before: 0 after: 82
.C ID: 0x1c4c5933680, before: 0 after: 82
.C ID: 0x1c4c5936a40, before: 0 after: 82
.C ID: 0x1c4c5931400, before: 0 after: 82
.C ID: 0x1c4c5935900, before: 0 after: 82

Somehow the class is occasionally occupying the same address, and tp_version_tag didn't update properly. tp_version_tag being unique is an important invariant required for LOAD_ATTR and LOAD_METHOD specialization. I bumped into this problem after LOAD_METHOD specialization kept failing magically in test_descr.

I think this is related to issue43636 and issue43452, but I ran out of time to bisect after spending a day chasing this down. I'll try to bisect soon.
History
Date User Action Args
2021-08-14 15:17:09kjsetrecipients: + kj, vstinner, Mark.Shannon, pablogsal
2021-08-14 15:17:09kjsetmessageid: <1628954229.73.0.911721360588.issue44914@roundup.psfhosted.org>
2021-08-14 15:17:09kjlinkissue44914 messages
2021-08-14 15:17:09kjcreate