-
Notifications
You must be signed in to change notification settings - Fork 69
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
BaseAdapterRegistry.subscribe/unsubscribe non-symmetric updating _provided
, leaves orphan entries
#227
Labels
Comments
jamadden
added a commit
that referenced
this issue
Mar 1, 2021
Add extensive tests for this. Fixes #224. Also adds test for, and fixes #227 Add BAR.rebuild() to fix the refcount issue, and to change datatypes. It works by using the new methods allRegistrations() and allSubscriptions() to re-create the data in new data structures. This makes fresh calls to subscribe() and register(). I went this way instead of trying to manually walk the data structures and create them because the logic in those methods is fully tested.
jamadden
added a commit
that referenced
this issue
Mar 3, 2021
Add extensive tests for this. Fixes #224. Also adds test for, and fixes #227 Add BAR.rebuild() to fix the refcount issue, and to change datatypes. It works by using the new methods allRegistrations() and allSubscriptions() to re-create the data in new data structures. This makes fresh calls to subscribe() and register(). I went this way instead of trying to manually walk the data structures and create them because the logic in those methods is fully tested.
netbsd-srcmastr
referenced
this issue
in NetBSD/pkgsrc
Apr 14, 2021
5.3.0 (2020-03-21) ================== - No changes from 5.3.0a1 5.3.0a1 (2021-03-18) ==================== - Improve the repr of ``zope.interface.Provides`` to remove ambiguity about what is being provided. This is especially helpful diagnosing IRO issues. - Allow subclasses of ``BaseAdapterRegistry`` (including ``AdapterRegistry`` and ``VerifyingAdapterRegistry``) to have control over the data structures. This allows persistent implementations such as those based on ZODB to choose more scalable options (e.g., BTrees instead of dicts). See `issue 224 <https://github.com/zopefoundation/zope.interface/issues/224>`_. - Fix a reference counting issue in ``BaseAdapterRegistry`` that could lead to references to interfaces being kept around even when all utilities/adapters/subscribers providing that interface have been removed. This is mostly an issue for persistent implementations. Note that this only corrects the issue moving forward, it does not solve any already corrupted reference counts. See `issue 227 <https://github.com/zopefoundation/zope.interface/issues/227>`_. - Add the method ``BaseAdapterRegistry.rebuild()``. This can be used to fix the reference counting issue mentioned above, as well as to update the data structures when custom data types have changed. - Add the interface method ``IAdapterRegistry.subscribed()`` and implementation ``BaseAdapterRegistry.subscribed()`` for querying directly registered subscribers. See `issue 230 <https://github.com/zopefoundation/zope.interface/issues/230>`_. - Add the maintenance method ``Components.rebuildUtilityRegistryFromLocalCache()``. Most users will not need this, but it can be useful if the ``Components.utilities`` registry is suspected to be out of sync with the ``Components`` object itself (this might happen to persistent ``Components`` implementations in the face of bugs). - Fix the ``Provides`` and ``ClassProvides`` descriptors to stop allowing redundant interfaces (those already implemented by the underlying class or meta class) to produce an inconsistent resolution order. This is similar to the change in ``@implementer`` in 5.1.0, and resolves inconsistent resolution orders with ``zope.proxy`` and ``zope.location``. See `issue 207 <https://github.com/zopefoundation/zope.interface/issues/207>`_.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
While working on #224 I noticed that there were no tests for
BaseAdapterRegistry._provided
(which keeps a map of{interface: reference count}
of interfaces it knows about in order to add them as "extendors" to the AdapterLookup classes).The
register
method increments this count and stores it:zope.interface/src/zope/interface/adapter.py
Lines 154 to 157 in bf0de08
As does the
subscribe
method:zope.interface/src/zope/interface/adapter.py
Lines 247 to 251 in bf0de08
The inverse of
register
,unregister
, decrements this count and either stores it, or, if it hits 0, removes it:zope.interface/src/zope/interface/adapter.py
Lines 219 to 224 in bf0de08
However, the inverse of
subscribe
,unsubscribe
, appears to have a bug. It decrements the count, but only if it hits zero is it removed. It never stores it, which means it can never hit 0 just by unsubscribing.zope.interface/src/zope/interface/adapter.py
Lines 305 to 309 in bf0de08
Making
unsubscribe
store the decremented value doesn't break any tests (and fixes the tests I was adding). Because the high-level classComponents
automatically both registers and subscribes utilities, it's fairly easy to end up with orphaned entries in_provided
.Here, I'll define an interface and class and register it both as the default (unnamed) and a named utility for the same interface.
Now, because
IFoo
was both provided and subscribed twice, it has a refcount of 4, and the two objects show up once each in_adapters
and_subscribers
of the adapter registry:Now we can unregister both utilities, and their entries will be gone from
_adapters
and_subscribers
:But
IFoo
is still in_provided
because of this issue:Because of the way
unsubscribe
calculates the delta (removing all equal objects) if I register the same identical object (which is if course equal to itself) as both the named and unnamed utility, this appears to work. That is,_provided
has no remaining references toIFoo
.When using non-equal objects, this only works (empty
_provided
) if I makeunsubscribe
store the decremented value. The equal object case still works then.The text was updated successfully, but these errors were encountered: