Remove the Python 2 C API compatibility macros from pyhead.swg (PyClass_Check,
PyInt_*, PyString_*, Py_TPFLAGS_HAVE_CLASS, _PyLong_FromSsize_t) and the SWIG
string helper macros SWIG_Python_str_FromFormat and SWIG_Python_str_FromChar.
These mapped Python 2 names onto the Python 3 C API and were kept only for user
typemaps, which should now call the Python 3 C API directly.
SWIG_Python_str_FromChar was still used internally, so its call sites now use
PyUnicode_FromString directly.
Also remove the dead SWIG_PYTHON_SLOW_GETSET_THIS "fast getset" code in
pyrun.swg. That macro was unconditionally defined for Python 3, so the guarded
Python 2 paths (using PyInstance_Check) were never compiled; only the slow
getset path is kept.
Update the python_annotations_typing test typemap, which used PyString_Check
and PyString_AsString, to use PyBytes_Check and PyBytes_AsString.
Assisted-by: Claude Code (Opus 4.8)
Follow-up work on top of the initial Python 2.x removal: it finishes the
removal and fixes several issues found while reviewing the change.
Correctness fixes:
- pyrun.swg: SwigPyPacked_str passed the type name straight to
PyUnicode_FromFormat as its format string, so a type name containing a
'%' would be misinterpreted. Use PyUnicode_FromString instead.
- Doc/Manual/Varargs.html: the (...) varargs freearg typemap example lost
its free() loop when the surrounding Python 2 guard was removed, leaking
the memory the in typemap allocates. Restore the loop, now unconditional.
- Doc/Manual/Typemaps.html: the PyInt_Check to PyLong_Check substitution
left two typecheck excerpts reading PyLong_Check || PyLong_Check; collapse
each back to a single check.
Code generator (Source/Modules/python.cxx):
- Emit the native class X(..., metaclass=_SwigNonDynamicMeta) form for
nondynamic classes in all three base-list branches (object, Exception and
explicit bases), and drop the Python 2 _swig_add_metaclass helper.
- Emit a plain import builtins as __builtin__ instead of the Python 2
try/except import fallback.
- Update a stale Python 2.x comment.
Remove the deprecated embed.i library (it only ever worked with Python 2):
- Delete Lib/python/embed.i and the Lib/python/Makefile.in reference to it.
- Remove the python_static and python_static_cpp targets from
Examples/Makefile.in and the now-orphaned static: targets that used them
from the Examples/python example Makefiles.
- Remove the embed.i section from the manual.
Python test suite (Examples/test-suite/python):
- profiletest_runme.py: convert the Python 2 print statements to print().
- doxygen_constructors_runme.py: drop the dead sys.version_info < (3, 0)
branch, keeping the Python 3 super().__init__() form.
- li_cdata_bytes_runme.py and li_cdata_bytes_cpp_runme.py: drop the dead
exit-on-Python-2 version guard.
- file_test_runme.py and python_abstractbase_runme.py: drop the now-unused
import sys left behind by guard removal.
Documentation (Doc/Manual/Python.html):
- Drop the embed.i and SWIG_PYTHON_STRICT_UNICODE_WCHAR sections; the latter
macro was Python 2 only and no longer exists, wide strings are unicode-only
by default.
- De-duplicate the %pythonabc example and drop a stale collections.abc
compatibility note.
- Update the version support statement and other stale Python 2 mentions.
Other cleanups:
- Tools/mkdist.py: raise the minimum Python version check to Python 3.
- Reword stale Python 2 comments in pyrun.swg, pyiterators.swg and
pycontainer.swg, and fix a PyString_FromFormat left in a pyclasses.swg
doc comment.
- CHANGES.current: record that Python 2 support has been dropped.
Assisted-by: Claude Code (Opus 4.8)
Python error instead of abort due to assert failure in python-3.8 and
earlier versions which fail using -builtin.
For li_std_vector_back_reference testcase when defining SWIG_HEAPTYPES.
Removes SwigPySequence_Cont and support classes:
SwigPySequence_ArrowProxy, SwigPySequence_Cont, SwigPySequence_Ref
The recently added Iterator Protocol support should cover the Sequence
Protocol usage for converting from Python containers to STL containers.
Newer clang versions emit warnings in generated code:
```
warning: 'sprintf' is deprecated: This function is provided for compatibility reasons only. Due to security concerns inherent in the design of sprintf(3), it is highly recommended that you use snprintf(3) instead. [-Wdeprecated-declarations]
```
Give reference in container_owner a more unique name (back_reference).
Change back-reference 'ret' typemap to have a function name so that they
are less unwittingly be used elsewhere where not intended.
Note that they can be overridden by users if needed using:
%extend std::vector {
%typemap(ret)
value_type const& __getitem__,
value_type const& front,
value_type const& back
{ ... }
}
These override the SWIG supplied versions because the SWIG supplied
typemaps use non-const value_type&, but the methods use const, so the
above have a higher precedence in the typemap search algorithm.
Use a struct with specialization to dispatch the container
owner reference function instead of a function. Avoids
possible future problems if overloading were introduced.
* tamuratak-fix_python_unordered_2:
[python] add %swig_sequence_iterator_with_making_function and make %swig_sequence_iterator forward to it. add %swig_sequence_forward_iterator too.
[python] make SwigPyIteratorClosed_T and SwigPyIteratorOpen_T inherit from forward iterator classes.
[python] fix std unordered containers
This fragment needs to depend on StdTraits fragment as it specializes the
template struct traits<> defined there and it could happen that the struct was
not declared before being specialized, resulting in compilation errors in the
generated code.
It doesn't seem to need to depend on stddef.h inclusion, however, so replace
it with the correct dependency instead of keeping both.
"CID 11151 (#3-1 of 3): Using invalid iterator (INVALIDATE_ITERATOR)18.
increment_iterator: Incrementing iterator it though it is already past
the end of its container."
Coverity does not understand 'replace_count', so warns that we may go
past self->end() (or self->rend() I guess).
The vector of pointers (just fixed) were not working correctly because the
descriptors returned from swig::type_info() were sometimes returning
zero. Zero should only be used for void * as the subsequent call to
SWIG_ConvertPtr will blindly cast the pointer without checking
descriptor.
std::vector<void *> does not work and will require further changes:
specializing traits_info<void *> to return 0 and traits_asptr<void *>.
I tried this and traits_asptr<void> also needs to be added in which
seems odd and requires further investigation...
Lib/python/pystdcommon.swg:
template <> struct traits_info<void *> {
static swig_type_info *type_info() {
static swig_type_info *info = 0;
}
};
Lib/std/std_common.i:
template <>
struct traits_asptr<void *> {
static int asptr(PyObject *obj, void ***val) {
void **p;
swig_type_info *descriptor = 0;
int res = SWIG_ConvertPtr(obj, (void **)&p, descriptor, 0);
if (SWIG_IsOK(res)) {
if (val) *val = p;
}
return res;
}
};
// this is needed, but am not sure this is expected
template <>
struct traits_asptr<void> {
static int asptr(PyObject *obj, void **val) {
void **p;
swig_type_info *descriptor = 0;
int res = SWIG_ConvertPtr(obj, (void **)&p, descriptor, 0);
if (SWIG_IsOK(res)) {
if (val) *val = p;
}
return res;
}
};
These work much like any of the other STL containers except Python slicing
is somewhat limited because the array is a fixed size. Only slices of
the full size are supported.