Skip to content

Commit 3fbe18b

Browse files
committed
Remove TYPE_CHANGED
Always use the type version from the __getattribute__ lookup (even if its zero). The guard will fail if the type changes afterwards.
1 parent 1398699 commit 3fbe18b

File tree

1 file changed

+7
-29
lines changed

1 file changed

+7
-29
lines changed

Python/specialize.c

Lines changed: 7 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -548,7 +548,6 @@ _PyCode_Quicken(_Py_CODEUNIT *instructions, Py_ssize_t size, PyObject *consts,
548548
#define SPEC_FAIL_ATTR_METACLASS_OVERRIDDEN 34
549549
#define SPEC_FAIL_ATTR_SPLIT_DICT 35
550550
#define SPEC_FAIL_ATTR_DESCR_NOT_DEFERRED 36
551-
#define SPEC_FAIL_ATTR_TYPE_CHANGED 37
552551

553552
/* Binary subscr and store subscr */
554553

@@ -837,7 +836,6 @@ typedef enum {
837836
DUNDER_CLASS, /* __class__ attribute */
838837
GETSET_OVERRIDDEN, /* __getattribute__ or __setattr__ has been overridden */
839838
GETATTRIBUTE_IS_PYTHON_FUNCTION, /* Descriptor requires calling a Python __getattribute__ */
840-
TYPE_CHANGED, /* Error: the type changed during classification */
841839
} DescriptorClassification;
842840

843841

@@ -887,8 +885,8 @@ static DescriptorClassification
887885
analyze_descriptor(PyTypeObject *type, PyObject *name, PyObject **descr, unsigned int *tp_version, int store)
888886
{
889887
bool has_getattr = false;
890-
bool have_getattribute_ver = false;
891-
unsigned int getattribute_ver;
888+
bool have_ga_version = false;
889+
unsigned int ga_version;
892890
if (store) {
893891
if (type->tp_setattro != PyObject_GenericSetAttr) {
894892
*descr = NULL;
@@ -906,26 +904,20 @@ analyze_descriptor(PyTypeObject *type, PyObject *name, PyObject **descr, unsigne
906904
/* One or both of __getattribute__ or __getattr__ may have been
907905
overridden See typeobject.c for why these functions are special. */
908906
PyObject *getattribute = _PyType_LookupRefAndVersion(type,
909-
&_Py_ID(__getattribute__), &getattribute_ver);
910-
have_getattribute_ver = true;
907+
&_Py_ID(__getattribute__), &ga_version);
908+
have_ga_version = true;
911909
PyInterpreterState *interp = _PyInterpreterState_GET();
912910
bool has_custom_getattribute = getattribute != NULL &&
913911
getattribute != interp->callable_cache.object__getattribute__;
914-
unsigned int getattr_ver;
915-
PyObject *getattr = _PyType_LookupRefAndVersion(type, &_Py_ID(__getattr__), &getattr_ver);
912+
PyObject *getattr = _PyType_LookupRef(type, &_Py_ID(__getattr__));
916913
has_getattr = getattr != NULL;
917-
if (getattr_ver != getattribute_ver) {
918-
Py_XDECREF(getattribute);
919-
Py_XDECREF(getattr);
920-
return TYPE_CHANGED;
921-
}
922914
if (has_custom_getattribute) {
923915
if (getattro_slot == _Py_slot_tp_getattro &&
924916
!has_getattr &&
925917
Py_IS_TYPE(getattribute, &PyFunction_Type)) {
926918
*descr = getattribute;
927919
assert(getattr == NULL);
928-
*tp_version = getattribute_ver;
920+
*tp_version = ga_version;
929921
return GETATTRIBUTE_IS_PYTHON_FUNCTION;
930922
}
931923
/* Potentially both __getattr__ and __getattribute__ are set.
@@ -952,12 +944,8 @@ analyze_descriptor(PyTypeObject *type, PyObject *name, PyObject **descr, unsigne
952944
}
953945
unsigned int descr_version;
954946
PyObject *descriptor = _PyType_LookupRefAndVersion(type, name, &descr_version);
955-
if (have_getattribute_ver && (descr_version != getattribute_ver)) {
956-
Py_XDECREF(descriptor);
957-
return TYPE_CHANGED;
958-
}
959947
*descr = descriptor;
960-
*tp_version = descr_version;
948+
*tp_version = have_ga_version ? ga_version : descr_version;
961949
if (PyUnicode_CompareWithASCIIString(name, "__class__") == 0) {
962950
if (descriptor == _PyType_Lookup(&PyBaseObject_Type, name)) {
963951
return DUNDER_CLASS;
@@ -1124,9 +1112,6 @@ do_specialize_instance_load_attr(PyObject* owner, _Py_CODEUNIT* instr, PyObject*
11241112
return -1;
11251113
}
11261114
switch(kind) {
1127-
case TYPE_CHANGED:
1128-
SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_ATTR_TYPE_CHANGED);
1129-
return -1;
11301115
case OVERRIDING:
11311116
SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_ATTR_OVERRIDING_DESCRIPTOR);
11321117
return -1;
@@ -1370,9 +1355,6 @@ _Py_Specialize_StoreAttr(_PyStackRef owner_st, _Py_CODEUNIT *instr, PyObject *na
13701355
goto fail;
13711356
}
13721357
switch(kind) {
1373-
case TYPE_CHANGED:
1374-
SPECIALIZATION_FAIL(STORE_ATTR, SPEC_FAIL_ATTR_TYPE_CHANGED);
1375-
goto fail;
13761358
case OVERRIDING:
13771359
SPECIALIZATION_FAIL(STORE_ATTR, SPEC_FAIL_ATTR_OVERRIDING_DESCRIPTOR);
13781360
goto fail;
@@ -1533,10 +1515,6 @@ specialize_class_load_attr(PyObject *owner, _Py_CODEUNIT *instr,
15331515
}
15341516
}
15351517
switch (kind) {
1536-
case TYPE_CHANGED:
1537-
SPECIALIZATION_FAIL(STORE_ATTR, SPEC_FAIL_ATTR_TYPE_CHANGED);
1538-
Py_XDECREF(descr);
1539-
return -1;
15401518
case METHOD:
15411519
case NON_DESCRIPTOR:
15421520
#ifdef Py_GIL_DISABLED

0 commit comments

Comments
 (0)