From 7da78204128f1219afb00799e754492da13f4df0 Mon Sep 17 00:00:00 2001
From: James McCoy <jamessan@apache.org>
Date: Thu, 24 Dec 2015 18:33:13 +0000
Subject: [PATCH] Fix Python bindings with SWIG < 3.0.6, followup on 1721488.
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

“%pythoncode { ... }” had to be changed to “%pythoncode %{ ... %}” to avoid
macro expansion (done in r1721488).  This was a latent bug in the bindings
exposed by stricter parsing in SWIG 3.x.

However, there was a bug in SWIG through 3.0.6 which would remove part of the
commented lines inside the “%pythoncode %{ ... %}” block.  This caused the
"right" fix to break everywhere except 3.0.6+.

As discussed in the SWIG bug tracker[0], an alternative form of the pythoncode
directive can be used to inline the contents of a specified file.  Use of this
form works in all supported SWIG versions.

[0]: https://github.com/swig/swig/issues/379#issuecomment-107664345

* subversion/bindings/swig/include/proxy.swg:
  (proxy_pythoncode): Copy %pythoncode contents to ...

* subversion/bindings/swig/include/proxy.py:
  ... new file which is included in proxy.swg via “%pythoncode "..."”
  directive.

* build/ac-macros/swig.m4
  subversion/bindings/swig/INSTALL:
  Remove 3.x related SWIG restrictions.  All SWIG versions are supported again.


git-svn-id: https://svn.apache.org/repos/asf/subversion/trunk@1721648 13f79535-47bb-0310-9956-ffa450edef68
---
 build/ac-macros/swig.m4                    |  5 ++--
 subversion/bindings/swig/INSTALL           |  2 +-
 subversion/bindings/swig/include/proxy.py  | 41 +++++++++++++++++++++++++
 subversion/bindings/swig/include/proxy.swg | 48 +++---------------------------
 4 files changed, 48 insertions(+), 48 deletions(-)
 create mode 100644 subversion/bindings/swig/include/proxy.py

Index: subversion-1.8.10/subversion/bindings/swig/include/proxy.py
===================================================================
--- /dev/null
+++ subversion-1.8.10/subversion/bindings/swig/include/proxy.py
@@ -0,0 +1,41 @@
+  def set_parent_pool(self, parent_pool=None):
+    """Create a new proxy object for TYPE"""
+    import libsvn.core, weakref
+    self.__dict__["_parent_pool"] = \
+      parent_pool or libsvn.core.application_pool;
+    if self.__dict__["_parent_pool"]:
+      self.__dict__["_is_valid"] = weakref.ref(
+        self.__dict__["_parent_pool"]._is_valid)
+
+  def assert_valid(self):
+    """Assert that this object is using valid pool memory"""
+    if "_is_valid" in self.__dict__:
+      assert self.__dict__["_is_valid"](), "Variable has already been deleted"
+
+  def __getattr__(self, name):
+    """Get an attribute from this object"""
+    self.assert_valid()
+
+    value = _swig_getattr(self, self.__class__, name)
+
+    # If we got back a different object than we have, we need to copy all our
+    # metadata into it, so that it looks identical
+    members = self.__dict__.get("_members")
+    if members is not None:
+      _copy_metadata_deep(value, members.get(name))
+
+    # Verify that the new object is good
+    _assert_valid_deep(value)
+
+    return value
+
+  def __setattr__(self, name, value):
+    """Set an attribute on this object"""
+    self.assert_valid()
+
+    # Save a copy of the object, so that the garbage
+    # collector won't kill the object while it's in
+    # SWIG-land
+    self.__dict__.setdefault("_members",{})[name] = value
+
+    return _swig_setattr(self, self.__class__, name, value)
Index: subversion-1.8.10/subversion/bindings/swig/include/proxy.swg
===================================================================
--- subversion-1.8.10.orig/subversion/bindings/swig/include/proxy.swg
+++ subversion-1.8.10/subversion/bindings/swig/include/proxy.swg
@@ -60,51 +60,11 @@
         value.assert_valid()
 %}
 
-/* Default code for all wrapped proxy classes in Python */
+/* 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. */
 %define %proxy_pythoncode(TYPE)
-%pythoncode {
-  def set_parent_pool(self, parent_pool=None):
-    """Create a new proxy object for TYPE"""
-    import libsvn.core, weakref
-    self.__dict__["_parent_pool"] = \
-      parent_pool or libsvn.core.application_pool;
-    if self.__dict__["_parent_pool"]:
-      self.__dict__["_is_valid"] = weakref.ref(
-        self.__dict__["_parent_pool"]._is_valid)
-
-  def assert_valid(self):
-    """Assert that this object is using valid pool memory"""
-    if "_is_valid" in self.__dict__:
-      assert self.__dict__["_is_valid"](), "Variable has already been deleted"
-
-  def __getattr__(self, name):
-    """Get an attribute from this object"""
-    self.assert_valid()
-
-    value = _swig_getattr(self, self.__class__, name)
-
-    # If we got back a different object than we have, we need to copy all our
-    # metadata into it, so that it looks identical
-    members = self.__dict__.get("_members")
-    if members is not None:
-      _copy_metadata_deep(value, members.get(name))
-        
-    # Verify that the new object is good
-    _assert_valid_deep(value)
-
-    return value
-
-  def __setattr__(self, name, value):
-    """Set an attribute on this object"""
-    self.assert_valid()
-
-    # Save a copy of the object, so that the garbage
-    # collector won't kill the object while it's in
-    # SWIG-land
-    self.__dict__.setdefault("_members",{})[name] = value
-
-    return _swig_setattr(self, self.__class__, name, value)
-}
+%pythoncode "proxy.py"
 %enddef
 
 /* Define a proxy for wrapping an existing struct */
Index: subversion-1.8.10/subversion/bindings/swig/core.i
===================================================================
--- subversion-1.8.10.orig/subversion/bindings/swig/core.i
+++ subversion-1.8.10/subversion/bindings/swig/core.i
@@ -789,10 +789,11 @@ svn_swig_pl_set_current_pool (apr_pool_t
 #endif
 
 #ifdef SWIGPYTHON
-# The auth baton depends on the providers, so we preserve a
-# reference to them inside the wrapper. This way, if all external
-# references to the providers are gone, they will still be alive,
-# keeping the baton valid.
+/* The auth baton depends on the providers, so we preserve a
+   reference to them inside the wrapper. This way, if all external
+   references to the providers are gone, they will still be alive,
+   keeping the baton valid.
+ */
 %feature("pythonappend") svn_auth_open %{
   val.__dict__["_deps"] = list(args[0])
 %}
Index: subversion-1.8.10/subversion/bindings/swig/svn_delta.i
===================================================================
--- subversion-1.8.10.orig/subversion/bindings/swig/svn_delta.i
+++ subversion-1.8.10/subversion/bindings/swig/svn_delta.i
@@ -208,11 +208,11 @@ void _ops_get(int *num_ops, svn_txdelta_
 %include svn_delta_h.swg
 
 #ifdef SWIGPYTHON
-%pythoncode {
+%pythoncode %{
 # This function is for backwards compatibility only.
 # Use svn_txdelta_window_t.ops instead.
 svn_txdelta_window_t_ops_get = svn_txdelta_window_t._ops_get
-}
+%}
 #endif
 
 #ifdef SWIGRUBY
