Drop support for Python classic classes

There were only needed to support Python < 2.2, and we now require at
least Python 2.6.

 Conflicts:
	.travis.yml
	Examples/test-suite/python/autodoc_runme.py
	Source/Modules/python.cxx

This is a cherry-pick and merge from patch in #1261
This commit is contained in:
Olly Betts 2018-05-19 11:47:23 +12:00 committed by William S Fulton
parent dcbccc6f6f
commit 728b8955bd
20 changed files with 96 additions and 241 deletions

View File

@ -222,11 +222,6 @@ matrix:
env: SWIGLANG=python SWIG_FEATURES=-O PY3=3 VER=3.7
sudo: required
dist: trusty
- compiler: gcc
os: linux
env: SWIGLANG=python SWIG_FEATURES=-classic
sudo: required
dist: trusty
- compiler: gcc
os: linux
env: SWIGLANG=r

View File

@ -6313,9 +6313,7 @@ SWIG is able to support Python 3.x. The wrapper code generated by
SWIG can be compiled with both Python 2.x or 3.x. Further more, by
passing the <tt>-py3</tt> command line option to SWIG, wrapper code
with some Python 3 specific features can be generated (see below
subsections for details of these features). The <tt>-py3</tt> option also
disables some incompatible features for Python 3, such as
<tt>-classic</tt>.
subsections for details of these features).
<p>
There is a list of known-to-be-broken features in Python 3:

View File

@ -59,15 +59,15 @@
*/
/*
Now, the EmptyError doesn't appear in a throw declaration, and hence
we need to 'mark' it as an exception class. In python, classes that
are used as exception are 'special', and need to be wrapped as
'classic' ones.
This is a python issue, and if you don't mark the class, you will
see 'interesting' behaviours at the python side.
Python classes that are used as exceptions need to be subclasses of the
"Exception" class, and so SWIG needs to know which wrapped classes may be
used in this way. You can explicitly tell SWIG this by using
%exceptionclass. SWIG will implicitly set this feature for classes which
appear in a throw declaration, but it's not a problem to explicitly
mark such classes as well.
This is a Python requirement - if you fail to mark such classes with
%exceptionclass you may see 'interesting' behaviour on the Python side.
*/
%exceptionclass EmptyError;
%exceptionclass FullError;

View File

@ -10,10 +10,6 @@ print " Finished importing pkg2.foo"
var2 = pkg2.foo.Pkg2_Foo()
classname = str(type(var2))
# Check for an old-style class if swig was run in -classic mode
if classname == "<type 'instance'>":
classname = str(var2.__class__)
if classname.find("pkg2.foo.Pkg2_Foo") == -1:
raise RuntimeError("failed type checking: " + classname)
print " Successfully created object pkg2.foo.Pkg2_Foo"

View File

@ -9,10 +9,6 @@ print " Finished importing pkg1.pkg2.foo"
var2 = pkg1.pkg2.foo.Pkg2_Foo()
classname = str(type(var2))
# Check for an old-style class if swig was run in -classic mode
if classname == "<type 'instance'>":
classname = str(var2.__class__)
if classname.find("pkg1.pkg2.foo.Pkg2_Foo") == -1:
raise RuntimeError("failed type checking: " + classname)
print " Successfully created object pkg1.pkg2.foo.Pkg2_Foo"

View File

@ -10,9 +10,6 @@ def check(got, expected, expected_builtin=None, skip=False):
expect = expected_builtin
comment_verifier.check(got, expect)
def is_new_style_class(cls):
return hasattr(cls, "__class__")
def is_fastproxy():
fastproxy = True
try:
@ -21,11 +18,6 @@ def is_fastproxy():
fastproxy = False
return fastproxy
if not is_new_style_class(A):
# Missing static methods make this hard to test... skip if -classic is
# used!
sys.exit(0)
if is_fastproxy():
# Detect when -fastproxy is specified and skip test as it changes the function names making it
# hard to test... skip until the number of options are reduced in SWIG-3.1 and autodoc is improved

View File

@ -2,17 +2,9 @@
from cpp_static import *
def is_new_style_class(cls):
return hasattr(cls, "__class__")
if is_new_style_class(StaticFunctionTest):
StaticFunctionTest.static_func()
StaticFunctionTest.static_func_2(1)
StaticFunctionTest.static_func_3(1, 2)
else:
StaticFunctionTest().static_func()
StaticFunctionTest().static_func_2(1)
StaticFunctionTest().static_func_3(1, 2)
if is_python_builtin():
if not StaticMemberTest.static_int == 99: raise RuntimeError("static_int not 99")

View File

@ -2,10 +2,6 @@
# the use of __main__ and the run function
def is_new_style_class(cls):
return hasattr(cls, "__class__")
def run(module_name):
default_args = __import__(module_name)
ec = default_args.EnumClass()
@ -101,10 +97,7 @@ def run(module_name):
if error:
raise RuntimeError("Foo::meth ignore is not working")
if is_new_style_class(default_args.Klass):
Klass_inc = default_args.Klass.inc
else:
Klass_inc = default_args.Klass_inc
if Klass_inc(100, default_args.Klass(22)).val != 122:
raise RuntimeError("Klass::inc failed")

View File

@ -1,10 +1,6 @@
import director_abstract
def is_new_style_class(cls):
return hasattr(cls, "__class__")
class MyFoo(director_abstract.Foo):
def __init__(self):
@ -44,20 +40,12 @@ me1 = MyExample1()
if director_abstract.Example1_get_color(me1, 1, 2, 3) != 1:
raise RuntimeError
if is_new_style_class(MyExample2):
MyExample2_static = MyExample2
else:
MyExample2_static = MyExample2(0, 0)
me2 = MyExample2(1, 2)
if MyExample2_static.get_color(me2, 1, 2, 3) != 2:
if MyExample2.get_color(me2, 1, 2, 3) != 2:
raise RuntimeError
if is_new_style_class(MyExample3):
MyExample3_static = MyExample3
else:
MyExample3_static = MyExample3()
me3 = MyExample3()
if MyExample3_static.get_color(me3, 1, 2, 3) != 3:
if MyExample3.get_color(me3, 1, 2, 3) != 3:
raise RuntimeError
error = 1

View File

@ -1,9 +1,6 @@
from global_namespace import *
def is_new_style_class(cls):
return hasattr(cls, "__class__")
k1 = Klass1()
k2 = Klass2()
k3 = Klass3()
@ -12,12 +9,8 @@ k5 = Klass5()
k6 = Klass6()
k7 = Klass7()
if is_new_style_class(KlassMethods):
KlassMethods_static = KlassMethods
else:
KlassMethods_static = KlassMethods()
KlassMethods_static.methodA(k1, k2, k3, k4, k5, k6, k7)
KlassMethods_static.methodB(k1, k2, k3, k4, k5, k6, k7)
KlassMethods.methodA(k1, k2, k3, k4, k5, k6, k7)
KlassMethods.methodB(k1, k2, k3, k4, k5, k6, k7)
k1 = getKlass1A()
k2 = getKlass2A()
@ -27,8 +20,8 @@ k5 = getKlass5A()
k6 = getKlass6A()
k7 = getKlass7A()
KlassMethods_static.methodA(k1, k2, k3, k4, k5, k6, k7)
KlassMethods_static.methodB(k1, k2, k3, k4, k5, k6, k7)
KlassMethods.methodA(k1, k2, k3, k4, k5, k6, k7)
KlassMethods.methodB(k1, k2, k3, k4, k5, k6, k7)
k1 = getKlass1B()
k2 = getKlass2B()
@ -38,21 +31,11 @@ k5 = getKlass5B()
k6 = getKlass6B()
k7 = getKlass7B()
KlassMethods_static.methodA(k1, k2, k3, k4, k5, k6, k7)
KlassMethods_static.methodB(k1, k2, k3, k4, k5, k6, k7)
KlassMethods.methodA(k1, k2, k3, k4, k5, k6, k7)
KlassMethods.methodB(k1, k2, k3, k4, k5, k6, k7)
if is_new_style_class(XYZMethods):
XYZMethods_static = XYZMethods
else:
XYZMethods_static = XYZMethods()
XYZMethods_static.methodA(
XYZ1(), XYZ2(), XYZ3(), XYZ4(), XYZ5(), XYZ6(), XYZ7())
XYZMethods_static.methodB(
XYZ1(), XYZ2(), XYZ3(), XYZ4(), XYZ5(), XYZ6(), XYZ7())
XYZMethods.methodA(XYZ1(), XYZ2(), XYZ3(), XYZ4(), XYZ5(), XYZ6(), XYZ7())
XYZMethods.methodB(XYZ1(), XYZ2(), XYZ3(), XYZ4(), XYZ5(), XYZ6(), XYZ7())
if is_new_style_class(TheEnumMethods):
TheEnumMethods_static = TheEnumMethods
else:
TheEnumMethods_static = TheEnumMethods()
TheEnumMethods_static.methodA(theenum1, theenum2, theenum3)
TheEnumMethods_static.methodA(theenum1, theenum2, theenum3)
TheEnumMethods.methodA(theenum1, theenum2, theenum3)
TheEnumMethods.methodA(theenum1, theenum2, theenum3)

View File

@ -6,9 +6,6 @@ def check(a, b):
raise RuntimeError(str(a) + " does not equal " + str(b))
def is_new_style_class(cls):
return hasattr(cls, "__class__")
#### Class ####
# No implicit conversion
@ -45,17 +42,13 @@ check(2, A_int(1.0).get())
check(3, A_int(B()).get())
check(4, A_int("hello").get())
if is_new_style_class(A_int):
A_int_static = A_int
else:
A_int_static = A_int(0)
check(1, A_int_static.sget(1))
check(2, A_int_static.sget(1.0))
check(3, A_int_static.sget(B()))
check(1, A_int.sget(1))
check(2, A_int.sget(1.0))
check(3, A_int.sget(B()))
# explicit constructor:
try:
check(4, A_int_static.sget("hello"))
check(4, A_int.sget("hello"))
raise RuntimeError
except TypeError:
pass

View File

@ -1,10 +1,6 @@
from li_boost_shared_ptr_bits import *
def is_new_style_class(cls):
return hasattr(cls, "__class__")
def check(nd):
nd.i = 200
i = nd.i
@ -35,7 +31,4 @@ if sum != 66:
raise "sum is wrong"
################################
if is_new_style_class(HiddenDestructor):
p = HiddenDestructor.create()
else:
p = HiddenDestructor_create()

View File

@ -1,9 +1,5 @@
from namespace_class import *
def is_new_style_class(cls):
return hasattr(cls, "__class__")
try:
p = Private1()
error = 1
@ -22,10 +18,7 @@ except:
if (error):
raise RuntimeError, "Private2 is private"
if is_new_style_class(EulerT3D):
EulerT3D.toFrame(1, 1, 1)
else:
EulerT3D().toFrame(1, 1, 1)
b = BooT_i()
b = BooT_H()
@ -40,7 +33,6 @@ f.moo(1)
f = FooT_H()
f.foo(Hi)
if is_new_style_class(FooT_H):
f_type = str(type(f))
if f_type.find("'namespace_class.FooT_H'") == -1:
raise RuntimeError("Incorrect type: " + f_type)

View File

@ -1,9 +1,5 @@
from overload_template_fast import *
def is_new_style_class(cls):
return hasattr(cls, "__class__")
f = foo()
a = maximum(3, 4)
@ -145,9 +141,6 @@ if (nsoverload() != 1050):
raise RuntimeError, ("nsoverload(const char *)")
if is_new_style_class(A):
A.foo(1)
else:
A_foo(1)
b = B()
b.foo(1)

View File

@ -1,19 +1,13 @@
from python_append import *
def is_new_style_class(cls):
return hasattr(cls, "__class__")
# test not relevant for -builtin
if is_python_builtin():
exit(0)
t = Test()
t.funk()
if is_new_style_class(Test):
t.static_func()
else:
Test_static_func()
if grabpath() != os.path.dirname(mypath):
raise RuntimeError("grabpath failed")

View File

@ -9,7 +9,7 @@ def check(got, expected):
raise RuntimeError("\n" + "Expected: " + str(expected_list) + "\n" + "Got : " + str(got_list))
# When getting docstrings, use inspect.getdoc(x) instead of x.__doc__ otherwise the different options
# such as -O, -builtin, -classic produce different initial indentation.
# such as -O and -builtin may produce different initial indentation.
check(inspect.getdoc(DocStrings.docstring1),
" line 1\n"

View File

@ -3,17 +3,11 @@ import python_pickle
import pickle
import sys
def is_new_style_class(cls):
return hasattr(cls, "__class__")
def check(p):
msg = p.msg
if msg != "hi there":
raise RuntimeError("Bad, got: " + msg)
if not is_new_style_class(python_pickle.PickleMe):
sys.exit(0)
python_pickle.cvar.debug = False
p = python_pickle.PickleMe("hi there")

View File

@ -6,9 +6,6 @@ def check_unorderable_types(exception):
# raise RuntimeError("A TypeError 'unorderable types' exception was expected"), None, sys.exc_info()[2]
pass # Exception message seems to vary from one version of Python to another
def is_new_style_class(cls):
return hasattr(cls, "__class__")
base1 = python_richcompare.BaseClass(1)
base2 = python_richcompare.BaseClass(2)
base3 = python_richcompare.BaseClass(3)
@ -103,8 +100,6 @@ if not (a2 <= b2):
# Check inequalities to other objects
#-------------------------------------------------------------------------------
if is_new_style_class(python_richcompare.BaseClass):
# Skip testing -classic option
if sys.version_info[0:2] < (3, 0):
if (base1 < 42):
raise RuntimeError("Comparing class to incompatible type, < returned True")

View File

@ -1,9 +1,6 @@
from smart_pointer_member import *
def is_new_style_class(cls):
return hasattr(cls, "__class__")
f = Foo()
f.y = 1
@ -24,6 +21,5 @@ if b.x != f.x:
if b.z != f.z:
raise RuntimeError
if is_new_style_class(Bar): # feature not supported in old style classes
if Foo.z == Bar.z:
raise RuntimeError

View File

@ -65,7 +65,6 @@ static String *methods;
static String *class_name;
static String *shadow_indent = 0;
static int in_class = 0;
static int classic = 0;
static int modern = 0;
static int new_repr = 1;
static int no_header_file = 0;
@ -123,7 +122,6 @@ Python Options (available with -python)\n\
-buildnone - Use Py_BuildValue(" ") to obtain Py_None (default in Windows)\n\
-builtin - Create new python built-in types, rather than proxy classes, for better performance\n\
-castmode - Enable the casting mode, which allows implicit cast between types in python\n\
-classic - Use classic classes only\n\
-classptr - Generate shadow 'ClassPtr' as in older swig versions\n\
-cppcast - Enable C++ casting operators (default) \n\
-dirvtable - Generate a pseudo virtual table for directors for faster dispatch \n\
@ -393,10 +391,8 @@ public:
SWIG_cparse_set_compact_default_args(1);
Swig_mark_arg(i);
} else if (strcmp(argv[i], "-classic") == 0) {
classic = 1;
modernargs = 0;
modern = 0;
Swig_mark_arg(i);
Printf(stderr, "*** %s is no longer supported.\n", argv[i]);
SWIG_exit(EXIT_FAILURE);
} else if (strcmp(argv[i], "-cppcast") == 0) {
cppcast = 1;
Swig_mark_arg(i);
@ -510,7 +506,6 @@ public:
proxydel = 0;
Swig_mark_arg(i);
} else if (strcmp(argv[i], "-modern") == 0) {
classic = 0;
modern = 1;
modernargs = 1;
Swig_mark_arg(i);
@ -527,7 +522,6 @@ public:
no_header_file = 1;
Swig_mark_arg(i);
} else if (strcmp(argv[i], "-O") == 0) {
classic = 0;
modern = 1;
safecstrings = 0;
buildnone = 0;
@ -562,11 +556,6 @@ public:
}
}
if (py3) {
/* force disable features that not compatible with Python 3.x */
classic = 0;
}
if (cppcast) {
Preprocessor_define((DOH *) "SWIG_CPLUSPLUS_CAST", 0);
}
@ -745,10 +734,6 @@ public:
Printf(f_runtime, "#define SWIG_PYTHON_EXTRA_NATIVE_CONTAINERS\n");
}
if (classic) {
Printf(f_runtime, "#define SWIG_PYTHON_CLASSIC\n");
}
if (builtin) {
Printf(f_runtime, "#define SWIGPYTHON_BUILTIN\n");
}
@ -911,14 +896,12 @@ public:
tab4, "if not static:\n",
#endif
NIL);
if (!classic) {
if (!modern)
Printv(f_shadow, tab4, tab4, "if _newclass:\n", tab4, NIL);
Printv(f_shadow, tab4, tab4, "object.__setattr__(self, name, value)\n", NIL);
if (!modern)
Printv(f_shadow, tab4, tab4, "else:\n", tab4, NIL);
}
if (classic || !modern)
if (!modern)
Printv(f_shadow, tab4, tab4, "self.__dict__[name] = value\n", NIL);
Printv(f_shadow,
tab4, "else:\n",
@ -937,7 +920,7 @@ public:
tab4, "try:\n", tab8, "strthis = \"proxy of \" + self.this.__repr__()\n",
tab4, "except __builtin__.Exception:\n", tab8, "strthis = \"\"\n", tab4, "return \"<%s.%s; %s >\" % (self.__class__.__module__, self.__class__.__name__, strthis,)\n\n", NIL);
if (!classic && !modern) {
if (!modern) {
Printv(f_shadow,
"try:\n",
tab4, "_object = object\n", tab4, "_newclass = 1\n",
@ -1057,7 +1040,7 @@ public:
if (shadow) {
Swig_banner_target_lang(f_shadow_py, "#");
if (!modern && !classic) {
if (!modern) {
Printv(f_shadow, "# This file is compatible with both classic and new-style classes.\n", NIL);
}
if (Len(f_shadow_begin) > 0)
@ -4433,7 +4416,6 @@ public:
}
virtual int classHandler(Node *n) {
int oldclassic = classic;
int oldmodern = modern;
File *f_shadow_file = f_shadow;
Node *base_node = NULL;
@ -4445,15 +4427,12 @@ public:
have_repr = 0;
if (GetFlag(n, "feature:classic")) {
classic = 1;
modern = 0;
}
if (GetFlag(n, "feature:modern")) {
classic = 0;
modern = 1;
}
if (GetFlag(n, "feature:exceptionclass")) {
classic = 1;
modern = 0;
}
@ -4541,14 +4520,13 @@ public:
if (Len(base_class)) {
Printf(f_shadow, "(%s)", base_class);
} else {
if (!classic) {
if (GetFlag(n, "feature:exceptionclass")) {
Printf(f_shadow, "(Exception)");
} else {
Printf(f_shadow, modern ? "(object" : "(_object");
Printf(f_shadow, modern && py3 && GetFlag(n, "feature:python:nondynamic") ? ", metaclass=_SwigNonDynamicMeta" : "", ")");
Printf(f_shadow, ")");
}
if (GetFlag(n, "feature:exceptionclass")) {
Printf(f_shadow, "(Exception)");
}
}
Printf(f_shadow, ":\n");
@ -4718,7 +4696,6 @@ public:
Clear(builtin_methods);
}
classic = oldclassic;
modern = oldmodern;
/* Restore shadow file back to original version */
@ -4913,14 +4890,11 @@ public:
}
Printv(f_shadow, tab4, symname, " = staticmethod(", symname, ")\n", NIL);
} else {
if (!classic) {
if (!modern)
Printv(f_shadow, tab4, "if _newclass:\n", tab4, NIL);
Printv(f_shadow, tab4, symname, " = staticmethod(", module, ".", Swig_name_member(NSPACE_TODO, class_name, symname),
")\n", NIL);
}
if (classic || !modern) {
if (!classic)
if (!modern) {
Printv(f_shadow, tab4, "else:\n", tab4, NIL);
Printv(f_shadow, tab4, symname, " = ", module, ".", Swig_name_member(NSPACE_TODO, class_name, symname), "\n", NIL);
}
@ -5153,14 +5127,12 @@ public:
}
Printv(f_shadow, tab4, "__swig_getmethods__[\"", symname, "\"] = ", module, ".", getname, "\n", NIL);
}
if (!classic) {
if (!modern)
Printv(f_shadow, tab4, "if _newclass:\n", tab4, NIL);
Printv(f_shadow, tab4, symname, " = property(", module, ".", getname, NIL);
if (assignable)
Printv(f_shadow, ", ", module, ".", setname, NIL);
Printv(f_shadow, ")\n", NIL);
}
Delete(mname);
Delete(setname);
Delete(getname);
@ -5227,7 +5199,7 @@ public:
}
Printv(f_shadow, tab4, "__swig_getmethods__[\"", symname, "\"] = ", module, ".", getname, "\n", NIL);
}
if (!classic && !builtin) {
if (!builtin) {
if (!modern)
Printv(f_shadow, tab4, "if _newclass:\n", tab4, NIL);
Printv(f_shadow, tab4, symname, " = property(", module, ".", getname, NIL);