zope.interface icon indicating copy to clipboard operation
zope.interface copied to clipboard

Assigning a bases base does not 'update' parent registries

Open agroszer opened this issue 2 years ago • 1 comments

BUG/PROBLEM REPORT (OR OTHER COMMON ISSUE)

On latest master, linux.

Basically I'm setting a base's to a base that has registrations. comp.getUtilitiesFor is expected to return all registrations, but it does so only after re-setting comp.__bases__.

Let my code speak for me:

import unittest


class Dummy:
    text = ''

    def __init__(self, text):
        self.text = text


class ComponentsTestsZZZ(unittest.TestCase):

    def _getTargetClass(self):
        from zope.interface.registry import Components
        return Components

    def _makeOne(self, name='test', *args, **kw):
        return self._getTargetClass()(name, *args, **kw)

    def test_zzz(self):
        base1 = self._makeOne('base1')
        base2 = self._makeOne('base2')
        comp = self._makeOne()
        comp.__bases__ = (base1, base2)

        from zope.interface.declarations import InterfaceClass

        class IFoo(InterfaceClass):
            pass
        ifoo = IFoo('IFoo')

        comp.registerUtility(Dummy('comp'), ifoo, name='comp')
        base1.registerUtility(Dummy('base1'), ifoo, name='base1')
        base2.registerUtility(Dummy('base2'), ifoo, name='base2')

        res = list(comp.getUtilitiesFor(ifoo))
        self.assertEqual(
            sorted([r[0] for r in res]),
            ['base1', 'base2', 'comp']
        )

        base21 = self._makeOne('base21')
        base21.registerUtility(Dummy('base21'), ifoo, name='base21')

        base2.__bases__ = (base21,)

        res = list(comp.getUtilitiesFor(ifoo))
        # fails with 
        #   ['base1', 'base2', 'comp']
        self.assertEqual(
            sorted([r[0] for r in res]),
            ['base1', 'base2', 'base21', 'comp']
        )

        comp.__bases__ = (base1, base2)

        res = list(comp.getUtilitiesFor(ifoo))
        self.assertEqual(
            sorted([r[0] for r in res]),
            ['base1', 'base2', 'base21', 'comp']
        )

agroszer avatar May 03 '22 13:05 agroszer

Looks sofar comp.utilities._registry.ro does not get updated

agroszer avatar May 03 '22 14:05 agroszer