Add Python < 3.3 support for pyabc.i

pyabc.i for abstract base classes now supports versions of Python
prior to 3.3 by using the collection module for these older versions.
Python-3.3 and later continue to use the collections.abc module.
The -py3 option no longer has any effect on the %pythonabc feature.
This commit is contained in:
William S Fulton 2022-03-21 23:56:54 +00:00
parent 9fd2356104
commit f068f2c2d6
6 changed files with 51 additions and 36 deletions

View File

@ -7,6 +7,12 @@ the issue number to the end of the URL: https://github.com/swig/swig/issues/
Version 4.1.0 (in progress)
===========================
2022-03-21: wsfulton
[Python] #1779 pyabc.i for abstract base classes now supports versions of
Python prior to 3.3 by using the collection module for these older versions.
Python-3.3 and later continue to use the collections.abc module.
The -py3 option no longer has any effect on the %pythonabc feature.
2022-03-21: jschueller, jim-easterbrook, wsfulton
[Python] #2137 C++ static member functions no longer generate a "flattened"
name in the Python module. For example:

View File

@ -7036,10 +7036,11 @@ modify the buffer.
<p>
By including <tt>pyabc.i</tt> and using the <tt>-py3</tt> command
line option when calling SWIG, the proxy classes of the STL containers
By including <tt>pyabc.i</tt> in your interface file,
the proxy classes of the STL containers
will automatically gain an appropriate abstract base class from the
<tt>collections.abc</tt> module. For
<tt>collections.abc</tt> module for Python 3.3 and later, otherwise from the
<tt>collections</tt> module. For
example, the following SWIG interface:
</p>
@ -7056,8 +7057,10 @@ namespace std {
<p>
will generate a Python proxy class <tt>Mapii</tt> inheriting from
<tt>collections.abc.MutableMap</tt> and a proxy class <tt>IntList</tt>
inheriting from <tt>collections.abc.MutableSequence</tt>.
<tt>collections.abc.MutableMap</tt> for Python 3.3 and later, or <tt>collections.MutableMap</tt>
for earlier versions and a proxy class <tt>IntList</tt>
inheriting from <tt>collections.abc.MutableSequence</tt> for Python 3.3 or later,
or <tt>collections.MutableSequence</tt> for earlier versions.
</p>
<p>
@ -7066,7 +7069,9 @@ used to define an abstract base class for your own C++ class:
</p>
<div class="code"><pre>
%pythonabc(MySet, collections.abc.MutableSet);
%pythonabc(MySet, collections.abc.MutableSet); # Python 3.3 and later
%pythonabc(MySet, collections.MutableSet); # Prior to Python 3.3
%pythonabc(MySet, "collections.abc.MutableSet if _swig_python_version_info &gt;= (3, 3) else collections.MutableSet"); # All Python versions
</pre></div>
<p>
@ -7080,6 +7085,8 @@ For details of abstract base class, please see
of the classes in the <tt>collections</tt> module in Python 3.7.
The <tt>collections.abc</tt> module was introduced in Python 3.3 and hence this feature
requires Python 3.3 or later.
SWIG-4.1.0 introduced the flexibility of using
either the <tt>collections.abc</tt> module for Python 3.3 and later or the <tt>collections</tt> module for earlier Python versions.
</p>
<H3><a name="Python_nn77">33.12.4 Byte string output conversion</a></H3>

View File

@ -1,31 +1,36 @@
import sys
# collections.abc requires Python 3.3+
if sys.version_info[0:2] < (3, 3):
exit(0)
from python_abstractbase import *
import collections.abc
if sys.version_info[0:2] >= (3, 3):
import collections.abc
else:
import collections
# This is expected to fail with -builtin option
# Builtin types can't inherit from pure-python abstract bases
if is_python_builtin():
exit(0)
# Python abc is only turned on when -py3 option is passed to SWIG
if not is_swig_py3:
exit(0)
def check_issubclass(derived, base):
if not issubclass(derived, base):
raise RuntimeError("{} is not a subclass of {}".format(derived, base))
check_issubclass(Mapii, collections.abc.MutableMapping)
check_issubclass(Multimapii, collections.abc.MutableMapping)
check_issubclass(IntSet, collections.abc.MutableSet)
check_issubclass(IntMultiset, collections.abc.MutableSet)
check_issubclass(IntVector, collections.abc.MutableSequence)
check_issubclass(IntList, collections.abc.MutableSequence)
if sys.version_info[0:2] >= (3, 3):
check_issubclass(Mapii, collections.abc.MutableMapping)
check_issubclass(Multimapii, collections.abc.MutableMapping)
check_issubclass(IntSet, collections.abc.MutableSet)
check_issubclass(IntMultiset, collections.abc.MutableSet)
check_issubclass(IntVector, collections.abc.MutableSequence)
check_issubclass(IntList, collections.abc.MutableSequence)
else:
check_issubclass(Mapii, collections.MutableMapping)
check_issubclass(Multimapii, collections.MutableMapping)
check_issubclass(IntSet, collections.MutableSet)
check_issubclass(IntMultiset, collections.MutableSet)
check_issubclass(IntVector, collections.MutableSequence)
check_issubclass(IntList, collections.MutableSequence)
mapii = Mapii()
multimapii = Multimapii()

View File

@ -24,9 +24,3 @@ bool is_python_builtin() { return true; }
bool is_python_builtin() { return false; }
#endif
%}
#ifdef SWIGPYTHON_PY3 // set when using -py3
#define is_swig_py3 1
#else
#define is_swig_py3 0
#endif

View File

@ -1,10 +1,14 @@
%define %pythonabc(Type, Abc)
%feature("python:abc", #Abc) Type;
%feature("python:abc", Abc) Type;
%enddef
%pythoncode %{import collections.abc%}
%pythonabc(std::vector, collections.abc.MutableSequence);
%pythonabc(std::list, collections.abc.MutableSequence);
%pythonabc(std::map, collections.abc.MutableMapping);
%pythonabc(std::multimap, collections.abc.MutableMapping);
%pythonabc(std::set, collections.abc.MutableSet);
%pythonabc(std::multiset, collections.abc.MutableSet);
%pythoncode %{if _swig_python_version_info[0:2] >= (3, 3):
import collections.abc
else:
import collections
%}
%pythonabc(std::vector, "collections.abc.MutableSequence if _swig_python_version_info >= (3, 3) else collections.MutableSequence");
%pythonabc(std::list, "collections.abc.MutableSequence if _swig_python_version_info >= (3, 3) else collections.MutableSequence");
%pythonabc(std::map, "collections.abc.MutableMapping if _swig_python_version_info >= (3, 3) else collections.MutableMapping");
%pythonabc(std::multimap, "collections.abc.MutableMapping if _swig_python_version_info >= (3, 3) else collections.MutableMapping");
%pythonabc(std::set, "collections.abc.MutableSet if _swig_python_version_info >= (3, 3) else collections.MutableSet");
%pythonabc(std::multiset, "collections.abc.MutableSet if _swig_python_version_info >= (3, 3) else collections.MutableSet");

View File

@ -4480,10 +4480,9 @@ public:
/* dealing with abstract base class */
String *abcs = Getattr(n, "feature:python:abc");
if (py3 && abcs) {
if (Len(base_class)) {
if (abcs) {
if (Len(base_class) > 0)
Printv(base_class, ", ", NIL);
}
Printv(base_class, abcs, NIL);
}