Good morning Troy, troycurti...@apache.org wrote on Fri, Dec 22, 2017 at 03:52:59 -0000: > On branch swig-py3: Correctly manage swig objects with Python new style > classes. > > * build/ac-macros/swig.m4 > (SVN_FIND_SWIG): > Request that swig generate new style classes, even for Python 2, to reduce > differences with Python 3. > > 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=1818995&r1=1818994&r2=1818995&view=diff > ============================================================================== > --- subversion/branches/swig-py3/build/ac-macros/swig.m4 (original) > +++ subversion/branches/swig-py3/build/ac-macros/swig.m4 Fri Dec 22 03:52:59 > 2017 > @@ -143,7 +143,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 -classic" > + SWIG_PY_OPTS="-python" > fi
What are the compatibility implications of this change? I couldn't find any documentation for the "-classic" option. > * subversion/bindings/swig/include/proxy.py > (__getattr__): Replace __getattr__ with __getattribute__ to correctly > intercept attribute access, even when swig uses descriptors for new style > classes (which are the only type available in Python 3). Could you help me understand what's going on here and why it's correct? I've read the documentation of object.__getattr__ and object.__getattribute__¹ but I don't follow how the fact that the class into which this code is included became a new-style class (rather than a classic class) brought on the need to migrate from __getattr__ to __getattribute__, nor why the order of precedence of lookup (first __dict__, then object.__getattribute__, then _swig_getattr) is correct. I'm asking because I'm trying to review the branch (to +1 its merge) and this is one of the open questions I have. ¹ https://docs.python.org/3/reference/datamodel.html#object.__getattr__ et seq. > 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=1818995&r1=1818994&r2=1818995&view=diff > ============================================================================== > --- subversion/branches/swig-py3/subversion/bindings/swig/include/proxy.py > (original) > +++ subversion/branches/swig-py3/subversion/bindings/swig/include/proxy.py > Fri Dec 22 03:52:59 2017 > @@ -12,17 +12,36 @@ > 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() > + def __getattribute__(self, name): > + """Manage access to all attributes of this object.""" > > - value = _swig_getattr(self, self.__class__, name) > + # 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 > - members = self.__dict__.get("_members") > - if members is not None: > - _copy_metadata_deep(value, members.get(name)) > + 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 > > # Verify that the new object is good > _assert_valid_deep(value) Cheers, Daniel