Miserable bug day. Rdflib integration ==================
Ok, now I'm ready to start the rdflib integration into this boilerplate product:
# Import of the needed rdflib functionality from rdflib.InMemoryTripleStore import InMemoryTripleStore from rdflib.Literal import Literal from rdflib.Namespace import Namespace
And RopeProduct
inherits from InMemoryTripleStore
. That should
probably be changed to some b-tree based zodb storage, but for the
moment it is ok:
class RopeProduct(Implicit, Persistent, RoleManager, PropertyManager, Item, InMemoryTripleStore):
Ouch, that turned into a two hour obscure bug hunt. I finally figured
out that rdflib uses the super()
function extensively, which doesn't
work for some reason. I started zope within the python console
(zopectl debug
in zope 2.7 at least) and tried to get at my test
rope object. It presented itself as a
Acquisition.ImplicitAcquirerWrapper
object. Calling super()
on
that thingy won't work. Now what...
I did put from Acquisition import Implicit
, prompted by the
ZDG. I'm seeing some talk about "automatically wrapping the object in
its context". Apparently the super()
method bugs the wrapper object
instead of the RopeProduct object... Ok, I'll switch to explicit
acquisition to see whether that works:
from Acquisition import Explicit
That seems to work. Now for some testing: Most of it didn't seem to
work. And once something was wrong I got an unclear
exceptions.TypeError
error message: "TypeError: function takes
exactly 2 arguments (1 given)". After another hour I figured out that
the error display function was having fits. Probable cause is of
course some of the rdflib stuff that I subclassed from. But another
two hours didn't help, so I decided to attach a rdflib store to a
local variable.
This hack worked. I can now add a triple and view it. A lot isn't right yet, but:
# Standard zope inclusions: acquisition, persistence in the zope # database, access control. Rope isn't a folder containing other # things at the moment, so we'll make it into a simple item. from Acquisition import Explicit from Globals import Persistent from AccessControl.Role import RoleManager from OFS.SimpleItem import Item # Extra: property tab in the management interface and security # declarations plus instantiation. from OFS.PropertyManager import PropertyManager from AccessControl import ClassSecurityInfo from Globals import InitializeClass # Import of the needed rdflib functionality from rdflib.InMemoryTripleStore import InMemoryTripleStore from rdflib.Literal import Literal from rdflib.Namespace import Namespace class RopeProduct(Explicit, Persistent, RoleManager, PropertyManager, Item): """ Rope product class. Makes rdflib available to zope. """ meta_type = 'Rope' # Required by Item baseclass security = ClassSecurityInfo() manage_options = RoleManager.manage_options + ( {'label': 'View', 'action': 'index_html'}, ) ns_rdf = Namespace("http://www.w3.org/1999/02/22-rdf-syntax-ns#") store = InMemoryTripleStore() def __init__(self, id): self.id = id # id needed by Item baseclass security.declarePublic('index_html') def index_html(self): """ Dummy index page. """ header = """ Role product instance <p>My id is %s</p> """ % self.id footer = """ """ main = '' for s,p,o in self.store.triples((None,None,None)): main += '%s %s %s<br>' % (s,p,o) return header + main + footer security.declarePublic('add') def add(self, s, p, o): """Adds a triple to the store""" self.store.add((self.ns_rdf[s], self.ns_rdf[p], self.ns_rdf[o])) def addForm(unknown): # I couldn't really find what 'unknown' does... """ Returns an html form used to instantiate a RopeProduct instance. """ return """ Add Rope id: <br> """ def addRope(dispatcher, id): """ Create a new Rope and add it to myself. """ rope = RopeProduct(id) dispatcher.Destination()._setObject(id,rope) InitializeClass(RopeProduct)
Well, I'm going to relax for a week.
My name is Reinout van Rees and I program in Python, I live in the Netherlands, I cycle recumbent bikes and I have a model railway.
Most of my website content is in my weblog. You can keep up to date by subscribing to the automatic feeds (for instance with Google reader):