Commit f0ac08a6 authored by Jason Madden's avatar Jason Madden

Add a test checking the non-cooperative behaviour of...

Add a test checking the non-cooperative behaviour of Persistent.__getattribute__ in both C and Python.
parent 2467abc9
...@@ -23,7 +23,7 @@ try: ...@@ -23,7 +23,7 @@ try:
from persistent.cPersistence import UPTODATE from persistent.cPersistence import UPTODATE
from persistent.cPersistence import CHANGED from persistent.cPersistence import CHANGED
from persistent.cPersistence import STICKY from persistent.cPersistence import STICKY
except ImportError: #pragma NO COVER except ImportError: # pragma: no cover
GHOST = -1 GHOST = -1
UPTODATE = 0 UPTODATE = 0
CHANGED = 1 CHANGED = 1
......
...@@ -48,7 +48,7 @@ _SWEEP_NEEDS_GC = not hasattr(sys, 'getrefcount') ...@@ -48,7 +48,7 @@ _SWEEP_NEEDS_GC = not hasattr(sys, 'getrefcount')
# On Jython, we need to explicitly ask it to monitor # On Jython, we need to explicitly ask it to monitor
# objects if we want a more deterministic GC # objects if we want a more deterministic GC
if hasattr(gc, 'monitorObject'): #pragma: no cover if hasattr(gc, 'monitorObject'): # pragma: no cover
_gc_monitor = gc.monitorObject _gc_monitor = gc.monitorObject
else: else:
def _gc_monitor(o): def _gc_monitor(o):
...@@ -395,7 +395,8 @@ class PickleCache(object): ...@@ -395,7 +395,8 @@ class PickleCache(object):
value = self.data.get(oid) value = self.data.get(oid)
if value is not None and value._p_state != GHOST: if value is not None and value._p_state != GHOST:
value._p_invalidate() value._p_invalidate()
if self.ring.delete(value): was_in_ring = self.ring.delete(value)
assert was_in_ring, "Ring corruption: invalidated a non-ghost not in ring"
self.non_ghost_count -= 1 self.non_ghost_count -= 1
elif oid in self.persistent_classes: elif oid in self.persistent_classes:
persistent_class = self.persistent_classes[oid] persistent_class = self.persistent_classes[oid]
......
...@@ -146,7 +146,7 @@ class _DequeRing(object): ...@@ -146,7 +146,7 @@ class _DequeRing(object):
try: try:
from cffi import FFI from cffi import FFI
except ImportError: #pragma: no cover except ImportError: # pragma: no cover
_CFFIRing = None _CFFIRing = None
else: else:
......
...@@ -692,6 +692,24 @@ class _Persistent_Base(object): ...@@ -692,6 +692,24 @@ class _Persistent_Base(object):
self.assertEqual(getattr(inst, 'normal', None), 'value') self.assertEqual(getattr(inst, 'normal', None), 'value')
self._checkMRU(jar, [OID]) self._checkMRU(jar, [OID])
def test___getattribute___non_cooperative(self):
# Getting attributes is NOT cooperative with the superclass.
# This comes from the C implementation and is maintained
# for backwards compatibility. (For example, Persistent and
# ExtensionClass.Base/Acquisition take special care to mix together.)
class Base(object):
def __getattribute__(self, name):
if name == 'magic':
return 42
return super(Base,self).__getattribute__(name)
self.assertEqual(getattr(Base(), 'magic'), 42)
class Derived(self._getTargetClass(), Base):
pass
self.assertRaises(AttributeError, getattr, Derived(), 'magic')
def test___setattr___p__names(self): def test___setattr___p__names(self):
from persistent.timestamp import _makeOctets from persistent.timestamp import _makeOctets
SERIAL = _makeOctets('\x01' * 8) SERIAL = _makeOctets('\x01' * 8)
......
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