Abstracting try..finally with generators (instead of macros)

Beni Cherniavsky cben at techunix.technion.ac.il
Tue Dec 17 10:25:22 EST 2002


On 2002-12-16, Andrew Dalke wrote:

> Excerpt from the modules cleanup essay:
> > While modules are generally not involved in cycles (except when there are
> > mutually recursive imports), a module's dictionary generally is involved
> > in a cycle because every function and method defined in the module
> > references its __dict__, and these functions and methods are generally
> > reachable from that __dict__. Thus, when a module is deleted, I explicitly
> > clear its __dict__ carefully. (This has always been done, just not
> > "carefully".)
>
> I'm sorry.I haven't put enough time into this to explain myself
> properly.
>
> I've had this be the case.I have a C extension called
> 'dayswig_python'.It contains two functions, dt_alloc_mol() and
> dt_dealloc(). I made a wrapper like this:
>
> import dayswig_python
>
> class Molecule:
>  def __init__(self):
>    self.mol = dayswig_python.dt_alloc_mol()
>  def __del__(self):
>    dayswig_python.dt_dealloc(self.mol)
>
> Call this module 'daylight'.Now instantiate a Molecule and
> exit Python
>
> import daylight
> mol = Dayight.Molecule()
>
> The __main__, daylight, and dayswig_python modules can be cleared
> in arbitrary order.Suppose dayswig_python is cleared first.
> Then when mol's finalizer is called, dayswig_python contains
> nothing so the getattr for dayswig_python.dt_dealloc fails with
> an AttributeError.
>
> I know this happens.'mol' doesn't have a reference to
> 'dayswig_python'.The __del__ does a global (in-module) lookup
> for that module in the finalizer, based on the string name.
> So the module cleanup code doesn't know there are functions
> which might still use functions in the module.
>
I'm sorry I must go now and I don't have time to understand your example
(I'll try again when I have time) but I think that C extensions should
behave as cleanly in this respect as Python functions (see below) --
otherwise they have a bug that hsould be fixed.

> You said:
>  > because every function and method defined in the module
>  > references [the module's] __dict__,
>
> This is not the case.Rather, if it is, please show me
> how to get to the module's global namespace via a gettattr
> chain.(globals() will work, but I don't know how it works.)
>

Every python function has an attribute `func_globals`.

>>> def foo():
...   print 2
...
>>> dir(foo)
['__call__', '__class__', '__delattr__', '__dict__', '__doc__', '__get__',
'__getattribute__', '__hash__', '__init__', '__name__', '__new__',
'__reduce__', '__repr__', '__setattr__', '__str__', 'func_closure',
'func_code', 'func_defaults', 'func_dict', 'func_doc', 'func_globals',
'func_name']
>>> foo.func_globals
{'__builtins__': <module '__builtin__' (built-in)>, '__name__':
'__main__', 'foo': <function foo at 0x815231c>, '__doc__': None}
>>> foo.func_globals is globals()
1


-- 
Beni Cherniavsky <cben at tx.technion.ac.il>




More information about the Python-list mailing list