[pypy-svn] r33615 - in pypy/dist/pypy/lib/pyontology: . test

ale at codespeak.net ale at codespeak.net
Mon Oct 23 19:48:05 CEST 2006


Author: ale
Date: Mon Oct 23 19:48:04 2006
New Revision: 33615

Added:
   pypy/dist/pypy/lib/pyontology/test/testont.rdf
Modified:
   pypy/dist/pypy/lib/pyontology/pyontology.py
   pypy/dist/pypy/lib/pyontology/test/test_ontology.py
   pypy/dist/pypy/lib/pyontology/test/test_sparql.py
Log:
progress on the refactoring.


Modified: pypy/dist/pypy/lib/pyontology/pyontology.py
==============================================================================
--- pypy/dist/pypy/lib/pyontology/pyontology.py	(original)
+++ pypy/dist/pypy/lib/pyontology/pyontology.py	Mon Oct 23 19:48:04 2006
@@ -1,3 +1,4 @@
+import autopath
 from rdflib import Graph, URIRef, BNode, Literal
 from logilab.constraint import  Repository, Solver
 from logilab.constraint.fd import  Expression, FiniteDomain as fd
@@ -86,7 +87,8 @@
         self.finished = False
         self.value = None
         self.type = []
-
+        self.setValues(values)
+        
     def finish(self, variables, glob_constraints):
         # The finish method constructs the constraints
         if not self.finished:
@@ -117,7 +119,7 @@
                 # if the base class is a Restriction we shouldnt add the constraints to the store
                 if not isinstance(cls, Restriction):
                     self.domains.update(dom)
-                    self.constraint.extend(constraint)
+                self.constraint.extend(constraint)
                 # initialise the constraint with this class as the first argument
                 for constraint in cls.un_constraint:
                     dom, constraints = constraint(self.name, variables[cls.property], cls.value)
@@ -142,7 +144,7 @@
         return item in self.values
 
     def copy(self):
-        return self
+        return self.__class__(self.name, self.uri, self.getValues())
     
     def size(self):
         return len(self.values)
@@ -171,8 +173,9 @@
         self.values[value] = True
 
     def getValues(self):
-        for key in self.values:
-            yield key
+        #for key in self.values:
+        #    yield key
+        return self.values.keys()
         
     def __iter__(self):
         return iter(self.values.keys())
@@ -184,17 +187,26 @@
 class FixedClassDomain(ClassDomain):
 
     finished = True 
-    fixed = True
- 
-    def removeValues(self, values):
-        raise ConsistencyFailure("Cannot remove values from a FixedClassDomain")
 
-    def removeValue(self, value):
-        raise ConsistencyFailure("Cannot remove values from a FixedClassDomain")
+    def __init__(self, name='', uri=None, values = [], bases = []):
+        ClassDomain.__init__(self, name, uri, values, bases)
+        self.fixed = True
 
-    def setValues(self, values):
-        if not self.values:
-            self.values = dict.fromkeys(values)
+    def addValue(self, value):
+        if self.fixed :
+            raise ValueError("Fixed classes can only add vulues during initialisation")
+        else:
+            ClassDomain.addValue(self, value)
+
+#    def removeValues(self, values):
+#        raise ConsistencyFailure("Cannot remove values from a FixedClassDomain")
+
+#    def removeValue(self, value):
+#        raise ConsistencyFailure("Cannot remove values from a FixedClassDomain")
+
+#    def setValues(self, values):
+#        if not self.values:
+#            self.values = dict.fromkeys(values)
         #else:
             #raise ConsistencyFailure
 
@@ -250,7 +262,12 @@
         self.un_constraint = []
         self.in_constraint = []
         self.bases = []
+        self.name_uri = uri
         self.finished = True
+        self.setValues(values)
+
+    def copy(self):
+        return Property(self.name, self.uri, list(self.getValues()))
 
     def finish(self, var, constraints):
         return var, constraints
@@ -263,7 +280,9 @@
         res = []
         for k,vals in items:
             for v in vals:
-                yield (k,v)
+                #yield (k,v)
+                res.append((k,v))
+        return res
 
     def getValuesPrKey(self, key= None):
         if key:
@@ -287,6 +306,10 @@
                 self._dict.pop(k)
             else:
                 self._dict[k] = [ x for x in vals if x != v]
+                if not self._dict[k]:
+                    self._dict.pop(k)
+        if not self._dict:
+            raise ConsistencyFailure
 
     def __contains__(self, (cls, val)):
         if not cls in self._dict:
@@ -383,10 +406,15 @@
                 The class is saved in the restrictions cls attribute
         """
     uri = URIRef(namespaces['owl'] + "#Restriction")
-    def __init__(self, name='', values=[], bases = []):
-        ClassDomain.__init__(self, name, values, bases)
+    def __init__(self, name='', uri='', values=[], bases = []):
+        ClassDomain.__init__(self, name, uri, values, bases)
         self.property = None
 
+    def copy(self):
+        cc = ClassDomain.copy(self)
+        cc.property = self.property
+        return cc
+
 def Types(typ):
     class Type(ClassDomain):
         def __contains__(self, item):
@@ -440,11 +468,11 @@
         self.var2ns ={}
         self.nr_of_triples = 0
         self.time = time.time()
-        for pr in builtin_voc:
-            name = self.mangle_name(pr)
+#        for pr in builtin_voc:
+#            name = self.mangle_name(pr)
             # Instantiate ClassDomains to record instances of the types
-            name = name + "_type"
-            self.variables[name] = ClassDomain(name, pr)
+#            name = name + "_type"
+#            self.variables[name] = ClassDomain(name, pr)
 
     def add(self, triple):
         self.graph.add(triple)
@@ -494,7 +522,7 @@
 
         triples = where.GroupGraphPattern[0].Triples
         new = []
-
+        vars = []
         for trip in triples:
             case = 0
             inc = 1
@@ -507,7 +535,9 @@
                     uri = prefixes[item[0].NCNAME_PREFIX[0]] + item[0].NCNAME[0]
                     newtrip.append(URIRef(uri))
                 elif item.VAR1:
-                    newtrip.append(URIRef('query_'+item.VAR1[0][0]))
+                    var_uri = URIRef('query_'+item.VAR1[0][0])
+                    newtrip.append(var_uri)
+                    vars.append(var_uri)
                     case += trip_.index(item) + inc
                     inc = 2
                 else:
@@ -515,7 +545,7 @@
             newtrip.append(case)
             new.append(newtrip)
         constrain = where.GroupGraphPattern[0].Constraint
-        return new, prefixes, resvars, constrain
+        return new, prefixes, resvars, constrain, vars
 
 # There are 8 ways of having the triples in the query, if predicate is not a builtin owl predicate
 #
@@ -532,7 +562,9 @@
 #
 
     def sparql(self, query):
-        new, prefixes, resvars, constrain = self._sparql(query)
+        new, prefixes, resvars, constrain, vars = self._sparql(query)
+        query_dom = {}
+        query_constr = []
         for trip in new:
             case = trip.pop(-1)
             if case == 0:
@@ -559,18 +591,22 @@
                 else:
                     obj = trip[2]
                 prop = self.variables[prop_name]
-                prop.setValues(list(self.variables['rdf_Property_type'].getValues()))
-                # Get all properties by looking at 'rdf_Property_type'
+                prop.setValues(list(self.variables['rdf_Property'].getValues()))
+                # Get all properties by looking at 'rdf_Property'
                 # add a constraint trip[0] in domains[prop] and trip[2] in domains[prop].getValuesPrKey(trip[0])
                 self.constraints.append(PropertyConstrain(prop_name, indi, obj))
 
             elif case == 3:
                 #  search for s in p
                 prop = self.make_var(None, trip[1])
-                indi = self.variables[self.make_var(Individual, trip[0])]
+                #indi = self.variables[self.make_var(
+                indi = Individual( self.mangle_name(trip[0]), trip[0])
                 p_vals = self.variables[prop].getValuesPrKey(indi)
                 var = self.make_var(Thing, trip[2])
                 self.variables[var].setValues((p_vals))
+                if [dom for dom in self.variables.values() if isinstance(dom, Individual)]: 
+                    import pdb
+                    pdb.set_trace()
             elif case == 4:
                 #  for all p's return p[0] if p[1]==o 
                  
@@ -579,7 +615,7 @@
                 sub = self.variables[sub_name]
                 sub.setValues(list(self.variables['owl_Thing'].getValues()))
                 prop = self.variables[prop_name]
-                prop.setValues(list(self.variables['rdf_Property_type'].getValues()))
+                prop.setValues(list(self.variables['rdf_Property'].getValues()))
                 obj_name = self.mangle_name(trip[2])
                 if  obj_name in self.variables:
                     obj = self.variables[self.mangle_name(trip[2])]
@@ -601,9 +637,17 @@
             elif case == 7:
                 #  for all p's return p.getvalues 
                 pass
+        # call finish on the variables in the query
+        for v in vars:
+            query_dom, query_constr = self.variables[self.mangle_name(v)].finish(self.variables, self.constraints) #query_dom, query_constr)
+        # Build a repository with the variables in the query
+        #dom = dict([(self.mangle_name(v),self.variables[self.mangle_name(v))
+        #             for v in vars])
+        # solve the repository and return the solution
+#        rep = Repository(query_dom.keys(), query_dom, query_constr)
+#        return Solver().solve(rep)
 
-        self.consistency()
-
+        return self.solve(verbose=6)
     
     def consider_triple(self,(s, p, o)):
         if (s, p, o) in self.seen:
@@ -623,15 +667,18 @@
             #predicate is one of builtin OWL or rdf predicates
             pred = getattr(self, func)
             res = pred(s, o)
-            #avar = self.make_var(ClassDomain, s)
+        #avar = self.make_var(ClassDomain, s)
         #else:
         avar = self.make_var(Property, p)
         # Set the values of the property p to o
-        self.type(s, Thing_uri)
-        sub = self.make_var(Thing, s)
+#        self.type(s, Thing_uri)
+        sub = self.mangle_name(s)
         if type(o) == URIRef:
-            obj = self.make_var(Thing, o)
-            val = Individual(obj,o)
+            obj = self.mangle_name(o)
+            if obj in self.variables:
+                val = self.variables[obj]
+            else:
+                val = Individual(obj, o)
         else:
             val = o
         propdom = self.variables[avar]
@@ -672,17 +719,16 @@
  
     def make_var(self, cls=fd, a=''):
         log("make_var %r,%r" %(cls,a))
-        if a in builtin_voc:
-           cls = builtin_voc[a]
         var = self.mangle_name(a)
         if not cls:
             return var
         if not var in self.variables:
+            if a in builtin_voc and issubclass(builtin_voc[a], ClassDomain):
+                cls = builtin_voc[a]
             cls = self.variables[var] = cls(var, a)
             if cls.constraint:
                 log("make_var constraint 1 %r,%r" %(cls,a))
                 self.constraints.extend(cls.constraint)
-        # XXX needed because of old style classes
         elif not cls == self.variables[var].__class__ and issubclass(cls, self.variables[var].__class__):
             vals = self.variables[var].getValues()
             tmp = cls(var, a)
@@ -737,32 +783,40 @@
 
     def type(self, s, var):
         log("type %r %r"%(s, var))
-        avar = self.make_var(ClassDomain, var)
         if not var in builtin_voc :
-            # var is not one of the builtin classes -> it is a Thing
-            self.type(s, Thing_uri)
-            svar = self.make_var(Individual, s)
-            self.variables[svar].type.append(avar) 
+            # var is not one of the builtin classes -> it is a Class 
+            avar = self.make_var(ClassDomain, var)
+            #self.type(s, Thing_uri)
+            svar = self.mangle_name(s)
+            s_type = Individual(svar, s)
+            self.variables[svar] = s_type
+            if type(self.variables[avar]) != FixedClassDomain:
+                self.variables[avar].addValue(s_type)
             self.constraints.append(MemberConstraint(svar, avar))
         else:
             # var is a builtin class
             cls = builtin_voc[var]
+            avar = self.make_var(ClassDomain, var)
+            if cls in [Thing]:
+                svar = self.mangle_name(s)
+                self.variables[avar].addValue(Individual(svar, s))
+                return
             svar = self.make_var(cls, s)
-            for parent in cls.__mro__:
+            for parent in cls.__mro__[1:]:
                 if not hasattr(parent, 'uri'):
                     break
-                typ_name = self.mangle_name(parent.uri) + "_type"
+                typ_name = self.make_var(ClassDomain, parent.uri)
                 self.variables[typ_name].addValue(svar)
             if cls == List:
                 return
             cls = self.variables[svar]
             if cls.constraint:
                 self.constraints.extend(cls.constraint)
-            if not isinstance(self.variables[avar], Property):
-                if isinstance(self.variables[avar], Thing):
-                    self.variables[avar].addValue(Individual(svar, s))
-                else:
-                    self.variables[avar].addValue(svar)
+#            if not isinstance(self.variables[avar], Property):
+            if isinstance(self.variables[avar], Thing):
+                self.variables[avar].addValue(Individual(svar, s))
+            else:
+                self.variables[avar].addValue(svar)
     
     def first(self, s, var):
         pass
@@ -820,15 +874,11 @@
         # Can be used to define an enumerated datatype as well.
         # The memebers of the list can be Urirefs (Individuals) or Literals
         var = self.flatten_rdf_list(var)
-        svar = self.make_var(FixedClassDomain, s)
+        svar = self.mangle_name(s)
         res = list(self.variables[var].getValues())
-        if type(res[0]) == URIRef:
-            self.variables[svar].setValues([
-                Individual(self.make_var(Thing, x), x) for x in res])
-            for i in res:
-                self.type(i, Thing_uri)
-        else: 
-            self.variables[svar].setValues(res)
+        # For Individuals (datatypes handled differently ?) XXX
+        s_cls = FixedClassDomain(svar, s, [Individual(self.mangle_name(x), x) for x in res])
+        self.variables[svar] = s_cls
 
     def unionOf(self,s, var):
         var = self.flatten_rdf_list(var)
@@ -989,3 +1039,22 @@
            indx = diff_list.index(v)
            for other in diff_list[indx+1:]:
                self.differentFrom(v, other)
+
+if __name__ == "__main__":
+    import SimpleXMLRPCServer
+
+    import sys
+
+    def ok():
+        return "ok"
+
+    rdffile = sys.argv[-1]
+    O = Ontology()
+    O.add_file(rdffile)
+    O.attach_fd()
+    O.consistency()
+    server = SimpleXMLRPCServer.SimpleXMLRPCServer(("localhost", 9000))
+    server.register_instance(O)
+    server.register_function(ok)
+    server.serve_forever()
+

Modified: pypy/dist/pypy/lib/pyontology/test/test_ontology.py
==============================================================================
--- pypy/dist/pypy/lib/pyontology/test/test_ontology.py	(original)
+++ pypy/dist/pypy/lib/pyontology/test/test_ontology.py	Mon Oct 23 19:48:04 2006
@@ -145,7 +145,7 @@
     O.type(sub, obj)
     O.type(obj, namespaces['owl']+"#Class")
     
-    assert O.variables[O.make_var(None, sub)].__class__  == Individual 
+    assert O.variables[O.make_var(None, obj)].getValues()[0].__class__  == Individual 
 
 # test for multiple types
 # test for type hierarchy
@@ -276,24 +276,26 @@
 def test_Transitiveproperty():
     O = Ontology()
     #Make functional property
-    sub = URIRef('subRegionOf')
+    subreg = URIRef('subRegionOf')
     obj = URIRef(namespaces['owl']+'#TransitiveProperty')
-    O.type(sub, obj)
+    O.type(subreg, obj)
     #Make class
     sub = URIRef('c')
     obj = URIRef(namespaces['owl']+'#Class')
     O.type(sub, obj)
     #Make individual with a value of the property
-    sub = URIRef('Italy')
+    it = URIRef('Italy')
     obj = URIRef('c')
-    O.type(sub, obj)
-    sub = URIRef('Tuscanny')
-    O.type(sub, obj)
-    sub = URIRef('Chianti')
-    O.type(sub, obj)
-    O.variables['subRegionOf_'].setValues([('Italy_','Tuscanny_'),('Tuscanny_','Chianti_')])
+    O.type(it, obj)
+    tus = URIRef('Tuscanny')
+    O.type(tus, obj)
+    chi = URIRef('Chianti')
+    O.type(chi, obj)
+#    O.variables['subRegionOf_'].setValues([('Italy_','Tuscanny_'),('Tuscanny_','Chianti_')])
+    O.consider_triple((tus, subreg, it))
+    O.consider_triple((chi, subreg, tus))
     O.consistency()
-    assert 'Chianti_' in O.variables['subRegionOf_']._dict['Italy_']
+    assert Individual('Italy_', it) in O.variables['subRegionOf_'].getValuesPrKey(Individual('Chianti',chi))
     
 def test_symmetricproperty():    
     O = Ontology()
@@ -717,5 +719,5 @@
 #    O.type(first, URIRef(namespaces['owl']+'#SymmetricProperty'))
     O.consider_triple((first, URIRef(namespaces['rdf']+'#type'), URIRef(namespaces['owl']+'#SymmetricProperty')))
     assert isinstance(O.variables['first_'], SymmetricProperty)
-    assert 'first_' in O.variables['rdf_Property_type'].getValues()
-    assert 'first_' in O.variables['owl_ObjectProperty_type'].getValues()
+    assert 'first_' in O.variables['owl_ObjectProperty'] #.getValues()
+    assert 'first_' in O.variables['rdf_Property'] # .getValues()

Modified: pypy/dist/pypy/lib/pyontology/test/test_sparql.py
==============================================================================
--- pypy/dist/pypy/lib/pyontology/test/test_sparql.py	(original)
+++ pypy/dist/pypy/lib/pyontology/test/test_sparql.py	Mon Oct 23 19:48:04 2006
@@ -66,24 +66,6 @@
 #   var             var             var    ; for all p's return p.getvalues
 #
 # If p is a builtin owl property
-Onto = """<rdf:RDF
-      xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
-      xmlns:owl="http://www.w3.org/2002/07/owl#"
-      xmlns:ns="http://example.org/ns#"
-      xmlns:base="http://example.org/ns#">
-
-<owl:Class rdf:about="http://www.w3.org/2002/07/owl#Thing">
-        <owl:oneOf rdf:parseType="Collection">
-            <owl:Thing rdf:about="http://example.org/ns#s"/>
-       </owl:oneOf>
-      </owl:Class>
-    <owl:Thing rdf:about="http://example.org/ns#sub">
-        <ns:p rdf:datatype=
-        "http://www.w3.org/2001/XMLSchema#int">123</ns:p>
-    </owl:Thing>
-    <owl:ObjectProperty rdf:about="http://example.org/ns#p" />
-  </rdf:RDF>
-    """
 
 qt_proto = """
         PREFIX ns: <http://example.org/ns#>
@@ -99,7 +81,7 @@
 
     query = qt_proto % ('?x', 'ns:sub ns:p "a123" .')
     O = Ontology()
-    O.add_file(StringIO(Onto))
+    O.add_file("testont.rdf")
     O.attach_fd()
     raises(ConsistencyFailure, O.sparql, query)
 
@@ -108,9 +90,9 @@
 
     query = qt_proto % ('?x', '?x ns:p 123 .')
     O = Ontology()
-    O.add_file(StringIO(Onto))
+    O.add_file("testont.rdf")
     O.attach_fd()
-    O.sparql(query)
+    res = O.sparql(query)
     assert list(O.variables['query_x_'].getValues())[0].uri == u'http://example.org/ns#sub' 
 
 def test_case_2():
@@ -118,47 +100,52 @@
 
     query = qt_proto % ('?x', 'ns:sub  ?x 123 .')
     O = Ontology()
-    O.add_file(StringIO(Onto))
+    O.add_file("testont.rdf")
     O.attach_fd()
 
-    O.sparql(query)
+    res = O.sparql(query)
     assert list(O.variables['query_x_'].getValues())[0] == 'ns_p' 
+    assert res[0]['query_x_'] == 'ns_p'
 
 def test_case_3():
     """search for s in p"""
 
     query = qt_proto % ('?x', 'ns:sub ns:p ?x .')
     O = Ontology()
-    O.add_file(StringIO(Onto))
+    O.add_file("testont.rdf")
 
     O.attach_fd()
-
-    O.sparql(query)
-    assert list(O.variables['query_x_'].getValues())[0] == '123' 
+#    import pdb
+#    pdb.set_trace()
+    res = O.sparql(query)
+    assert list(O.variables['query_x_'].getValues())[0] == '123'
+    assert res[0]['query_x_'] == '123'
 
 def test_case_4():
     """ search for s in p """
 
     query = qt_proto % ('?x ?y', '?x ?y 123 .')
     O = Ontology()
-    O.add_file(StringIO(Onto))
+    O.add_file("testont.rdf")
     O.attach_fd()
 
-    O.sparql(query)
+    res = O.sparql(query)
     assert list(O.variables['query_x_'].getValues())[0].uri == u'http://example.org/ns#sub' 
     assert list(O.variables['query_y_'].getValues())[0] == 'ns_p' #u'http://example.org/ns#p' 
+    assert res[0]['query_x_'] == u'http://example.org/ns#sub' 
 
 def test_case_5():
     """ for all p's return p[0] if p[1]==o """
 
     query = qt_proto % ('?x ?y', '?x ns:p ?y .')
     O = Ontology()
-    O.add_file(StringIO(Onto))
+    O.add_file("testont.rdf")
     O.attach_fd()
 
-    O.sparql(query)
+    res = O.sparql(query)
     assert list(O.variables['query_x_'].getValues())[0].uri == u'http://example.org/ns#sub' 
     assert list(O.variables['query_y_'].getValues())[0] == u'123' 
+    assert res[0]['query_x_'] == u'http://example.org/ns#sub' 
 
 def test_case_6():
     """ return the values of p """
@@ -166,11 +153,12 @@
 
     query = qt_proto % ('?x ?y', 'ns:sub ?x ?y .')
     O = Ontology()
-    O.add_file(StringIO(Onto))
+    O.add_file("testont.rdf")
     O.attach_fd()
 
-    O.sparql(query)
+    res = O.sparql(query)
     assert list(O.variables['query_x_'].getValues())[0].uri == u'http://example.org/ns#sub' 
+    assert res[0]['query_x_'] == u'http://example.org/ns#sub' 
 
 def test_case_7():
     """ for all p's return p[1] if p[0]==s """
@@ -178,11 +166,38 @@
 
     query = qt_proto % ('?x ?y ?z', '?x ?y ?z .')
     O = Ontology()
-    O.add_file(StringIO(Onto))
+    O.add_file("testont.rdf")
     O.attach_fd()
 
-    O.sparql(query)
+    res = O.sparql(query)
     assert list(O.variables['query_x_'].getValues())[0].uri == u'http://example.org/ns#sub' 
+    assert res[0]['query_x_'] == u'http://example.org/ns#sub' 
+ 
 
+import xmlrpclib, socket, os, signal
 
-
+class TestXMLRPC:
+    
+    def setup_class(self):
+        from subprocess import Popen 
+        self.shell = Popen("python ../pyontology.py testont.rdf", shell=True)
+        server = xmlrpclib.ServerProxy("http://localhost:9000")
+        print "setup"
+
+        while 1:
+            try:
+                server.ok()
+            except socket.error:
+                pass
+            else:
+                break
+    def teardown_class(self):
+        print " teardown", self.shell.pid
+        os.kill(self.shell.pid, signal.SIGTERM)
+
+    def test_xmlrpc(self):
+        py.test.skip("WIP")
+        print "test_xmlrpc"
+        server = xmlrpclib.ServerProxy("http://localhost:9000", allow_none=True)
+        result = server.sparql(qt_proto % ('?x', 'ns:sub ns:p ?x .'))
+        assert result == [u'http://example.org/ns#sub']

Added: pypy/dist/pypy/lib/pyontology/test/testont.rdf
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/lib/pyontology/test/testont.rdf	Mon Oct 23 19:48:04 2006
@@ -0,0 +1,18 @@
+<rdf:RDF
+      xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+      xmlns:owl="http://www.w3.org/2002/07/owl#"
+      xmlns:ns="http://example.org/ns#"
+      xmlns:base="http://example.org/ns#">
+
+<owl:Class rdf:about="http://example.org/ns#test">
+        <owl:oneOf rdf:parseType="Collection">
+            <owl:Thing rdf:about="http://example.org/ns#s"/>
+       </owl:oneOf>
+      </owl:Class>
+    <owl:Thing rdf:about="http://example.org/ns#sub">
+        <ns:p rdf:datatype=
+        "http://www.w3.org/2001/XMLSchema#int">123</ns:p>
+    </owl:Thing>
+    <owl:ObjectProperty rdf:about="http://example.org/ns#p" />
+  </rdf:RDF>
+



More information about the Pypy-commit mailing list