New submission from Ken Jin <[email protected]>:
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.
----------
components: Interpreter Core
messages: 399594
nosy: Mark.Shannon, kj, pablogsal, vstinner
priority: normal
severity: normal
status: open
title: tp_version_tag is not unique when test runs with -R :
versions: Python 3.11
_______________________________________
Python tracker <[email protected]>
<https://bugs.python.org/issue44914>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe:
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com