You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by tr...@apache.org on 2018/01/04 04:06:36 UTC
svn commit: r1820032 - in /subversion/branches/swig-py3:
build/ac-macros/swig.m4 subversion/bindings/swig/include/proxy.py
Author: troycurtisjr
Date: Thu Jan 4 04:06:36 2018
New Revision: 1820032
URL: http://svn.apache.org/viewvc?rev=1820032&view=rev
Log:
On branch swig-py3: Go back to using classic classes for Python 2 swig bindings.
Add some additional clarifying comments for the reasons behind overriding
__getattr__ and __getattribute__.
* build/ac-macros/swig.m4
(SVN_FIND_SWIG): Add the '-classic' flag to swig when python 2 is detected.
* subversion/bindings/swig/include/proxy.py
(_retrieve_swig_value): Factor out metadata retrieval from __getattribute__ to a new function.
(__getattribute__): Only define __getattribute__ for new style classes.
(__getattr__): Add back implementation for classic classes.
Suggested By: brane
Modified:
subversion/branches/swig-py3/build/ac-macros/swig.m4
subversion/branches/swig-py3/subversion/bindings/swig/include/proxy.py
Modified: subversion/branches/swig-py3/build/ac-macros/swig.m4
URL: http://svn.apache.org/viewvc/subversion/branches/swig-py3/build/ac-macros/swig.m4?rev=1820032&r1=1820031&r2=1820032&view=diff
==============================================================================
--- subversion/branches/swig-py3/build/ac-macros/swig.m4 (original)
+++ subversion/branches/swig-py3/build/ac-macros/swig.m4 Thu Jan 4 04:06:36 2018
@@ -155,7 +155,7 @@ AC_DEFUN(SVN_FIND_SWIG,
if test "$ac_cv_python_is_py3" = "yes"; then
SWIG_PY_OPTS="-python -py3"
else
- SWIG_PY_OPTS="-python"
+ SWIG_PY_OPTS="-python -classic"
fi
dnl Sun Forte adds an extra space before substituting APR_INT64_T_FMT
Modified: subversion/branches/swig-py3/subversion/bindings/swig/include/proxy.py
URL: http://svn.apache.org/viewvc/subversion/branches/swig-py3/subversion/bindings/swig/include/proxy.py?rev=1820032&r1=1820031&r2=1820032&view=diff
==============================================================================
--- subversion/branches/swig-py3/subversion/bindings/swig/include/proxy.py (original)
+++ subversion/branches/swig-py3/subversion/bindings/swig/include/proxy.py Thu Jan 4 04:06:36 2018
@@ -12,42 +12,70 @@
if "_is_valid" in self.__dict__:
assert self.__dict__["_is_valid"](), "Variable has already been deleted"
- def __getattribute__(self, name):
- """Manage access to all attributes of this object."""
-
- # Start by mimicing __getattr__ behavior: immediately return __dict__ or
- # items directly present in __dict__
- mydict = object.__getattribute__(self, '__dict__')
- if name == "__dict__":
- return mydict
-
- if name in mydict:
- return mydict[name]
-
- object.__getattribute__(self, 'assert_valid')()
-
- try:
- value = object.__getattribute__(self, name)
- except AttributeError:
- value = _swig_getattr(self,
- object.__getattribute__(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
- try:
- members = object.__getattribute__(self, '_members')
- if name in members:
- _copy_metadata_deep(value, members[name])
- # Verify that the new object is good
- except AttributeError:
- pass
+ def _retrieve_swig_value(self, name, value):
+ # If we got back a different object than we have cached, we need to copy
+ # all our metadata into it, so that it looks identical to the one
+ # originally set.
+ members = self.__dict__.get('_members')
+ if members is not None and name in members:
+ _copy_metadata_deep(value, members[name])
# Verify that the new object is good
_assert_valid_deep(value)
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
+ # match the originally assigned object.
+ #
+ # For classic classes it is enough to use __getattr__ to intercept swig
+ # derived attributes. However, with new style classes SWIG makes use of
+ # descriptors which mean that __getattr__ is never called. Therefore,
+ # __getattribute__ must be used for the interception.
+
+ if _newclass:
+ def __getattribute__(self, name):
+ """Manage access to all attributes of this object."""
+
+ # Start by mimicing __getattr__ behavior: immediately return __dict__ or
+ # items directly present in __dict__
+ mydict = object.__getattribute__(self, '__dict__')
+
+ if name == "__dict__":
+ return mydict
+
+ if name in mydict:
+ return mydict[name]
+
+ object.__getattribute__(self, 'assert_valid')()
+
+ try:
+ value = object.__getattribute__(self, name)
+ except AttributeError:
+ value = _swig_getattr(self,
+ object.__getattribute__(self, '__class__'),
+ name)
+
+ fn = object.__getattribute__(self, '_retrieve_swig_value')
+ return fn(name, value)
+ else:
+ def __getattr__(self, name):
+ """Get an attribute from this object"""
+ self.assert_valid()
+
+ value = _swig_getattr(self, self.__class__, name)
+
+ return self._retrieve_swig_value(name, value)
+
def __setattr__(self, name, value):
"""Set an attribute on this object"""
self.assert_valid()