Python: Uses typing.io for I/O types annotations

pull/348/head
Tpt 2 years ago committed by Thomas Tanon
parent 719cde2eac
commit d453721e8b
  1. 1
      python/generate_stubs.py
  2. 4
      python/src/io.rs
  3. 6
      python/src/store.rs
  4. 17
      python/tests/test_io.py
  5. 1
      python/tests/test_model.py
  6. 18
      python/tests/test_store.py

@ -23,6 +23,7 @@ GENERICS = {
"iterable": _path_to_type("typing", "Iterable"), "iterable": _path_to_type("typing", "Iterable"),
"iterator": _path_to_type("typing", "Iterator"), "iterator": _path_to_type("typing", "Iterator"),
"list": _path_to_type("typing", "List"), "list": _path_to_type("typing", "List"),
"io": _path_to_type("typing", "IO"),
} }
OBJECT_MEMBERS = dict(inspect.getmembers(object)) OBJECT_MEMBERS = dict(inspect.getmembers(object))

@ -32,7 +32,7 @@ pub fn add_to_module(module: &PyModule) -> PyResult<()> {
/// and ``application/xml`` for `RDF/XML <https://www.w3.org/TR/rdf-syntax-grammar/>`_. /// and ``application/xml`` for `RDF/XML <https://www.w3.org/TR/rdf-syntax-grammar/>`_.
/// ///
/// :param input: The binary I/O object or file path to read from. For example, it could be a file path as a string or a file reader opened in binary mode with ``open('my_file.ttl', 'rb')``. /// :param input: The binary I/O object or file path to read from. For example, it could be a file path as a string or a file reader opened in binary mode with ``open('my_file.ttl', 'rb')``.
/// :type input: io.RawIOBase or io.BufferedIOBase or io.TextIOBase or str /// :type input: io(bytes) or io(str) or str
/// :param mime_type: the MIME type of the RDF serialization. /// :param mime_type: the MIME type of the RDF serialization.
/// :type mime_type: str /// :type mime_type: str
/// :param base_iri: the base IRI used to resolve the relative IRIs in the file or :py:const:`None` if relative IRI resolution should not be done. /// :param base_iri: the base IRI used to resolve the relative IRIs in the file or :py:const:`None` if relative IRI resolution should not be done.
@ -105,7 +105,7 @@ pub fn parse(
/// :param input: the RDF triples and quads to serialize. /// :param input: the RDF triples and quads to serialize.
/// :type input: iterable(Triple) or iterable(Quad) /// :type input: iterable(Triple) or iterable(Quad)
/// :param output: The binary I/O object or file path to write to. For example, it could be a file path as a string or a file writer opened in binary mode with ``open('my_file.ttl', 'wb')``. /// :param output: The binary I/O object or file path to write to. For example, it could be a file path as a string or a file writer opened in binary mode with ``open('my_file.ttl', 'wb')``.
/// :type output: io.RawIOBase or io.BufferedIOBase or str /// :type output: io(bytes) or str
/// :param mime_type: the MIME type of the RDF serialization. /// :param mime_type: the MIME type of the RDF serialization.
/// :type mime_type: str /// :type mime_type: str
/// :rtype: None /// :rtype: None

@ -266,7 +266,7 @@ impl PyStore {
/// and ``application/xml`` for `RDF/XML <https://www.w3.org/TR/rdf-syntax-grammar/>`_. /// and ``application/xml`` for `RDF/XML <https://www.w3.org/TR/rdf-syntax-grammar/>`_.
/// ///
/// :param input: The binary I/O object or file path to read from. For example, it could be a file path as a string or a file reader opened in binary mode with ``open('my_file.ttl', 'rb')``. /// :param input: The binary I/O object or file path to read from. For example, it could be a file path as a string or a file reader opened in binary mode with ``open('my_file.ttl', 'rb')``.
/// :type input: io.RawIOBase or io.BufferedIOBase or io.TextIOBase or str /// :type input: io(bytes) or io(str) or str
/// :param mime_type: the MIME type of the RDF serialization. /// :param mime_type: the MIME type of the RDF serialization.
/// :type mime_type: str /// :type mime_type: str
/// :param base_iri: the base IRI used to resolve the relative IRIs in the file or :py:const:`None` if relative IRI resolution should not be done. /// :param base_iri: the base IRI used to resolve the relative IRIs in the file or :py:const:`None` if relative IRI resolution should not be done.
@ -350,7 +350,7 @@ impl PyStore {
/// and ``application/xml`` for `RDF/XML <https://www.w3.org/TR/rdf-syntax-grammar/>`_. /// and ``application/xml`` for `RDF/XML <https://www.w3.org/TR/rdf-syntax-grammar/>`_.
/// ///
/// :param input: The binary I/O object or file path to read from. For example, it could be a file path as a string or a file reader opened in binary mode with ``open('my_file.ttl', 'rb')``. /// :param input: The binary I/O object or file path to read from. For example, it could be a file path as a string or a file reader opened in binary mode with ``open('my_file.ttl', 'rb')``.
/// :type input: io.RawIOBase or io.BufferedIOBase or io.TextIOBase or str /// :type input: io(bytes) or io(str) or str
/// :param mime_type: the MIME type of the RDF serialization. /// :param mime_type: the MIME type of the RDF serialization.
/// :type mime_type: str /// :type mime_type: str
/// :param base_iri: the base IRI used to resolve the relative IRIs in the file or :py:const:`None` if relative IRI resolution should not be done. /// :param base_iri: the base IRI used to resolve the relative IRIs in the file or :py:const:`None` if relative IRI resolution should not be done.
@ -431,7 +431,7 @@ impl PyStore {
/// and ``application/xml`` for `RDF/XML <https://www.w3.org/TR/rdf-syntax-grammar/>`_. /// and ``application/xml`` for `RDF/XML <https://www.w3.org/TR/rdf-syntax-grammar/>`_.
/// ///
/// :param output: The binary I/O object or file path to write to. For example, it could be a file path as a string or a file writer opened in binary mode with ``open('my_file.ttl', 'wb')``. /// :param output: The binary I/O object or file path to write to. For example, it could be a file path as a string or a file writer opened in binary mode with ``open('my_file.ttl', 'wb')``.
/// :type output: io.RawIOBase or io.BufferedIOBase or str /// :type output: io(bytes) or str
/// :param mime_type: the MIME type of the RDF serialization. /// :param mime_type: the MIME type of the RDF serialization.
/// :type mime_type: str /// :type mime_type: str
/// :param from_graph: if a triple based format is requested, the store graph from which dump the triples. By default, the default graph is used. /// :param from_graph: if a triple based format is requested, the store graph from which dump the triples. By default, the default graph is used.

@ -1,6 +1,6 @@
import unittest import unittest
from io import StringIO, BytesIO, RawIOBase from io import StringIO, BytesIO, UnsupportedOperation
from tempfile import NamedTemporaryFile from tempfile import NamedTemporaryFile, TemporaryFile
from pyoxigraph import * from pyoxigraph import *
@ -49,11 +49,9 @@ class TestParse(unittest.TestCase):
) )
def test_parse_io_error(self) -> None: def test_parse_io_error(self) -> None:
class BadIO(RawIOBase): with self.assertRaises(UnsupportedOperation) as _:
pass with TemporaryFile("wb") as fp:
list(parse(fp, mime_type="application/n-triples"))
with self.assertRaises(NotImplementedError) as _:
list(parse(BadIO(), mime_type="application/n-triples"))
class TestSerialize(unittest.TestCase): class TestSerialize(unittest.TestCase):
@ -71,3 +69,8 @@ class TestSerialize(unittest.TestCase):
self.assertEqual( self.assertEqual(
fp.read(), b'<http://example.com/foo> <http://example.com/p> "1" .\n' fp.read(), b'<http://example.com/foo> <http://example.com/p> "1" .\n'
) )
def test_serialize_io_error(self) -> None:
with self.assertRaises(UnsupportedOperation) as _:
with TemporaryFile("rb") as fp:
serialize([EXAMPLE_TRIPLE], fp, "text/turtle")

@ -1,4 +1,5 @@
import unittest import unittest
from pyoxigraph import * from pyoxigraph import *
XSD_STRING = NamedNode("http://www.w3.org/2001/XMLSchema#string") XSD_STRING = NamedNode("http://www.w3.org/2001/XMLSchema#string")

@ -1,10 +1,10 @@
import os import os
import unittest import unittest
from io import BytesIO, RawIOBase from io import BytesIO, UnsupportedOperation
from tempfile import NamedTemporaryFile, TemporaryFile
from typing import Any from typing import Any
from pyoxigraph import * from pyoxigraph import *
from tempfile import NamedTemporaryFile
foo = NamedNode("http://foo") foo = NamedNode("http://foo")
bar = NamedNode("http://bar") bar = NamedNode("http://bar")
@ -241,11 +241,9 @@ class TestStore(unittest.TestCase):
self.assertEqual(set(store), {Quad(foo, bar, baz, graph)}) self.assertEqual(set(store), {Quad(foo, bar, baz, graph)})
def test_load_with_io_error(self) -> None: def test_load_with_io_error(self) -> None:
class BadIO(RawIOBase): with self.assertRaises(UnsupportedOperation) as _:
pass with TemporaryFile("wb") as fp:
Store().load(fp, mime_type="application/n-triples")
with self.assertRaises(NotImplementedError) as _:
Store().load(BadIO(), mime_type="application/n-triples")
def test_dump_ntriples(self) -> None: def test_dump_ntriples(self) -> None:
store = Store() store = Store()
@ -281,11 +279,9 @@ class TestStore(unittest.TestCase):
) )
def test_dump_with_io_error(self) -> None: def test_dump_with_io_error(self) -> None:
class BadIO(RawIOBase):
pass
with self.assertRaises(OSError) as _: with self.assertRaises(OSError) as _:
Store().dump(BadIO(), mime_type="application/rdf+xml") with TemporaryFile("rb") as fp:
Store().dump(fp, mime_type="application/rdf+xml")
def test_write_in_read(self) -> None: def test_write_in_read(self) -> None:
store = Store() store = Store()

Loading…
Cancel
Save