Skip to content

Commit

Permalink
Fix doctests
Browse files Browse the repository at this point in the history
  • Loading branch information
hagenw committed Nov 15, 2024
1 parent c242636 commit 7155cf7
Show file tree
Hide file tree
Showing 6 changed files with 179 additions and 89 deletions.
4 changes: 2 additions & 2 deletions audbackend/core/backend/minio.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,11 +40,11 @@ class Minio(Base):
>>> auth = ("Q3AM3UQ867SPQQA43P2F", "zuf+tfteSlswRu7BJ86wekitnifILbZam1KYY3TG")
>>> repository = "my-data" + audeer.uid()
>>> Minio.create(host, repository, authentication=auth)
>>> file = audeer.touch("file.txt")
>>> file = audeer.touch("src.txt")
>>> backend = Minio(host, repository, authentication=auth)
>>> try:
... with backend:
... backend.put_file("src.txt", "/sub/file.txt")
... backend.put_file(file, "/sub/file.txt")
... backend.ls()
... finally:
... Minio.delete(host, repository, authentication=auth)
Expand Down
117 changes: 66 additions & 51 deletions audbackend/core/conftest.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import datetime
import doctest
import os

import pytest
import sybil
Expand All @@ -14,74 +15,88 @@
pytest_collect_file = sybil.Sybil(
parsers=[DocTestParser(optionflags=doctest.ELLIPSIS)],
patterns=["*.py"],
fixtures=["prepare_docstring_tests", "filesystem_backend"],
fixtures=[
"filesystem_backend",
"prepare_docstring_tests",
"clear",
],
).pytest()


class FileSystem(audbackend.backend.FileSystem):
def __init__(
self,
host: str,
repository: str,
):
def __init__(self, host, repository):
super().__init__(host, repository)
self.opened = True

def _date(
self,
path: str,
) -> str:
def _date(self, path):
date = datetime.datetime(1991, 2, 20)
date = audbackend.core.utils.date_format(date)
return date

def _owner(
self,
path: str,
) -> str:
def _owner(self, path):
return "doctest"


@pytest.fixture(scope="session", autouse=True)
def clear():
"""Clear local files and filesystem backend.
When using a tmpdir with the scope ``"function"`` or ``"class"``,
a new tmpdir is used each line
in the docstring tests.
When using the next greater scope ``"module"``,
the same tmpdir is used in the whole file,
which means there is no scope
that provides a new tmpdir
for each function/method
within a file.
To simulate this behavior,
we use the scope ``"module"``,
and provide this ``clear()`` function
to reset after a finished docstring.
"""

def clear_all():
# Clear backend
audeer.rmdir("host", "repo")
audeer.mkdir("host", "repo")
# Clear local files
files = audeer.list_file_names(".", basenames=True)
files = [file for file in files if not file == "src.txt"]
for file in files:
os.remove(file)

yield clear_all


@pytest.fixture(scope="function")
def filesystem_backend():
"""Filesystem backend with patched date and owner methods.
The backend is also opened already.
"""
yield FileSystem("host", "repo")


@pytest.fixture(scope="function", autouse=True)
def prepare_docstring_tests(tmpdir, monkeypatch):
@pytest.fixture(scope="module", autouse=True)
def prepare_docstring_tests(tmpdir_factory):
r"""Code to be run before each doctest."""
# Change to tmp dir
monkeypatch.chdir(tmpdir)

# Provide example file `src.txt`
audeer.touch("src.txt")

# Prepare backend
audeer.mkdir("host", "repo")

yield


# @pytest.fixture(scope="function", autouse=True)
# def prepare_docstring_tests(doctest_namespace):
# with tempfile.TemporaryDirectory() as tmp:
# # Change to tmp dir
# current_dir = os.getcwd()
# os.chdir(tmp)
# # Prepare backend
# audeer.mkdir("host")
# audbackend.backend.FileSystem.create("host", "repo")
# # Provide example file `src.txt`
# audeer.touch("src.txt")
# # Provide DoctestFileSystem as FileSystem,
# # and audbackend
# # in docstring examples
# doctest_namespace["DoctestFileSystem"] = DoctestFileSystem
# doctest_namespace["audbackend"] = audbackend
#
# yield
#
# # Remove backend
# audbackend.backend.FileSystem.delete("host", "repo")
# # Change back to current dir
# os.chdir(current_dir)
tmp_dir = tmpdir_factory.mktemp("tmp")

try:
# Change to tmp dir
current_dir = os.getcwd()
os.chdir(tmp_dir)

# Provide example file `src.txt`
audeer.touch("src.txt")

# Prepare backend
audeer.mkdir("host", "repo")

yield

finally:
os.chdir(current_dir)
1 change: 1 addition & 0 deletions audbackend/core/errors.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ class BackendError(Exception):
>>> import audeer
>>> import audbackend
>>> _ = audeer.mkdir("host", "repo")
Examples:
>>> backend = audbackend.backend.FileSystem("host", "repo")
Expand Down
7 changes: 7 additions & 0 deletions audbackend/core/interface/maven.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ class Maven(Versioned):
..
>>> import audbackend
>>> import audeer
Examples:
>>> file = "src.txt"
Expand All @@ -79,6 +80,9 @@ class Maven(Versioned):
>>> interface.get_file("/file.txt", "dst.txt", "2.0.0")
'...dst.txt'
..
>>> clear()
""" # noqa: E501

def __init__(
Expand Down Expand Up @@ -162,6 +166,9 @@ def ls(
>>> interface.ls("/sub/")
[('/sub/archive.zip', '1.0.0')]
..
>>> clear()
""" # noqa: E501
if path.endswith("/"): # find files under sub-path
paths = self.backend.ls(
Expand Down
47 changes: 47 additions & 0 deletions audbackend/core/interface/unversioned.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,17 @@ class Unversioned(Base):
..
>>> import audbackend
>>> import audeer
.. >>> def clear():
.. ... # Clear backend
.. ... audeer.rmdir("host", "repo")
.. ... audeer.mkdir("host", "repo")
.. ... # Clear local files
.. ... files = audeer.list_file_names(".", basenames=True)
.. ... files = [file for file in files if not file == "src.txt"]
.. ... for file in files:
.. ... os.remove(file)
Examples:
>>> file = "src.txt"
Expand All @@ -30,6 +41,9 @@ class Unversioned(Base):
>>> interface.get_file("/file.txt", "dst.txt")
'...dst.txt'
..
>>> clear()
"""

def checksum(
Expand Down Expand Up @@ -64,6 +78,9 @@ def checksum(
>>> interface.checksum("/file.txt")
'd41d8cd98f00b204e9800998ecf8427e'
..
>>> clear()
"""
return self.backend.checksum(path)

Expand Down Expand Up @@ -118,6 +135,9 @@ def copy_file(
>>> interface.exists("/copy.txt")
True
..
>>> clear()
"""
self.backend.copy_file(
src_path,
Expand Down Expand Up @@ -158,6 +178,9 @@ def date(
>>> interface.date("/file.txt")
'1991-02-20'
..
>>> clear()
"""
return self.backend.date(path)

Expand Down Expand Up @@ -200,6 +223,9 @@ def exists(
>>> interface.exists("/file.txt")
True
..
>>> clear()
"""
return self.backend.exists(
path,
Expand Down Expand Up @@ -268,6 +294,9 @@ def get_archive(
>>> interface.get_archive("/sub/archive.zip", ".")
['src.txt']
..
>>> clear()
"""
return self.backend.get_archive(
src_path,
Expand Down Expand Up @@ -339,6 +368,9 @@ def get_file(
>>> os.path.exists("dst.txt")
True
..
>>> clear()
"""
return self.backend.get_file(
src_path,
Expand Down Expand Up @@ -411,6 +443,9 @@ def ls(
>>> interface.ls("/sub/")
['/sub/archive.zip']
..
>>> clear()
""" # noqa: E501
return self.backend.ls(
path,
Expand Down Expand Up @@ -475,6 +510,9 @@ def move_file(
>>> interface.exists("/file.txt")
False
..
>>> clear()
"""
self.backend.move_file(
src_path,
Expand Down Expand Up @@ -516,6 +554,7 @@ def owner(
>>> interface.owner("/file.txt")
'doctest'
>>> clear()
"""
return self.backend.owner(path)

Expand Down Expand Up @@ -587,6 +626,8 @@ def put_archive(
>>> interface.exists("/sub/archive.tar.gz")
True
>>> clear()
"""
self.backend.put_archive(
src_root,
Expand Down Expand Up @@ -647,6 +688,9 @@ def put_file(
>>> interface.exists("/file.txt")
True
..
>>> clear()
"""
self.backend.put_file(
src_path,
Expand Down Expand Up @@ -683,5 +727,8 @@ def remove_file(
>>> interface.exists("/file.txt")
False
..
>>> clear()
"""
self.backend.remove_file(path)
Loading

0 comments on commit 7155cf7

Please sign in to comment.