Commit 9d03f582 authored by Tres Seaver's avatar Tres Seaver

Collector #2157: Expose name of broken class in SystemError raised from

'__getstate__' of a broken instance.
parent eb6b6891
...@@ -4,6 +4,13 @@ Zope Changes ...@@ -4,6 +4,13 @@ Zope Changes
Change information for previous versions of Zope can be found in the Change information for previous versions of Zope can be found in the
file HISTORY.txt. file HISTORY.txt.
After Zope 2.8.8
Bugs fixed
- Collector #2157: Expose name of broken class in SystemError raised
from '__getstate__' of a broken instance.
Zope 2.8.8 (2006/07/14) Zope 2.8.8 (2006/07/14)
Bugs fixed Bugs fixed
......
...@@ -38,7 +38,7 @@ class BrokenClass(Acquisition.Explicit, SimpleItem.Item, ...@@ -38,7 +38,7 @@ class BrokenClass(Acquisition.Explicit, SimpleItem.Item,
raise SystemError, ( raise SystemError, (
"""This object was originally created by a product that """This object was originally created by a product that
is no longer installed. It cannot be updated. is no longer installed. It cannot be updated.
""") (%s)""" % repr(self))
def __getattr__(self, name): def __getattr__(self, name):
if name[:3]=='_p_': if name[:3]=='_p_':
......
##############################################################################
#
# Copyright (c) 2006 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.
#
##############################################################################
import unittest
class TestsOfBroken(unittest.TestCase):
"""Tests for the factory for "broken" classes.
"""
def setUp(self):
from OFS.Uninstalled import broken_klasses
from OFS.Uninstalled import broken_klasses_lock
self.broken_klasses_OLD = {}
broken_klasses_lock.acquire()
try:
self.broken_klasses_OLD.update(broken_klasses)
broken_klasses.clear()
finally:
broken_klasses_lock.release()
def tearDown(self):
from OFS.Uninstalled import broken_klasses
from OFS.Uninstalled import broken_klasses_lock
broken_klasses_lock.acquire()
try:
broken_klasses.clear()
broken_klasses.update(self.broken_klasses_OLD)
finally:
broken_klasses_lock.release()
def test_Broken_non_product_no_oid_yields_class_derived_from_Broken(self):
from OFS.Uninstalled import Broken
from OFS.Uninstalled import BrokenClass
klass = Broken(self, None, ('some.python.module', 'MyClass'))
self.failUnless(issubclass(klass, BrokenClass))
self.assertEqual(klass.__name__, 'MyClass')
self.assertEqual(klass.__module__, 'some.python.module')
self.assertEqual(klass.product_name, 'unknown')
def test_Broken_product_no_oid_yields_class_derived_from_Broken(self):
from OFS.Uninstalled import Broken
from OFS.Uninstalled import BrokenClass
klass = Broken(self, None, ('Products.MyProduct.MyClass', 'MyClass'))
self.failUnless(issubclass(klass, BrokenClass))
self.assertEqual(klass.__name__, 'MyClass')
self.assertEqual(klass.__module__, 'Products.MyProduct.MyClass')
self.assertEqual(klass.product_name, 'MyProduct')
def test_Broken_product_with_oid_yields_instance_derived_from_Broken(self):
from OFS.Uninstalled import Broken
from OFS.Uninstalled import BrokenClass
OID = '\x01' * 8
inst = Broken(self, OID, ('Products.MyProduct.MyClass', 'MyClass'))
self.failUnless(isinstance(inst, BrokenClass))
self.failUnless(inst._p_jar is self)
self.assertEqual(inst._p_oid, OID)
klass = inst.__class__
self.assertEqual(klass.__name__, 'MyClass')
self.assertEqual(klass.__module__, 'Products.MyProduct.MyClass')
self.assertEqual(klass.product_name, 'MyProduct')
def test_Broken_instance___getstate___raises_useful_exception(self):
# see http://www.zope.org/Collectors/Zope/2157
from OFS.Uninstalled import Broken
from OFS.Uninstalled import BrokenClass
OID = '\x01' * 8
inst = Broken(self, OID, ('Products.MyProduct.MyClass', 'MyClass'))
try:
dict = inst.__getstate__()
except SystemError, e:
self.failUnless('MyClass' in str(e), str(e))
else:
self.fail("'__getstate__' didn't raise SystemError!")
def test_Broken_instance___getattr___allows_persistence_attrs(self):
from OFS.Uninstalled import Broken
from OFS.Uninstalled import BrokenClass
OID = '\x01' * 8
PERSISTENCE_ATTRS = ["_p_changed",
"_p_jar",
"_p_mtime",
"_p_oid",
"_p_serial",
"_p_state",
]
PERSISTENCE_METHODS = ["_p_deactivate",
"_p_activate",
"_p_invalidate",
"_p_getattr",
"_p_setattr",
"_p_delattr",
]
inst = Broken(self, OID, ('Products.MyProduct.MyClass', 'MyClass'))
for attr_name in PERSISTENCE_ATTRS:
attr = getattr(inst, attr_name) # doesn't raise
for meth_name in PERSISTENCE_METHODS:
meth = getattr(inst, meth_name) # doesn't raise
def test_suite():
suite = unittest.TestSuite()
suite.addTest( unittest.makeSuite(TestsOfBroken))
return suite
def main():
unittest.main(defaultTest='test_suite')
if __name__ == '__main__':
main()
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