Skip to content
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

Changes to graph.serialize() #1183

Merged
merged 2 commits into from
Dec 27, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ g.bind("xsd", XSD)
```
This will allow the n-triples triple above to be serialised like this:
```python
print(g.serialize(format="turtle").decode("utf-8"))
print(g.serialize(format="turtle"))
```

With these results:
Expand Down
4 changes: 2 additions & 2 deletions rdflib/container.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ class Container(object):
>>> from rdflib import Graph, BNode, Literal, Bag
>>> g = Graph()
>>> b = Bag(g, BNode(), [Literal("One"), Literal("Two"), Literal("Three")])
>>> print(g.serialize(format="turtle").decode())
>>> print(g.serialize(format="turtle"))
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
<BLANKLINE>
[] a rdf:Bag ;
Expand All @@ -30,7 +30,7 @@ class Container(object):

>>> # add a new item
>>> b.append(Literal("Hello"))
>>> print(g.serialize(format="turtle").decode())
>>> print(g.serialize(format="turtle"))
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
<BLANKLINE>
[] a rdf:Bag ;
Expand Down
28 changes: 22 additions & 6 deletions rdflib/graph.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from typing import Optional
from typing import Optional, Union
import logging
from warnings import warn
import random
Expand Down Expand Up @@ -957,12 +957,17 @@ def absolutize(self, uri, defrag=1):
return self.namespace_manager.absolutize(uri, defrag)

def serialize(
self, destination=None, format="xml", base=None, encoding=None, **args
) -> Optional[bytes]:
self, destination=None, format="turtle", base=None, encoding=None, **args
) -> Optional[Union[bytes, str]]:
"""Serialize the Graph to destination

If destination is None serialize method returns the serialization as
bytes. Format defaults to xml (AKA rdf/xml).
bytes or string.

If encoding is None and destination is None, returns a string
If encoding is set, and Destination is None, returns bytes

Format defaults to turtle.

Format support can be extended with plugins,
but "xml", "n3", "turtle", "nt", "pretty-xml", "trix", "trig" and "nquads" are built in.
Expand All @@ -975,8 +980,12 @@ def serialize(
serializer = plugin.get(format, Serializer)(self)
if destination is None:
stream = BytesIO()
serializer.serialize(stream, base=base, encoding=encoding, **args)
return stream.getvalue()
if encoding is None:
serializer.serialize(stream, base=base, encoding="utf-8", **args)
return stream.getvalue().decode("utf-8")
else:
serializer.serialize(stream, base=base, encoding=encoding, **args)
return stream.getvalue()
if hasattr(destination, "write"):
stream = destination
serializer.serialize(stream, base=base, encoding=encoding, **args)
Expand All @@ -999,6 +1008,13 @@ def serialize(
shutil.copy(name, dest)
os.remove(name)

def print(self, format="turtle", encoding="utf-8", out=None):
print(
self.serialize(None, format=format, encoding=encoding).decode(encoding),
file=out,
flush=True,
)

def parse(
self,
source=None,
Expand Down
4 changes: 2 additions & 2 deletions test/test_finalnewline.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,9 @@ def testFinalNewline():

failed = set()
for p in rdflib.plugin.plugins(None, rdflib.plugin.Serializer):
v = graph.serialize(format=p.name)
v = graph.serialize(format=p.name, encoding="latin-1")
lines = v.split("\n".encode("latin-1"))
if "\n".encode("latin-1") not in v or (lines[-1] != "".encode("latin-1")):
if b"\n" not in v or (lines[-1] != b""):
failed.add(p.name)
assert len(failed) == 0, "No final newline for formats: '%s'" % failed

Expand Down
42 changes: 17 additions & 25 deletions test/test_issue1003.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,14 +34,14 @@
g1 = Graph()
g1 += g
# @base should not be in output
assert "@base" not in g.serialize(format="turtle").decode("utf-8")
assert "@base" not in g.serialize(format="turtle")


# 2. base one set for graph, no base set for serialization
g2 = Graph(base=base_one)
g2 += g
# @base should be in output, from Graph (one)
assert "@base <http://one.org/> ." in g2.serialize(format="turtle").decode("utf-8")
assert "@base <http://one.org/> ." in g2.serialize(format="turtle")


# 3. no base set for graph, base two set for serialization
Expand All @@ -50,7 +50,7 @@
# @base should be in output, from serialization (two)
assert "@base <http://two.org/> ." in g3.serialize(
format="turtle", base=base_two
).decode("utf-8")
)


# 4. base one set for graph, base two set for serialization, Graph one overrides
Expand All @@ -59,11 +59,11 @@
# @base should be in output, from graph (one)
assert "@base <http://two.org/> ." in g4.serialize(
format="turtle", base=base_two
).decode("utf-8")
)
# just checking that the serialization setting (two) hasn't snuck through
assert "@base <http://one.org/> ." not in g4.serialize(
format="turtle", base=base_two
).decode("utf-8")
)


# 5. multiple serialization side effect checking
Expand All @@ -72,42 +72,34 @@
# @base should be in output, from serialization (two)
assert "@base <http://two.org/> ." in g5.serialize(
format="turtle", base=base_two
).decode("utf-8")
)

# checking for side affects - no base now set for this serialization
# @base should not be in output
assert "@base" not in g5.serialize(format="turtle").decode("utf-8")
assert "@base" not in g5.serialize(format="turtle")


# 6. checking results for RDF/XML
g6 = Graph()
g6 += g
g6.bind("dct", DCTERMS)
g6.bind("skos", SKOS)
assert "@xml:base" not in g6.serialize(format="xml").decode("utf-8")
assert 'xml:base="http://one.org/"' in g6.serialize(format="xml", base=base_one).decode(
"utf-8"
)
assert "@xml:base" not in g6.serialize(format="xml")
assert 'xml:base="http://one.org/"' in g6.serialize(format="xml", base=base_one)
g6.base = base_two
assert 'xml:base="http://two.org/"' in g6.serialize(format="xml").decode("utf-8")
assert 'xml:base="http://one.org/"' in g6.serialize(format="xml", base=base_one).decode(
"utf-8"
)
assert 'xml:base="http://two.org/"' in g6.serialize(format="xml")
assert 'xml:base="http://one.org/"' in g6.serialize(format="xml", base=base_one)

# 7. checking results for N3
g7 = Graph()
g7 += g
g7.bind("dct", DCTERMS)
g7.bind("skos", SKOS)
assert "@xml:base" not in g7.serialize(format="xml").decode("utf-8")
assert "@base <http://one.org/> ." in g7.serialize(format="n3", base=base_one).decode(
"utf-8"
)
assert "@xml:base" not in g7.serialize(format="xml")
assert "@base <http://one.org/> ." in g7.serialize(format="n3", base=base_one)
g7.base = base_two
assert "@base <http://two.org/> ." in g7.serialize(format="n3").decode("utf-8")
assert "@base <http://one.org/> ." in g7.serialize(format="n3", base=base_one).decode(
"utf-8"
)
assert "@base <http://two.org/> ." in g7.serialize(format="n3")
assert "@base <http://one.org/> ." in g7.serialize(format="n3", base=base_one)

# 8. checking results for TriX & TriG
# TriX can specify a base per graph but setting a base for the whole
Expand All @@ -122,12 +114,12 @@
g9.base = base_two
ds1.base = base_three

trix = ds1.serialize(format="trix", base=Namespace("http://two.org/")).decode("utf-8")
trix = ds1.serialize(format="trix", base=Namespace("http://two.org/"))
assert '<graph xml:base="http://one.org/">' in trix
assert '<graph xml:base="http://two.org/">' in trix
assert '<TriX xml:base="http://two.org/"' in trix

trig = ds1.serialize(format="trig", base=Namespace("http://two.org/")).decode("utf-8")
trig = ds1.serialize(format="trig", base=Namespace("http://two.org/"))
assert "@base <http://one.org/> ." not in trig
assert "@base <http://three.org/> ." not in trig
assert "@base <http://two.org/> ." in trig
2 changes: 1 addition & 1 deletion test/test_issue1043.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ def test_issue_1043(self):
g.bind('rdfs', RDFS)
n = Namespace("http://example.org/")
g.add((n.number, RDFS.label, Literal(0.00000004, datatype=XSD.decimal)))
print(g.serialize(format="turtle").decode("utf-8"))
g.print()
sys.stdout = sys.__stdout__
self.assertEqual(capturedOutput.getvalue(), expected)

Expand Down
4 changes: 2 additions & 2 deletions test/test_issue161.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,6 @@ def test_turtle_namespace_prefixes(self):
g = ConjunctiveGraph()
g.parse(data=turtle, format="turtle")
# Shouldn't have got to here
s = g.serialize(format="turtle")
s = g.serialize(format="turtle", encoding='latin-1')

self.assertTrue("@prefix _9".encode("latin-1") not in s)
self.assertTrue(b"@prefix _9" not in s)
2 changes: 1 addition & 1 deletion test/test_issue248.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ def test_issue_248(self):
graph.add((concept, rdflib.RDF.type, SKOS["Concept"]))
graph.add((concept, SKOS["prefLabel"], rdflib.Literal("Scrapbooks")))
graph.add((concept, DC["LCC"], rdflib.Literal("AC999.0999 - AC999999.Z9999")))
sg = graph.serialize(format="n3", base=LCCO).decode("utf8")
sg = graph.serialize(format="n3", base=LCCO)
# See issue 248
# Actual test should be the inverse of the below ...
self.assertTrue("<1> a skos:Concept ;" in sg, sg)
Expand Down
2 changes: 1 addition & 1 deletion test/test_issue801.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ def test_issue_801(self):
g.bind('', example)
node = BNode()
g.add((node, example['first%20name'], Literal('John')))
self.assertEqual(g.serialize(format="turtle").decode().split("\n")[-3],
self.assertEqual(g.serialize(format="turtle").split("\n")[-3],
'[] :first%20name "John" .')

if __name__ == "__main__":
Expand Down
6 changes: 2 additions & 4 deletions test/test_issue_git_336.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,10 @@ def test_ns_localname_roundtrip():
rdflib.Literal("Junk"),
)
)
turtledump = g.serialize(format="turtle").decode("utf-8")
xmldump = g.serialize().decode("utf-8")
turtledump = g.serialize(format="turtle")
xmldump = g.serialize(format="xml")
g1 = rdflib.Graph()

g1.parse(data=xmldump, format="xml")

g1.parse(data=turtledump, format="turtle")


Expand Down
4 changes: 2 additions & 2 deletions test/test_n3.py
Original file line number Diff line number Diff line change
Expand Up @@ -125,8 +125,8 @@ def testBaseSerialize(self):
URIRef("http://example.com/people/Linda"),
)
)
s = g.serialize(base="http://example.com/", format="n3")
self.assertTrue("<people/Bob>".encode("latin-1") in s)
s = g.serialize(base="http://example.com/", format="n3", encoding="latin-1")
self.assertTrue(b"<people/Bob>" in s)
g2 = ConjunctiveGraph()
g2.parse(data=s, publicID="http://example.com/", format="n3")
self.assertEqual(list(g), list(g2))
Expand Down
10 changes: 4 additions & 6 deletions test/test_namespace.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,11 +72,11 @@ def test_n3(self):
URIRef("http://example.com/baz"),
)
)
n3 = g.serialize(format="n3")
n3 = g.serialize(format="n3", encoding='latin-1')
# Gunnar disagrees that this is right:
# self.assertTrue("<http://example.com/foo> ns1:bar <http://example.com/baz> ." in n3)
# as this is much prettier, and ns1 is already defined:
self.assertTrue("ns1:foo ns1:bar ns1:baz .".encode("latin-1") in n3)
self.assertTrue(b"ns1:foo ns1:bar ns1:baz ." in n3)

def test_n32(self):
# this test not generating prefixes for subjects/objects
Expand All @@ -88,12 +88,10 @@ def test_n32(self):
URIRef("http://example3.com/baz"),
)
)
n3 = g.serialize(format="n3")
n3 = g.serialize(format="n3", encoding="latin-1")

self.assertTrue(
"<http://example1.com/foo> ns1:bar <http://example3.com/baz> .".encode(
"latin-1"
)
b"<http://example1.com/foo> ns1:bar <http://example3.com/baz> ."
in n3
)

Expand Down
4 changes: 2 additions & 2 deletions test/test_nquads.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,9 +52,9 @@ def test_serialize(self):
g.get_context(uri1).add((bob, likes, pizza))
g.get_context(uri2).add((bob, likes, pizza))

s = g.serialize(format="nquads")
s = g.serialize(format="nquads", encoding="latin-1")
self.assertEqual(
len([x for x in s.split("\n".encode("latin-1")) if x.strip()]), 2
len([x for x in s.split(b"\n") if x.strip()]), 2
)

g2 = ConjunctiveGraph()
Expand Down
6 changes: 3 additions & 3 deletions test/test_nt_misc.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,15 +24,15 @@ def testIssue859(self):
def testIssue78(self):
g = Graph()
g.add((URIRef("foo"), URIRef("foo"), Literal("R\u00E4ksm\u00F6rg\u00E5s")))
s = g.serialize(format="nt")
s = g.serialize(format="nt", encoding="latin-1")
self.assertEqual(type(s), bytes)
self.assertTrue(r"R\u00E4ksm\u00F6rg\u00E5s".encode("latin-1") in s)

def testIssue146(self):
g = Graph()
g.add((URIRef("foo"), URIRef("foo"), Literal("test\n", lang="en")))
s = g.serialize(format="nt").strip()
self.assertEqual(s, '<foo> <foo> "test\\n"@en .'.encode("latin-1"))
s = g.serialize(format="nt", encoding="latin-1").strip()
self.assertEqual(s, b'<foo> <foo> "test\\n"@en .')

def testIssue1144_rdflib(self):
fname = "test/nt/lists-02.nt"
Expand Down
6 changes: 3 additions & 3 deletions test/test_prefixTypes.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,10 @@ class PrefixTypesTest(unittest.TestCase):
"""

def test(self):
s = graph.serialize(format="n3")
s = graph.serialize(format="n3", encoding="latin-1")
print(s)
self.assertTrue("foaf:Document".encode("latin-1") in s)
self.assertTrue("xsd:date".encode("latin-1") in s)
self.assertTrue(b"foaf:Document" in s)
self.assertTrue(b"xsd:date" in s)


if __name__ == "__main__":
Expand Down
8 changes: 2 additions & 6 deletions test/test_prettyxml.py
Original file line number Diff line number Diff line change
Expand Up @@ -188,9 +188,7 @@ def test_pretty_xmlliteral(self):
xmlrepr = g.serialize(format="pretty-xml")
# then:
assert (
"""<rdf:value rdf:parseType="Literal"><p xmlns="http://www.w3.org/1999/xhtml">See also <a href="#aring">Å</a></p></rdf:value>""".encode(
"utf-8"
)
"""<rdf:value rdf:parseType="Literal"><p xmlns="http://www.w3.org/1999/xhtml">See also <a href="#aring">Å</a></p></rdf:value>"""
in xmlrepr
)

Expand All @@ -202,9 +200,7 @@ def test_pretty_broken_xmlliteral(self):
xmlrepr = g.serialize(format="pretty-xml")
# then:
assert (
"""<rdf:value rdf:datatype="http://www.w3.org/1999/02/22-rdf-syntax-ns#XMLLiteral">&lt;p """.encode(
"utf-8"
)
"""<rdf:value rdf:datatype="http://www.w3.org/1999/02/22-rdf-syntax-ns#XMLLiteral">&lt;p """
in xmlrepr
)

Expand Down
3 changes: 1 addition & 2 deletions test/test_roundtrip.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,7 @@ def roundtrip(e, verbose=False):

if verbose:
print("S:")
print(s)
print(s.decode())
print(s, flush=True)

g2 = rdflib.ConjunctiveGraph()
g2.parse(data=s, format=testfmt)
Expand Down
2 changes: 1 addition & 1 deletion test/test_sparql.py
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ def test_sparql_update_with_bnode_serialize_parse():
"""
graph = Graph()
graph.update("INSERT DATA { _:blankA <urn:type> <urn:Blank> }")
string = graph.serialize(format="ntriples").decode("utf-8")
string = graph.serialize(format="ntriples")
raised = False
try:
Graph().parse(data=string, format="ntriples")
Expand Down
2 changes: 1 addition & 1 deletion test/test_sparqlupdatestore.py
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,7 @@ def testUpdateWithBlankNodeSerializeAndParse(self):
"INSERT DATA { GRAPH <urn:graph> { _:blankA <urn:type> <urn:Blank> } }"
)
g = self.graph.get_context(graphuri)
string = g.serialize(format="ntriples").decode("utf-8")
string = g.serialize(format="ntriples")
raised = False
try:
Graph().parse(data=string, format="ntriples")
Expand Down
Loading