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
diff --git a/.travis.yml b/.travis.yml
index 5621683..29c3129 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -224,11 +224,6 @@
       dist: trusty
     - compiler: gcc
       os: linux
-      env: SWIGLANG=python SWIG_FEATURES=-classic
-      sudo: required
-      dist: trusty
-    - compiler: gcc
-      os: linux
       env: SWIGLANG=r
       sudo: required
       dist: trusty
diff --git a/Doc/Manual/Python.html b/Doc/Manual/Python.html
index db9bf97..4958d80 100644
--- a/Doc/Manual/Python.html
+++ b/Doc/Manual/Python.html
@@ -6313,9 +6313,7 @@
 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:
diff --git a/Examples/python/exceptproxy/example.i b/Examples/python/exceptproxy/example.i
index f5f8351..4ad9608 100644
--- a/Examples/python/exceptproxy/example.i
+++ b/Examples/python/exceptproxy/example.i
@@ -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.
+  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 issue, and if you don't mark the class, you will
-  see 'interesting' behaviours at the python side.
-  
-
+  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;
diff --git a/Examples/python/import_packages/same_modnames1/runme.py b/Examples/python/import_packages/same_modnames1/runme.py
index 3c3c00c..5f6a7f5 100644
--- a/Examples/python/import_packages/same_modnames1/runme.py
+++ b/Examples/python/import_packages/same_modnames1/runme.py
@@ -10,10 +10,6 @@
 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"
diff --git a/Examples/python/import_packages/same_modnames2/runme.py b/Examples/python/import_packages/same_modnames2/runme.py
index 38daad0..55f6826 100644
--- a/Examples/python/import_packages/same_modnames2/runme.py
+++ b/Examples/python/import_packages/same_modnames2/runme.py
@@ -9,10 +9,6 @@
 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"
diff --git a/Examples/test-suite/python/autodoc_runme.py b/Examples/test-suite/python/autodoc_runme.py
index d89c7a8..1350c6d 100644
--- a/Examples/test-suite/python/autodoc_runme.py
+++ b/Examples/test-suite/python/autodoc_runme.py
@@ -10,9 +10,6 @@
             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 @@
         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
diff --git a/Examples/test-suite/python/cpp_static_runme.py b/Examples/test-suite/python/cpp_static_runme.py
index ef31f88..e8c8cf6 100644
--- a/Examples/test-suite/python/cpp_static_runme.py
+++ b/Examples/test-suite/python/cpp_static_runme.py
@@ -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)
+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")
diff --git a/Examples/test-suite/python/default_args_runme.py b/Examples/test-suite/python/default_args_runme.py
index 4d937d2..683314d 100644
--- a/Examples/test-suite/python/default_args_runme.py
+++ b/Examples/test-suite/python/default_args_runme.py
@@ -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 @@
     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
+    Klass_inc = default_args.Klass.inc
 
     if Klass_inc(100, default_args.Klass(22)).val != 122:
         raise RuntimeError("Klass::inc failed")
diff --git a/Examples/test-suite/python/director_abstract_runme.py b/Examples/test-suite/python/director_abstract_runme.py
index 031c476..333b75f 100644
--- a/Examples/test-suite/python/director_abstract_runme.py
+++ b/Examples/test-suite/python/director_abstract_runme.py
@@ -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 @@
 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
diff --git a/Examples/test-suite/python/global_namespace_runme.py b/Examples/test-suite/python/global_namespace_runme.py
index ac12fe2..a47f410 100644
--- a/Examples/test-suite/python/global_namespace_runme.py
+++ b/Examples/test-suite/python/global_namespace_runme.py
@@ -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 @@
 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 @@
 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 @@
 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)
diff --git a/Examples/test-suite/python/implicittest_runme.py b/Examples/test-suite/python/implicittest_runme.py
index 4646d08..f17788e 100644
--- a/Examples/test-suite/python/implicittest_runme.py
+++ b/Examples/test-suite/python/implicittest_runme.py
@@ -6,9 +6,6 @@
         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(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
diff --git a/Examples/test-suite/python/li_boost_shared_ptr_bits_runme.py b/Examples/test-suite/python/li_boost_shared_ptr_bits_runme.py
index 9b9c7d6..adf9ac4 100644
--- a/Examples/test-suite/python/li_boost_shared_ptr_bits_runme.py
+++ b/Examples/test-suite/python/li_boost_shared_ptr_bits_runme.py
@@ -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 @@
     raise "sum is wrong"
 
 ################################
-if is_new_style_class(HiddenDestructor):
-    p = HiddenDestructor.create()
-else:
-    p = HiddenDestructor_create()
+p = HiddenDestructor.create()
diff --git a/Examples/test-suite/python/namespace_class_runme.py b/Examples/test-suite/python/namespace_class_runme.py
index e0bd3ca..aa51655 100644
--- a/Examples/test-suite/python/namespace_class_runme.py
+++ b/Examples/test-suite/python/namespace_class_runme.py
@@ -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 @@
 if (error):
     raise RuntimeError, "Private2 is private"
 
-if is_new_style_class(EulerT3D):
-    EulerT3D.toFrame(1, 1, 1)
-else:
-    EulerT3D().toFrame(1, 1, 1)
+EulerT3D.toFrame(1, 1, 1)
 
 b = BooT_i()
 b = BooT_H()
@@ -40,7 +33,6 @@
 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)
+f_type = str(type(f))
+if f_type.find("'namespace_class.FooT_H'") == -1:
+    raise RuntimeError("Incorrect type: " + f_type)
diff --git a/Examples/test-suite/python/overload_template_fast_runme.py b/Examples/test-suite/python/overload_template_fast_runme.py
index 95349a9..ca3cac9 100644
--- a/Examples/test-suite/python/overload_template_fast_runme.py
+++ b/Examples/test-suite/python/overload_template_fast_runme.py
@@ -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 @@
     raise RuntimeError, ("nsoverload(const char *)")
 
 
-if is_new_style_class(A):
-    A.foo(1)
-else:
-    A_foo(1)
+A.foo(1)
 b = B()
 b.foo(1)
diff --git a/Examples/test-suite/python/python_append_runme.py b/Examples/test-suite/python/python_append_runme.py
index ce5514d..eddda53 100644
--- a/Examples/test-suite/python/python_append_runme.py
+++ b/Examples/test-suite/python/python_append_runme.py
@@ -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()
+t.static_func()
 
 if grabpath() != os.path.dirname(mypath):
     raise RuntimeError("grabpath failed")
diff --git a/Examples/test-suite/python/python_docstring_runme.py b/Examples/test-suite/python/python_docstring_runme.py
index 0284ea0..a601ecb 100644
--- a/Examples/test-suite/python/python_docstring_runme.py
+++ b/Examples/test-suite/python/python_docstring_runme.py
@@ -9,7 +9,7 @@
         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"
diff --git a/Examples/test-suite/python/python_pickle_runme.py b/Examples/test-suite/python/python_pickle_runme.py
index cf28479..27c67ae 100644
--- a/Examples/test-suite/python/python_pickle_runme.py
+++ b/Examples/test-suite/python/python_pickle_runme.py
@@ -3,17 +3,11 @@
 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")
diff --git a/Examples/test-suite/python/python_richcompare_runme.py b/Examples/test-suite/python/python_richcompare_runme.py
index 2476603..724d1d7 100644
--- a/Examples/test-suite/python/python_richcompare_runme.py
+++ b/Examples/test-suite/python/python_richcompare_runme.py
@@ -6,9 +6,6 @@
 #        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,39 +100,37 @@
 
 # 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")
-        if (base1 <= 42):
-            raise RuntimeError("Comparing class to incompatible type, <= returned True")
-        if not (base1 > 42):
-            raise RuntimeError("Comparing class to incompatible type, > returned False")
-        if not (base1 >= 42):
-            raise RuntimeError("Comparing class to incompatible type, >= returned False")
-    else:
-        # Python 3 throws: TypeError: unorderable types
-        try:
-            res = base1 < 42
-            raise RuntimeError("Failed to throw")
-        except TypeError,e:
-            check_unorderable_types(e)
-        try:
-            res = base1 <= 42
-            raise RuntimeError("Failed to throw")
-        except TypeError,e:
-            check_unorderable_types(e)
-        try:
-            res = base1 > 42
-            raise RuntimeError("Failed to throw")
-        except TypeError,e:
-            check_unorderable_types(e)
-        try:
-            res = base1 >= 42
-            raise RuntimeError("Failed to throw")
-        except TypeError,e:
-            check_unorderable_types(e)
+if sys.version_info[0:2] < (3, 0):
+    if (base1 < 42):
+        raise RuntimeError("Comparing class to incompatible type, < returned True")
+    if (base1 <= 42):
+        raise RuntimeError("Comparing class to incompatible type, <= returned True")
+    if not (base1 > 42):
+        raise RuntimeError("Comparing class to incompatible type, > returned False")
+    if not (base1 >= 42):
+        raise RuntimeError("Comparing class to incompatible type, >= returned False")
+else:
+    # Python 3 throws: TypeError: unorderable types
+    try:
+        res = base1 < 42
+        raise RuntimeError("Failed to throw")
+    except TypeError,e:
+        check_unorderable_types(e)
+    try:
+        res = base1 <= 42
+        raise RuntimeError("Failed to throw")
+    except TypeError,e:
+        check_unorderable_types(e)
+    try:
+        res = base1 > 42
+        raise RuntimeError("Failed to throw")
+    except TypeError,e:
+        check_unorderable_types(e)
+    try:
+        res = base1 >= 42
+        raise RuntimeError("Failed to throw")
+    except TypeError,e:
+        check_unorderable_types(e)
 
 # Check inequalities used for ordering
 #-------------------------------------------------------------------------
diff --git a/Examples/test-suite/python/smart_pointer_member_runme.py b/Examples/test-suite/python/smart_pointer_member_runme.py
index ce91da2..d2ed87e 100644
--- a/Examples/test-suite/python/smart_pointer_member_runme.py
+++ b/Examples/test-suite/python/smart_pointer_member_runme.py
@@ -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.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
+if Foo.z == Bar.z:
+    raise RuntimeError
diff --git a/Source/Modules/python.cxx b/Source/Modules/python.cxx
index c2952d6..dbc0a98 100755
--- a/Source/Modules/python.cxx
+++ b/Source/Modules/python.cxx
@@ -65,7 +65,6 @@
 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 @@
      -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 @@
 	  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 @@
 	  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 @@
 	  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 @@
       }
     }
 
-    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 @@
       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 @@
 	       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, "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 (!modern)
 	  Printv(f_shadow, tab4, tab4, "self.__dict__[name] = value\n", NIL);
 	Printv(f_shadow,
 	       tab4, "else:\n",
@@ -937,7 +920,7 @@
 	       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 @@
 
     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 @@
   }
 
   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 @@
       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 @@
 	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 @@
       Clear(builtin_methods);
     }
 
-    classic = oldclassic;
     modern = oldmodern;
 
     /* Restore shadow file back to original version */
@@ -4913,15 +4890,12 @@
 	}
 	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)
-	    Printv(f_shadow, tab4, "else:\n", tab4, NIL);
+	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 (!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 @@
 	}
 	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);
-      }
+      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 @@
 	  }
 	  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);