Skip to content

Commit

Permalink
Set parent pointers
Browse files Browse the repository at this point in the history
  • Loading branch information
lrowe committed Nov 1, 2011
1 parent fbf0a6a commit 4986214
Show file tree
Hide file tree
Showing 4 changed files with 76 additions and 1 deletion.
8 changes: 7 additions & 1 deletion src/OFS/Application.py
Expand Up @@ -33,6 +33,7 @@

from zope.globalrequest import getRequest
from zope.interface import implements
from zope.location.interfaces import ILocation

import Folder
import misc_
Expand All @@ -51,13 +52,18 @@ class Application(ApplicationDefaultPermissions,
):
"""Top-level system object"""

implements(IApplication)
implements(
IApplication,
ILocation,
)

security = ClassSecurityInfo()

title = 'Zope'
__defined_roles__ = ('Manager', 'Anonymous', 'Owner')
__error_log__ = None
__name__ = None
__parent__ = None
isTopLevelPrincipiaApplicationObject = 1

manage_options=((
Expand Down
29 changes: 29 additions & 0 deletions src/OFS/ObjectManager.py
Expand Up @@ -49,11 +49,14 @@
from webdav.Lockable import ResourceLockedError
from webdav.NullResource import NullResource
from zExceptions import BadRequest
from zope.interface import alsoProvides
from zope.interface import implements
from zope.component.interfaces import ComponentLookupError
from zope.event import notify
from zope.lifecycleevent import ObjectAddedEvent
from zope.lifecycleevent import ObjectRemovedEvent
from zope.location.interfaces import IContained
from zope.location.interfaces import ILocation
from zope.container.contained import notifyContainerModified

from OFS.CopySupport import CopyContainer
Expand Down Expand Up @@ -274,10 +277,36 @@ def filtered_meta_types(self, user=None):

_checkId = checkValidId

def _contained(self, id, object):
if ILocation.providedBy(object):
if not ILocation.providedBy(self):
raise AssertionError(
"Cannot add an object providing ILocation to an "
"unlocated container."
)
if not IContained.providedBy(object):
alsoProvides(object, IContained)
oldparent = getattr(aq_base(object), '__parent__', None)
if aq_base(self) is not aq_base(oldparent):
aq_base(object).__parent__ = aq_base(self)
# __name__ assumed to be a property or set elsewhere

def _setOb(self, id, object):
self._contained(id, object)
setattr(self, id, object)

def _uncontained(self, id):
obj = self._getOb(id, _marker)
if obj is not _marker:
if IContained.providedBy(obj):
try:
aq_base(obj).__parent__ = None
except AttributeError:
# No need to fail if we can't set these
pass

def _delOb(self, id):
self._uncontained(id)
delattr(self, id)

def _getOb(self, id, default=_marker):
Expand Down
6 changes: 6 additions & 0 deletions src/OFS/tests/testApplication.py
Expand Up @@ -102,6 +102,12 @@ def test___bobo_traverse__attribute_key_miss_R_M_not_GET_POST(self):
self.assertTrue(isinstance(result, NullResource))
self.assertTrue(aq_parent(aq_inner(result)) is app)

def test_name_parent(self):
app = self._makeOne()
self.assertEquals(app.__name__, None)
self.assertEquals(app.__parent__, None)


def _noWay(self, key, default=None):
raise KeyError(key)

Expand Down
34 changes: 34 additions & 0 deletions src/OFS/tests/testObjectManager.py
Expand Up @@ -13,6 +13,7 @@
from zExceptions import BadRequest
from zope.component.testing import PlacelessSetup
from zope.interface import implements
from zope.location.interfaces import ILocation
from Zope2.App import zcml

from OFS.interfaces import IItem
Expand Down Expand Up @@ -70,6 +71,11 @@ class ObjectManagerWithIItem(ObjectManager):
implements(IItem)


class ObjectManagerWithILocation(ObjectManager, SimpleItem):
"""A located ObjectManager."""
implements(ILocation)


class ObjectManagerTests(PlacelessSetup, unittest.TestCase):

def setUp(self):
Expand Down Expand Up @@ -478,7 +484,35 @@ def test_list_imports(self):
self.assertTrue(filename.endswith('.zexp') or
filename.endswith('.xml'))


class LocatedObjectManagerTests(ObjectManagerTests):
def _getTargetClass(self):
return ObjectManagerWithILocation

def test_container_must_provide_ILocation(self):
unlocated = ObjectManager()
located = self._makeOne('located')
self.assertRaises( AssertionError
, unlocated._setObject, 'located', located )

def test_set_name_parent(self):
root = self._makeOne()
one = self._makeOne()
one._setId('one')
root._setObject('one', one, set_owner=0)
self.assertEquals(aq_base(root), aq_base(aq_base(one).__parent__))
self.assertEquals(one.__name__, 'one')

def test_delete(self):
root = self._makeOne()
one = self._makeOne('one')
root._setObject('one', one, set_owner=0)
root._delObject('one')
self.assertEquals(aq_base(one).__parent__, None)


def test_suite():
suite = unittest.TestSuite()
suite.addTest( unittest.makeSuite( ObjectManagerTests ) )
suite.addTest( unittest.makeSuite( LocatedObjectManagerTests ) )
return suite

0 comments on commit 4986214

Please sign in to comment.