Commit dece653b authored by Jim Fulton's avatar Jim Fulton

Fixed bug: External methods pickled function code and globals, which

was really stupid. It caused problems because func_defaults might
be non-unpicklable (e.g. includes somemodule.rfind).

Added simple unit test to allow me to fix the bug.
parent e1ed7d14
......@@ -16,7 +16,7 @@
This product provides support for external methods, which allow
domain-specific customization of web environments.
"""
__version__='$Revision: 1.46 $'[11:-2]
__version__='$Revision: 1.47 $'[11:-2]
from Globals import Persistent, DTMLFile, MessageDialog, HTML
import OFS.SimpleItem, Acquisition
import AccessControl.Role, sys, os, stat, traceback
......@@ -77,9 +77,9 @@ class ExternalMethod(OFS.SimpleItem.Item, Persistent, Acquisition.Explicit,
"""
meta_type='External Method'
func_defaults=()
func_code=None
meta_type = 'External Method'
_v_func_defaults = ()
_v_func_code = None
ZopeTime=Acquisition.Acquired
HelpSys=Acquisition.Acquired
......@@ -137,15 +137,8 @@ class ExternalMethod(OFS.SimpleItem.Item, Persistent, Acquisition.Explicit,
if hasattr(f,'im_func'): ff=f.im_func
else: ff=f
if check:
# Check to make sure function signature is the same.
# Otherwise, we may end up causing an unwanted change.
if self.func_defaults != ff.func_defaults:
self.func_defaults = ff.func_defaults
func_code=FuncCode(ff,f is not ff)
if func_code != self.func_code: self.func_code=func_code
self._v_func_defaults = ff.func_defaults
self._v_func_code = FuncCode(ff,f is not ff)
self._v_f=f
......@@ -196,15 +189,15 @@ class ExternalMethod(OFS.SimpleItem.Item, Persistent, Acquisition.Explicit,
f=self._v_f
else: f=self.getFunction()
__traceback_info__=args, kw, self.func_defaults
__traceback_info__=args, kw, self._v_func_defaults
try: return apply(f,args,kw)
except TypeError, v:
tb=sys.exc_info()[2]
try:
if ((self.func_code.co_argcount-
len(self.func_defaults or ()) - 1 == len(args))
and self.func_code.co_varnames[0]=='self'):
if ((self._v_func_code.co_argcount-
len(self._v_func_defaults or ()) - 1 == len(args))
and self._v_func_code.co_varnames[0]=='self'):
return apply(f,(self.aq_parent.this(),)+args,kw)
raise TypeError, v, tb
......
from math import sqrt
def testf(arg1, sqrt = sqrt):
return sqrt(arg1)
##############################################################################
#
# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
"""
$Id: __init__.py,v 1.2 2002/04/22 21:54:48 jim Exp $
"""
##############################################################################
#
# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
"""
Revision information:
$Id: testExternalMethod.py,v 1.2 2002/04/22 21:54:48 jim Exp $
"""
import math, os
from unittest import TestCase, TestSuite, main, makeSuite
import ZODB # dead goat
import Products.ExternalMethod.tests
from Products.ExternalMethod.ExternalMethod import ExternalMethod
class Test(TestCase):
def setUp(self):
self._old = __builtins__.__dict__.get('INSTANCE_HOME')
__builtins__.INSTANCE_HOME = os.path.split(
Products.ExternalMethod.tests.__file__)[0]
def tearDown(self):
if self._old is None:
del __builtins__.INSTANCE_HOME
else:
__builtins__.INSTANCE_HOME = self._old
def testStorage(self):
em1 = ExternalMethod('em', 'test method', 'Test', 'testf')
self.assertEqual(em1(4), math.sqrt(4))
state = em1.__getstate__()
em2 = ExternalMethod.__basicnew__()
em2.__setstate__(state)
self.assertEqual(em2(9), math.sqrt(9))
self.failIf(state.has_key('func_defaults'))
def test_suite():
return TestSuite((
makeSuite(Test),
))
def package_home(globals_dict):
__name__=globals_dict['__name__']
m=sys.modules[__name__]
if hasattr(m,'__path__'):
r=m.__path__[0]
elif "." in __name__:
r=sys.modules[__name__[:rfind(__name__,'.')]].__path__[0]
else:
r=__name__
return os.path.join(os.getcwd(), r)
if __name__=='__main__':
main(defaultTest='test_suite')
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