Message399594
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. |
|
Date |
User |
Action |
Args |
2021-08-14 15:17:09 | kj | set | recipients:
+ kj, vstinner, Mark.Shannon, pablogsal |
2021-08-14 15:17:09 | kj | set | messageid: <1628954229.73.0.911721360588.issue44914@roundup.psfhosted.org> |
2021-08-14 15:17:09 | kj | link | issue44914 messages |
2021-08-14 15:17:09 | kj | create | |
|