Commit 85eae639 authored by Jason Madden's avatar Jason Madden

The pure-Python Persistent class no longer calls subclass's __setattr__ at...

The pure-Python Persistent class no longer calls subclass's __setattr__ at instance creation time, just like the C version.
parent bf4fd8f9
...@@ -4,6 +4,9 @@ ...@@ -4,6 +4,9 @@
4.0.8 (Unreleased) 4.0.8 (Unreleased)
------------------ ------------------
- The pure-Python ``Persistent`` class no longer calls subclass's
``__setattr__`` at instance creation time. (PR #8)
- Make it possible to delete ``_p_jar`` / ``_p_oid`` of a pure-Python - Make it possible to delete ``_p_jar`` / ``_p_oid`` of a pure-Python
``Persistent`` object which has been removed from the jar's cache ``Persistent`` object which has been removed from the jar's cache
(fixes aborting a ZODB Connection that has added objects). (PR #7) (fixes aborting a ZODB Connection that has added objects). (PR #7)
......
...@@ -53,11 +53,15 @@ class Persistent(object): ...@@ -53,11 +53,15 @@ class Persistent(object):
def __new__(cls, *args, **kw): def __new__(cls, *args, **kw):
inst = super(Persistent, cls).__new__(cls) inst = super(Persistent, cls).__new__(cls)
inst.__jar = None # We bypass the __setattr__ implementation of this object
inst.__oid = None # at __new__ time, just like the C implementation does. This
inst.__serial = None # makes us compatible with subclasses that want to access
inst.__flags = None # properties like _p_changed in their setattr implementation
inst.__size = 0 _OSA(inst, '_Persistent__jar', None)
_OSA(inst, '_Persistent__oid', None)
_OSA(inst, '_Persistent__serial', None)
_OSA(inst, '_Persistent__flags', None)
_OSA(inst, '_Persistent__size', 0)
return inst return inst
# _p_jar: see IPersistent. # _p_jar: see IPersistent.
......
...@@ -1325,6 +1325,14 @@ class _Persistent_Base(object): ...@@ -1325,6 +1325,14 @@ class _Persistent_Base(object):
class mixed2(self._getTargetClass(), alternate): class mixed2(self._getTargetClass(), alternate):
pass pass
def test_setattr_in_subclass_is_not_called_creating_an_instance(self):
class subclass(self._getTargetClass()):
_v_setattr_called = False
def __setattr__(self, name, value):
object.__setattr__(self, '_v_setattr_called', True)
super(subclass,self).__setattr__(name, value)
inst = subclass()
self.assertEqual(object.__getattribute__(inst,'_v_setattr_called'), False)
class PyPersistentTests(unittest.TestCase, _Persistent_Base): class PyPersistentTests(unittest.TestCase, _Persistent_Base):
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment