Repository: RDFLib/rdflib

Issue:
graph.serialize(destination=) should accept a pathlib Path
If you try:

```python
g.serialize(destination=pathib.Path(__file__).parent / "some" / "path" / "to" / "a" / "file.ttl", format="ttl")
```

You get a:

```python
AttributeError: 'PosixPath' object has no attribute 'decode'
```

You have to do:

```python
g.serialize(destination=str(pathib.Path(__file__).parent / "some" / "path" / "to" / "a" / "file.ttl"), format="ttl")
```

We should allow a Path to be used like this.

Discussion:
coveralls: 
[![Coverage Status](https://coveralls.io/builds/39672491/badge)](https://coveralls.io/builds/39672491)

Coverage increased (+0.08%) to 75.607% when pulling **db2ff5d09366f1c846b210a279022bc4d19b83a4 on iafork:support_purepath** into **8d592a2e3bf7f63da52f9326f3f9d037e7d6ae51 on RDFLib:master**.

nicholascar: @aucampia can you resolve conflicts here so we can merge?

Patch:
diff --git a/rdflib/graph.py b/rdflib/graph.py
index 86b7ccb8..f90b3acb 100644
--- a/rdflib/graph.py
+++ b/rdflib/graph.py
@@ -19,6 +19,7 @@ from rdflib.exceptions import ParserError
 import os
 import shutil
 import tempfile
+import pathlib
 
 from io import BytesIO, BufferedIOBase
 from urllib.parse import urlparse
@@ -1065,7 +1066,10 @@ class Graph(Node):
             stream = cast(BufferedIOBase, destination)
             serializer.serialize(stream, base=base, encoding=encoding, **args)
         else:
-            location = cast(str, destination)
+            if isinstance(destination, pathlib.PurePath):
+                location = str(destination)
+            else:
+                location = cast(str, destination)
             scheme, netloc, path, params, _query, fragment = urlparse(location)
             if netloc != "":
                 print(
diff --git a/rdflib/parser.py b/rdflib/parser.py
index aa622ee0..ce4e5a2d 100644
--- a/rdflib/parser.py
+++ b/rdflib/parser.py
@@ -238,7 +238,7 @@ def create_input_source(
         else:
             if isinstance(source, str):
                 location = source
-            elif isinstance(source, pathlib.Path):
+            elif isinstance(source, pathlib.PurePath):
                 location = str(source)
             elif isinstance(source, bytes):
                 data = source


Test patch:
diff --git a/test/test_serialize.py b/test/test_serialize.py
new file mode 100644
index 00000000..cfc8a9d7
--- /dev/null
+++ b/test/test_serialize.py
@@ -0,0 +1,43 @@
+import unittest
+from rdflib import Graph, URIRef
+from tempfile import NamedTemporaryFile, TemporaryDirectory
+from pathlib import Path, PurePath
+
+
+class TestSerialize(unittest.TestCase):
+    def setUp(self) -> None:
+
+        graph = Graph()
+        subject = URIRef("example:subject")
+        predicate = URIRef("example:predicate")
+        object = URIRef("example:object")
+        self.triple = (
+            subject,
+            predicate,
+            object,
+        )
+        graph.add(self.triple)
+        self.graph = graph
+        return super().setUp()
+
+    def test_serialize_to_purepath(self):
+        with TemporaryDirectory() as td:
+            tfpath = PurePath(td) / "out.nt"
+            self.graph.serialize(destination=tfpath, format="nt")
+            graph_check = Graph()
+            graph_check.parse(source=tfpath, format="nt")
+
+        self.assertEqual(self.triple, next(iter(graph_check)))
+
+    def test_serialize_to_path(self):
+        with NamedTemporaryFile() as tf:
+            tfpath = Path(tf.name)
+            self.graph.serialize(destination=tfpath, format="nt")
+            graph_check = Graph()
+            graph_check.parse(source=tfpath, format="nt")
+
+        self.assertEqual(self.triple, next(iter(graph_check)))
+
+
+if __name__ == "__main__":
+    unittest.main()