Python: Runs doctests as part of the unittests

pull/724/head
Tpt 10 months ago committed by Thomas Tanon
parent 93eab63868
commit f01796b1a4
  1. 2
      .github/workflows/tests.yml
  2. 4
      python/src/io.rs
  3. 1
      python/src/store.rs
  4. 37
      python/tests/test_doc.py

@ -266,8 +266,6 @@ jobs:
- run: rm -r target/wheels
- run: python -m unittest
working-directory: ./python/tests
- run: sphinx-build -M doctest . build
working-directory: ./python/docs
- run: sphinx-build -M html . build
working-directory: ./python/docs
- run: python generate_stubs.py pyoxigraph pyoxigraph.pyi --ruff

@ -111,6 +111,7 @@ pub fn parse(
/// >>> serialize([Triple(NamedNode('http://example.com'), NamedNode('http://example.com/p'), Literal('1'))], format=RdfFormat.TURTLE)
/// b'<http://example.com> <http://example.com/p> "1" .\n'
///
/// >>> import io
/// >>> output = io.BytesIO()
/// >>> serialize([Triple(NamedNode('http://example.com'), NamedNode('http://example.com/p'), Literal('1'))], output, RdfFormat.TURTLE)
/// >>> output.getvalue()
@ -182,6 +183,9 @@ impl PyQuadReader {
/// * `TriG <https://www.w3.org/TR/trig/>`_ (:py:attr:`RdfFormat.TRIG`)
/// * `N3 <https://w3c.github.io/N3/spec/>`_ (:py:attr:`RdfFormat.N3`)
/// * `RDF/XML <https://www.w3.org/TR/rdf-syntax-grammar/>`_ (:py:attr:`RdfFormat.RDF_XML`)
///
/// >>> RdfFormat.N3.media_type
/// 'text/n3'
#[pyclass(name = "RdfFormat", module = "pyoxigraph")]
#[derive(Clone)]
pub struct PyRdfFormat {

@ -518,6 +518,7 @@ impl PyStore {
/// >>> store.dump(format=RdfFormat.TRIG)
/// b'<http://example.com> <http://example.com/p> "1" .\n'
///
/// >>> import io
/// >>> store = Store()
/// >>> store.add(Quad(NamedNode('http://example.com'), NamedNode('http://example.com/p'), Literal('1'), NamedNode('http://example.com/g')))
/// >>> output = io.BytesIO()

@ -0,0 +1,37 @@
# type: ignore
import inspect
from doctest import DocTestFinder, DocTestSuite
import pyoxigraph
class ExtendedDocTestFinder(DocTestFinder):
"""
More aggressive doctest lookup
"""
def _find(self, tests, obj, name, module, source_lines, globs, seen):
# If we've already processed this object, then ignore it.
if id(obj) in seen:
return
seen[id(obj)] = 1
# Find a test for this object, and add it to the list of tests.
test = self._get_test(obj, name, module, globs, source_lines)
if test is not None:
tests.append(test)
# Look for tests in a module's contained objects.
if inspect.ismodule(obj) or inspect.isclass(obj):
for valname, val in obj.__dict__.items():
if valname == "__doc__":
continue
# Special handling for staticmethod/classmethod.
if isinstance(val, (staticmethod, classmethod)):
val = val.__func__
self._find(tests, val, f"{name}.{valname}", module, source_lines, globs, seen)
def load_tests(_loader, tests, _ignore):
tests.addTests(DocTestSuite(pyoxigraph, test_finder=ExtendedDocTestFinder()))
return tests
Loading…
Cancel
Save