diff options
Diffstat (limited to 'subversion/bindings/swig/include/proxy.py')
-rw-r--r-- | subversion/bindings/swig/include/proxy.py | 58 |
1 files changed, 46 insertions, 12 deletions
diff --git a/subversion/bindings/swig/include/proxy.py b/subversion/bindings/swig/include/proxy.py index ca4a64d..73ff5ff 100644 --- a/subversion/bindings/swig/include/proxy.py +++ b/subversion/bindings/swig/include/proxy.py @@ -12,23 +12,57 @@ 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)) + 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 + # 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')() + + value = _get_instance_attr(self, 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() @@ -38,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) |