On Tuesday 03 October 2006 18:17, Oleg Broytmann wrote:
> I don't think the problem is in .expireAll(). What is going on, as I
> understand, is that .expireAll() clears the cache and as now there are
> only weak reference to the row, Python garbage-collects it immediately.
> After that Python is free to create another object at the same address.

I thought about this in the beginning, but I tried some simple test which 
was unsuccessful, so I thought it must be something else. The test showed 
that addresses were not reused:
>>> s = {'foo': 1}
>>> id(s)
-1210595428
>>> del s
>>> s = {'bar': 1}
>>> id(s)
-1210595972

But today I tried the test differently:
>>> class Obj(object):
...  def __del__(self):
...   print "deleted"
... 
>>> o = Obj()
>>> id(o)
-1210983732
>>> del o
deleted
>>> o = Obj()
>>> id(o)
-1210983636

>>> class A:
...  def __del__(self):
...   print "deleted"  
... 
>>> a = A()
>>> id(a)
-1211041652
>>> del a
deleted
>>> a = A()
>>> id(a)
-1211041652

So it seems that for objects that are obtained from classes derived from 
object (strings, dictionaries, Obj(object), ...) it won't reuse the 
addresses, but for objects that result from old style (pre 2.2) classes 
it seems it will. So if those objects that are referenced by the weakref 
are not derived from new style classes, this would explain it indeed.

> the solution would be either to check weak references or to hold a real
> reference, like this:
>
> def test_cache():
>     setupClass(CacheTest)
>     s = CacheTest(name='foo')
>     obj_id = id(s)
>     s_id = s.id
>     assert CacheTest.get(s_id) is s
>     assert not s.sqlmeta.expired
>     CacheTest.sqlmeta.expireAll()
>     assert s.sqlmeta.expired
>     CacheTest.sqlmeta.expireAll()
>     s1 = CacheTest.get(s_id)
>     # We should have a new object:
>     assert id(s1) != obj_id
>     obj_id2 = id(s1)
>     CacheTest._connection.expireAll()
>     s2 = CacheTest.get(s_id)
>     assert id(s2) != obj_id and id(s2) != obj_id2
>

If this test works I think it's a better version of the original one.
This test looks fine to me as it shows that the object the cache returns 
after an expiration is different that the one before even if it has the 
same id (or at least it would have the same id if the old object would 
not be kept around by a reference)

> (I have removed "del" statments and created s1 and s2 instead of s.)
>
>    If I understand it right, the failure in test_cache() actually shows
> that your patch really works and helps to save memory! (-:

That thing I already knew without the test ;)

-- 
Dan

-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys -- and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
_______________________________________________
sqlobject-discuss mailing list
sqlobject-discuss@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/sqlobject-discuss

Reply via email to