task: metadata: install: pip install -e .[test]
patch: diff --git a/CHANGES.rst b/CHANGES.rst
index 3c49567..7b8a73a 100644
--- a/CHANGES.rst
+++ b/CHANGES.rst
@@ -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)
 ==================
diff --git a/src/zope/component/interface.py b/src/zope/component/interface.py
index 35fecbe..2317149 100644
--- a/src/zope/component/interface.py
+++ b/src/zope/component/interface.py
@@ -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__)
@@ -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):
@@ -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()
@@ -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
 
 

problem_statement: The zcml directive interface registers the interfaces always in the global registry
In https://bugs.launchpad.net/zope.component/+bug/1089340, @agroszer reported:

> Whereas the other registrations use

``` python
sm = zope.component.getSiteManager()
sm.register...
```

`zope.component.interface.provideInterface` does:

``` python
gsm = zope.component.getGlobalSiteManager()
gsm.registerUtility...
```

what does not fit with `z3c.baseregistry` well.

repo: zopefoundation/zope.component
test_cmd: pytest --no-header -rA --tb=line --color=no -p no:cacheprovider -W ignore::DeprecationWarning
test_patch: diff --git a/src/zope/component/tests/test_interface.py b/src/zope/component/tests/test_interface.py
index e7580e0..f7d266a 100644
--- a/src/zope/component/tests/test_interface.py
+++ b/src/zope/component/tests/test_interface.py
@@ -15,6 +15,7 @@
 """
 import unittest
 
+# pylint:disable=inherit-non-class,blacklisted-name
 
 class Test_provideInterface(unittest.TestCase):
 
@@ -71,7 +72,32 @@ class Test_provideInterface(unittest.TestCase):
         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):
@@ -171,6 +197,41 @@ class Test_searchInterface(unittest.TestCase):
         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):