Index: build/ac-macros/swig.m4
===================================================================
--- build/ac-macros/swig.m4	(revision 1869792)
+++ build/ac-macros/swig.m4	(working copy)
@@ -158,15 +158,18 @@
           ])
 
           if test "$ac_cv_python_is_py3" = "yes"; then
-            if test "$SWIG_VERSION" -ge "300010" -a "$SWIG_VERSION" -lt "400000"; then
-              SWIG_PY_OPTS="-python -py3"
+            if test "$SWIG_VERSION" -ge "300010"; then
               dnl SWIG Python bindings successfully configured, clear the error message dnl
               SWIG_PY_ERRMSG=""
             else
-              SWIG_PY_OPTS="-python -py3 -nofastunpack"
               SWIG_PY_ERRMSG="SWIG version is not suitable"
-              AC_MSG_WARN([Subversion Python bindings for Python 3 require 3.0.10 <= SWIG < 4.0.0])
+              AC_MSG_WARN([Subversion Python bindings for Python 3 require SWIG 3.0.10 or newer])
             fi
+            if test "$SWIG_VERSION" -lt "400000"; then
+              SWIG_PY_OPTS="-python -py3 -nofastunpack -modern"
+            else
+              SWIG_PY_OPTS="-python -py3 -nofastunpack"
+            fi
           else
             if test "$SWIG_VERSION" -lt "400000"; then
               SWIG_PY_OPTS="-python -classic"
Index: subversion/bindings/swig/INSTALL
===================================================================
--- subversion/bindings/swig/INSTALL	(revision 1869792)
+++ subversion/bindings/swig/INSTALL	(working copy)
@@ -78,8 +78,7 @@
       - SWIG 1.3.24 and later 1.3.x may work, but we do not test these
         versions on our latest source code.
       - For Python 2 bindings, SWIG 4.0.0 or later is not supported.
-      - For Python 3 bindings, SWIG 3.0.10 or later is required, but
-        SWIG 4.0.0 and later is not supported (yet).
+      - For Python 3 bindings, SWIG 3.0.10 or later is required.
       - Note that SWIG 3.0.9 has some trouble with Python support.
         (See https://sourceforge.net/p/swig/news/2016/06/swig-3010-released/)
       - For Perl 5.16 and later, SWIG 2.0.8 or later is required.
Index: subversion/bindings/swig/include/proxy.py
===================================================================
--- subversion/bindings/swig/include/proxy.py	(revision 1869792)
+++ subversion/bindings/swig/include/proxy.py	(working copy)
@@ -25,13 +25,6 @@
 
     return value
 
-  # SWIG classes generated with -classic do not define this variable,
-  # so set it to 0 when it doesn't exist
-  try:
-    _newclass
-  except NameError:
-    _newclass = 0
-
   # Attribute access must be intercepted to ensure that objects coming from
   # read attribute access match those that are set with write attribute access.
   # Specifically the metadata, such as the associated apr_pool object, should
@@ -58,13 +51,7 @@
 
       object.__getattribute__(self, 'assert_valid')()
 
-      try:
-        value = object.__getattribute__(self, name)
-      except AttributeError:
-        value = _swig_getattr(self,
-                              object.__getattribute__(self, '__class__'),
-                              name)
-
+      value = _get_instance_attr(self, name)
       fn = object.__getattribute__(self, '_retrieve_swig_value')
       return fn(name, value)
   else:
@@ -85,4 +72,4 @@
     # SWIG-land
     self.__dict__.setdefault("_members",{})[name] = value
 
-    return _swig_setattr(self, self.__class__, name, value)
+    return _set_instance_attr(self, name, value)
Index: subversion/bindings/swig/include/proxy.swg
===================================================================
--- subversion/bindings/swig/include/proxy.swg	(revision 1869792)
+++ subversion/bindings/swig/include/proxy.swg	(working copy)
@@ -64,8 +64,59 @@
         pass
       else:
         fn()
+
 %}
+#if defined(SWIGPYTHON_PY3)
+#if SWIG_VERSION >= 0x040000
+%pythoncode %{
+  # -classic and -modern options have been dropped and this variable
+  # is not generated since SWIG 4
+  _newclass = 1
+  _get_instance_attr = object.__getattribute__
+  _set_instance_attr = _swig_setattr_nondynamic_instance_variable(object.__setattr__)
 
+%}
+#else
+%pythoncode %{
+  # SWIG classes generated with -modern do not define this variable
+  try:
+    _newclass
+  except NameError:
+    _newclass = 1
+  else:
+    raise RuntimeError("Require -modern option, but _newclass is defined")
+
+  _get_instance_attr = object.__getattribute__
+  _set_instance_attr = _swig_setattr_nondynamic_method(object.__setattr__)
+
+%}
+#endif
+#else
+%pythoncode %{
+  # SWIG classes generated with -classic do not define this variable,
+  # so set it to 0 when it doesn't exist
+  try:
+    _newclass
+  except NameError:
+    _newclass = 0
+
+  if _newclass:
+    def _get_instance_attr(self, name):
+      try:
+        return object.__getattribute__(self, name)
+      except AttributeError:
+        return _swig_getattr(self, object.__getattribute__(self, '__class__'),
+                             name)
+  else:
+    def _get_instance_attr(self, name):
+      return _swig_getattr(self, self.__class__, name)
+
+  def _set_instance_attr(self, name, value):
+    return _swig_setattr(self, self.__class__, name, value)
+
+%}
+#endif
+
 /* Default code for all wrapped proxy classes in Python.
  * Inline the code from a separate file to avoid issues with
  * SWIG mis-parsing the comments as preprocessor directives. */
