[Zope] Should lambda method be legal or not?

Terry Hancock hancock@anansispaceworks.com
Sat, 22 Jun 2002 04:41:50 -0700


I ran across this limitation in part of a product design.
Here I've reduced it to a kind of minimal case for
illustration.  I don't know whether to call it a bug or
not, because I'm not sure it *should* be possible to
do this.  I'd be interested in opinions. If there's a
consensus that its a bug I'll submit it to the collector,
otherwise, I'll just be enlightened. :-)

The code:


#---------------------------------------------
#
# MyFolder -- Test subclassing from Folder:
#
#---------------------------------------------

class MyFolder(OFS.Folder.Folder):
    """
    MyFolder tests subclassing from folder. No special behaviors are
defined.
    See Folder for expected behavior.
    """
    meta_type='MyFolder'

manage_addMyFolderForm=DTMLFile('dtml/myfolderAdd', globals())

def manage_addMyFolder(self, id, title='', REQUEST=None):
    """
    Add a new Folder object with id *id*.
    User and public interface features have been removed.
    """
    ob=MyFolder()
    ob.id=str(id)
    ob.title=title
    self._setObject(id, ob)
    ob=self._getOb(id)

    ob.mymethod = lambda: 2

    if REQUEST is not None:
        return self.manage_main(self, REQUEST, update_menu=1)


As you can see, this is an extremely simple case of subclassing
from Folder. The only thing I've done is add a method "mymethod"
which happens to be defined by an anonymous function (lambda).
Obviously I would've used something less trivial than "2" in
practice.

Defined like this, I can add this object through the Zope management
interface, and it behaves exactly as I would expect it to.

Until I restart.

Then, an attempt to view the contents of the folder containing
MyFolder (i.e. not MyFolder itself, but its parent), yields the
following traceback:

Failed to import class from module __main__ 

Traceback (innermost last):
  File /usr/local/narya/z2.5.1/lib/python/ZPublisher/Publish.py, line
150, in publish_module
  File /usr/local/narya/z2.5.1/lib/python/ZPublisher/Publish.py, line
114, in publish
  File /usr/local/narya/z2.5.1/lib/python/Zope/__init__.py, line 159, in
zpublisher_exception_hook
    (Object: Badge)
  File /usr/local/narya/z2.5.1/lib/python/ZPublisher/Publish.py, line
98, in publish
  File /usr/local/narya/z2.5.1/lib/python/ZPublisher/mapply.py, line 88,
in mapply
    (Object: manage_main)
  File /usr/local/narya/z2.5.1/lib/python/ZPublisher/Publish.py, line
39, in call_object
    (Object: manage_main)
  File /usr/local/narya/z2.5.1/lib/python/Shared/DC/Scripts/Bindings.py,
line 252, in __call__
    (Object: manage_main)
  File /usr/local/narya/z2.5.1/lib/python/Shared/DC/Scripts/Bindings.py,
line 283, in _bindAndExec
    (Object: manage_main)
  File /usr/local/narya/z2.5.1/lib/python/App/special_dtml.py, line 172,
in _exec
    (Object: manage_main)
  File /usr/local/narya/z2.5.1/lib/python/DocumentTemplate/DT_In.py,
line 637, in renderwob
    (Object: objectItems)
  File /usr/local/narya/z2.5.1/lib/python/DocumentTemplate/DT_In.py,
line 763, in sort_sequence
    (Object: objectItems)
  File /usr/local/narya/z2.5.1/lib/python/ZODB/Connection.py, line 472,
in setstate
SystemError: (see above)

The solution is simple enough -- remove the anonymous function and
replace it with a real function:

def mymethod_function():
    "My Method"
    return 2

and replace the method assignment with:

    ob.mymethod = mymethod_function

(it can also be a callable class -- which is the actual reason for not
just defining it in place. In my reduced example, it's sort of
contrived).

I note also that lambda doesn't appear to have any way to
assign the docstring required by Zope for publishing, so
maybe that in itself is reason enough not to do this.

In my original problem, lambda seemed to be a useful tool,
since the result was a trivial case (other functions used
a more complex callable class, but I just put in a lambda
for the trivial case).

Clearly, I'm just going to avoid using lambda like this
in the future, but should I have been able to?  It seems
kind of fuzzy to me either way, so I'd be interested
in the reasoning either way.

Thanks,
Terry

-- 
------------------------------------------------------
Terry Hancock
hancock@anansispaceworks.com       
Anansi Spaceworks                 
http://www.anansispaceworks.com 
P.O. Box 60583                     
Pasadena, CA 91116-6583
------------------------------------------------------