[pylucene-dev] Automatic call to finalize

Andi Vajda vajda at osafoundation.org
Thu Jan 17 11:34:03 PST 2008


On Thu, 17 Jan 2008, Andi Vajda wrote:

> On Thu, 17 Jan 2008, anurag uniyal wrote:
>
>> Here is a modified version which can wrap any PythonCustomClass
>
> There is a sneaky bug in this code. All objs that are considered 'False' will 
> be leaked.
>
>  if obj:
>      obj.finalize()
>
> should be changed into:
>
>  if obj is not None:
>      obj.finalize()
>
> For example, an empty IndexReader, empty Hits, any thing that implements 
> __len__() and returns 0 for that call would be leaked.
>
> I wonder if this class wrapper could be coded as a decorator ?
> As in:
>
>  @FinalizeClassWrapper
>  class WowParser(lucene.PythonQueryParser):
>    etc...
>
> Anyhow, it looks like this is promising and I like it better than the 
> background thread idea I had suggested in earlier messages.

It looks promising but there seem to be issues with returning such objects 
to Java as from a tokenStream() method. This could be solved, though, by not 
calling finalize() from the finalizer wrapper but instead calling a 
yet-to-be coded method that would replace the global java ref in the deadly 
embrace with a global java weak ref, allowing it to be garbage collected by 
Java and finalize()'d when its time has come.

Likewise, the type error that one would get on returning these wrapper 
objects could also be dealt with.

Maybe there is a way to make this finalize() business easier to use after 
all :)

Andi..

>
> ----
> import weakref
> class FinalizeClassWrapper(object):
>    finalized = 0
>    class FinalizeWrapper(object):
>        count = 0
>        def __init__(self, obj):
>            self.objRef = weakref.ref(obj)
>        def __getattr__(self, name):
>            return getattr(self.objRef(), name)
>        def __del__(self):
>            obj = self.objRef()
>            if obj:
>                obj.finalize()
>                FinalizeClassWrapper.finalized += 1
>    def __init__(self, klass):
>        self.klass = klass
>    def __call__(self, *args):
>        return self.FinalizeWrapper(self.klass(*args))
>
> # sample usage
> class _WowParser(lucene.PythonQueryParser):
>    def __init__(self,defaultField, analyzer):
>        super(_WowParser, self).__init__(defaultField, analyzer)
> WowParser = FinalizeClassWrapper(_WowParser)
> ----
> rgds
> Anurag
>
>
> ----- Original Message ----
> From: anurag uniyal <anuraguniyal at yahoo.com>
> To: pylucene-dev at osafoundation.org
> Sent: Thursday, 17 January, 2008 12:19:40 PM
> Subject: [pylucene-dev] Automatic call to finalize
>
>
> I have a custom parser which is created and used to parse queries at several 
> places.
> Instead of calling finalize each time, I have wrapped my custom parser in a 
> python class and keep a ref to it, delegating all calls and it works well, 
> without any weakrefs.
>
> Do you think such behaviour is correct and please tell if it can create any 
> problems?
>
> ---------
> import lucene
> lucene.initVM(lucene.CLASSPATH, maxheap='1m')
> class MyParser(object):
>
>    class _MyParser(lucene.PythonQueryParser):
>        def __init__(self,defaultField, analyzer):
>            super(MyParser._MyParser, self).__init__(defaultField, analyzer)
>
>    def __init__(self,defaultField, analyzer):
>        self._parser = self._MyParser(defaultField, analyzer)
>
>    def __getattr__(self, name):
>        return getattr(self._parser, name)
>
>    def __del__(self):
>        self._parser.finalize()
>
> analyzer = lucene.StandardAnalyzer()
> for i in xrange(100000):
>    if i%100==0:print i
>    customParser = MyParser("body", analyzer)
>    query = customParser.parse("anurag")
> ---------
>
>
>      Now you can chat without downloading messenger. Go to 
> http://in.messenger.yahoo.com/webmessengerpromo.php
> _______________________________________________
> pylucene-dev mailing list
> pylucene-dev at osafoundation.org
> http://lists.osafoundation.org/mailman/listinfo/pylucene-dev
>


More information about the pylucene-dev mailing list