Closed gelbi123 closed 4 months ago
@gelbi123 This is not really a problem with zope.interface.
You appear to be storing references to the interface in the ZODB. When the code for a class is no longer available, the ZODB loads it as an instance of ZODB.broken.Broken
. This error happens because the Broken
instance cannot function where an interface is expected.
In general with the ZODB you should remove all persistent references to a class before you remove the class from the code. If it's already too late, you can use https://pypi.org/project/zodbupdate/ to convert those references to a different class.
zope.interface could perhaps be improved to show a clearer error message in this case, where it gets an object that is not an interface where it is expecting an interface.
@davisagli thanks for your reply and sorry for my late reply!
You are right, it is not a problem with zope.interface itself.
Its a class implementing something which is not an interface.
Or in that case a object (folder) which should direclty provide ZODB.broken.Broken which is also not an interface.
But I wanted to mention that this behaviour could be a timebomb in the case of the following szenario:
Running a complex system with multiple zope instances coupled via ZEO. Then a
folder will be marked on InstanceA, all requests on other
instances (with the shared Data.fs) could lead to this error if the traverse
mechanism went trough the marked folder and the source code isn't installed.
This was approximately the case in my(our) setup.
In that case I would expect that the code depending on the marker interface
will not work but not all the other code.
Can you recommend a better place to mention that?
Actually a solution might be to "fake" the existence of the old Interface
derived class.
If you create somewhere in your code a fakemodule.py
containing the missing marker interface and use a technique like here
https://github.com/plone/plone.app.upgrade/blob/93157548a8b616b44e8fcc31f215806df7648863/plone/app/upgrade/utils.py#L209
to alias it to the old place, it should be possible to load the code in question.
Then you can develop code to find objects with the marker and use zope.interface.noLongerProvides to remove it.
@jensens Thank you for sharing this technique.
In my case it wasn't actually the problem to
get rid of the marker interface. On the Instance
with the source code I could unmark it
via the ZMI Interface tab. Instead of that I simple
installed the source code on all the other instances.
The problem was more that the added marker interface
causes a lot of broken requests(TypeError) on instances without
the source code.
To prevent this I developed a customized InterfaceClass object
which should be used as a base class for persistent marker
interfaces. Now when the marker interface gets unpickled and
the source code isn't found, a placeholder will be generated
(like broken objects).
@gelbi123 As your problem seems to be solved, I am closing this issue now.
Dear Zope-Developer Team,
following issue appeared:
What I did:
I created a MarkerInterface
and marked a ZMI-Folder @root with this Interface (via Interfaces-tab).
Now I removed the source file where the markerinterface is declared and restarted the instance. The restart works fine but EVERY request will lead now to the error described above.
Issue research:
File: declarations.py
Here some informations about the sequence parameter from debug session
What version of Python and Zope/Addons I am using: