Skip to content

Commit eeacb3e

Browse files
fix _PyType_LookupByVersion for types with pre-defined version tags
1 parent 8e1469c commit eeacb3e

File tree

2 files changed

+43
-0
lines changed

2 files changed

+43
-0
lines changed

Lib/test/test_capi/test_opt.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3017,6 +3017,20 @@ def f(n):
30173017
self.assertNotIn("_LOAD_ATTR_METHOD_NO_DICT", uops)
30183018
self.assertNotIn("_LOAD_ATTR_METHOD_LAZY_DICT", uops)
30193019

3020+
def test_cached_attributes_fixed_version_tag(self):
3021+
def f(n):
3022+
c = 1
3023+
x = 0
3024+
for _ in range(n):
3025+
x += c.bit_length()
3026+
return x
3027+
3028+
res, ex = self._run_with_optimizer(f, TIER2_THRESHOLD)
3029+
self.assertIsNotNone(ex)
3030+
self.assertEqual(res, TIER2_THRESHOLD)
3031+
uops = get_opnames(ex)
3032+
self.assertNotIn("_LOAD_ATTR_METHOD_NO_DICT", uops)
3033+
30203034
def test_store_fast_refcount_elimination(self):
30213035
def foo(x):
30223036
# Since x is known to be

Objects/typeobject.c

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1349,6 +1349,35 @@ _PyType_LookupByVersion(unsigned int version)
13491349
#ifdef Py_GIL_DISABLED
13501350
return NULL;
13511351
#else
1352+
switch (version) {
1353+
case _Py_TYPE_VERSION_INT:
1354+
return &PyLong_Type;
1355+
case _Py_TYPE_VERSION_FLOAT:
1356+
return &PyFloat_Type;
1357+
case _Py_TYPE_VERSION_LIST:
1358+
return &PyList_Type;
1359+
case _Py_TYPE_VERSION_TUPLE:
1360+
return &PyTuple_Type;
1361+
case _Py_TYPE_VERSION_STR:
1362+
return &PyUnicode_Type;
1363+
case _Py_TYPE_VERSION_SET:
1364+
return &PySet_Type;
1365+
case _Py_TYPE_VERSION_FROZEN_SET:
1366+
return &PyFrozenSet_Type;
1367+
case _Py_TYPE_VERSION_DICT:
1368+
return &PyDict_Type;
1369+
case _Py_TYPE_VERSION_BYTEARRAY:
1370+
return &PyByteArray_Type;
1371+
case _Py_TYPE_VERSION_BYTES:
1372+
return &PyBytes_Type;
1373+
case _Py_TYPE_VERSION_COMPLEX:
1374+
return &PyComplex_Type;
1375+
case _Py_TYPE_VERSION_FROZENDICT:
1376+
return &PyFrozenDict_Type;
1377+
default:
1378+
break;
1379+
}
1380+
13521381
PyInterpreterState *interp = _PyInterpreterState_GET();
13531382
PyTypeObject **slot =
13541383
interp->types.type_version_cache

0 commit comments

Comments
 (0)