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):