GH-99293: Fix stale method caches and assertion errors in SWIG-generated modules
Extension modules generated by SWIG up to version 4.1.0 clear the Py_TPFLAGS_VALID_VERSION_TAG bit from tp_flags when modifying the type, as they should, but do not update tp_version_tag as typeobject.c expects. (For example, merely one of many instances I've found: https://github.com/OSGeo/gdal/blob/6bd07b20b3e55c2fc94da611244a615a4fd2991f/swig/python/extensions/osr_wrap.cpp#L2296)
In release builds this means a potentially stale cached entry is used, and in debug builds (or release builds that happen to enable assertions, which as it turns out is actually a good idea) it triggers an assertion error.
SWIG 4.1.0 avoids this problem by using PyType_Modified(), but there are a lot of older versions of SWIG and of checked-in generated extension modules around.
- Issue: gh-99293
Copying a comment I made elsewhere:
The code will ~crash~ return incorrect cached methods and values on 3.11 when running specialised instructions. Those only use tp_version_tag as a guard and don't check Py_TPFLAGS_VALID_VERSION_TAG for speed reasons.
One fix is to add a guard to all specialised LOAD_METHOD/ATTR instructions to check for the flag (this will slow down all those instructions a little). Another fix is to ask everyone to regenerate their code with a newer SWIG for Python 3.11.0.