Skip to content

Commit

Permalink
Merge pull request #61 from zopefoundation/issue10
Browse files Browse the repository at this point in the history
Fix provideInterface et al to use the current site manager.
  • Loading branch information
jamadden committed Mar 19, 2021
2 parents 950b4a4 + 7a1d3c5 commit 4513462
Show file tree
Hide file tree
Showing 3 changed files with 82 additions and 8 deletions.
8 changes: 8 additions & 0 deletions CHANGES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,14 @@

See `issue 51 <https://github.com/zopefoundation/zope.component/issues/51>`_.

- Fix ``zope.interface.interface.provideInterface`` and the various
search and query methods to use the current site manager instead of
always using the global site manager. (``provideInterface`` is
called implicitly when registering components from ZCML.) The search
and query methods continue to return interfaces registered in base
site managers.

See `issue 10 <https://github.com/zopefoundation/zope.component/issues/51>`_.

4.6.2 (2020-07-03)
==================
Expand Down
19 changes: 12 additions & 7 deletions src/zope/component/interface.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,19 @@
from zope.interface import alsoProvides
from zope.interface.interfaces import IInterface

from zope.component.globalregistry import getGlobalSiteManager
from zope.interface.interfaces import ComponentLookupError
from zope.component._api import getSiteManager
from zope.component._api import queryUtility
from zope.component._compat import CLASS_TYPES


def provideInterface(id, interface, iface_type=None, info=''):
""" Mark 'interface' as a named utilty providing 'iface_type'.
"""
Mark *interface* as a named utility providing *iface_type*'.
.. versionchanged:: 5.0.0
The named utility is registered in the current site manager.
Previously it was always registered in the global site manager.
"""
if not id:
id = "%s.%s" % (interface.__module__, interface.__name__)
Expand All @@ -40,8 +45,8 @@ def provideInterface(id, interface, iface_type=None, info=''):
else:
iface_type = IInterface

gsm = getGlobalSiteManager()
gsm.registerUtility(interface, iface_type, id, info)
site_man = getSiteManager()
site_man.registerUtility(interface, iface_type, id, info)


def getInterface(context, id):
Expand Down Expand Up @@ -74,8 +79,8 @@ def searchInterfaceIds(context, search_string=None, base=None):


def searchInterfaceUtilities(context, search_string=None, base=None):
gsm = getGlobalSiteManager()
iface_utilities = gsm.getUtilitiesFor(IInterface)
site_man = getSiteManager()
iface_utilities = site_man.getUtilitiesFor(IInterface)

if search_string:
search_string = search_string.lower()
Expand All @@ -86,7 +91,7 @@ def searchInterfaceUtilities(context, search_string=None, base=None):
res = [iface_util for iface_util in iface_utilities
if iface_util[1].isOrExtends(base)]
else:
res = [iface_util for iface_util in iface_utilities]
res = list(iface_utilities)
return res


Expand Down
63 changes: 62 additions & 1 deletion src/zope/component/tests/test_interface.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
"""
import unittest

# pylint:disable=inherit-non-class,blacklisted-name

class Test_provideInterface(unittest.TestCase):

Expand Down Expand Up @@ -71,7 +72,32 @@ class IFoo(Interface):
self._callFUT('foo', IFoo)
self.assertTrue(IInterface.providedBy(IFoo))
registered = gsm.getUtility(IInterface, name='foo')
self.assertTrue(registered is IFoo)
self.assertIs(registered, IFoo)

def test_register_in_current_site(self):
from zope.component._api import getSiteManager
from zope.component.globalregistry import getGlobalSiteManager
from zope.interface.registry import Components
from zope.interface import Interface
from zope.interface.interfaces import IInterface

class IFoo(Interface):
pass

site_man = Components()
def get(_context=None):
return site_man
getSiteManager.sethook(get)
self.addCleanup(getSiteManager.reset)

self._callFUT('foo', IFoo)

self.assertIs(site_man.getUtility(IInterface, name='foo'),
IFoo)
self.assertIsNone(
getGlobalSiteManager().queryUtility(IInterface, name='foo')
)



class Test_getInterface(unittest.TestCase):
Expand Down Expand Up @@ -171,6 +197,41 @@ class IBar(Interface):
gsm.registerUtility(IBar, IInterface, 'bar')
self.assertEqual(self._callFUT(object(), base=IBase), [IFoo])

def test_hit_in_current_site(self):
from zope.component._api import getSiteManager
from zope.component.globalregistry import getGlobalSiteManager
from zope.interface.registry import Components
from zope.interface import Interface
from zope.interface.interfaces import IInterface

class ILocal(Interface):
pass

class IGlobal(Interface):
pass

gsm = getGlobalSiteManager()
site_man = Components(bases=(gsm,))
def get(_context=None):
return site_man
getSiteManager.sethook(get)
self.addCleanup(getSiteManager.reset)


gsm.registerUtility(IGlobal, IInterface, 'foo')
site_man.registerUtility(ILocal, IInterface, 'bar')

result = self._callFUT(None)
self.assertEqual(len(result), 2)
self.assertIn(ILocal, result)
self.assertIn(IGlobal, result)

getSiteManager.reset()

result = self._callFUT(None)
self.assertEqual(len(result), 1)
self.assertIn(IGlobal, result)


class Test_searchInterfaceIds(unittest.TestCase):

Expand Down

0 comments on commit 4513462

Please sign in to comment.