Skip to content

Commit

Permalink
Refactor: replace tmpdir fixture with tmp_path (#127)
Browse files Browse the repository at this point in the history
The `tmpdir` fixture provided by `pytest` has been deprecated and is
replaced by the `tmp_path` fixture.

Note that the `tmpdir` used to return an instance of `LocalPath`, a
class defined by `pytest`, but `tmp_path` returns an instance of
`pathlib.Path` from the standard library.
  • Loading branch information
sphuber authored Apr 29, 2022
1 parent de7ed43 commit 71a154f
Show file tree
Hide file tree
Showing 5 changed files with 50 additions and 45 deletions.
28 changes: 14 additions & 14 deletions tests/cli/test_install.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@


@pytest.fixture
def run_monkeypatched_install_sssp(run_cli_command, get_pseudo_potential_data, monkeypatch, tmpdir):
def run_monkeypatched_install_sssp(run_cli_command, get_pseudo_potential_data, monkeypatch, tmp_path):
"""Fixture to monkeypatch the ``aiida_pseudo.cli.install.download_sssp`` method and call the install cmd."""

def download_sssp(
Expand All @@ -37,14 +37,14 @@ def download_sssp(

element = 'Ar'
pseudo = get_pseudo_potential_data(element)
filepath = tmpdir / pseudo.filename
filepath = tmp_path / pseudo.filename

with pseudo.open(mode='rb') as handle:
md5 = hashlib.md5(handle.read()).hexdigest()
handle.seek(0)
filepath.write_binary(handle.read())
filepath.write_bytes(handle.read())

filename_archive = shutil.make_archive('temparchive', 'gztar', root_dir=tmpdir, base_dir='.')
filename_archive = shutil.make_archive('temparchive', 'gztar', root_dir=tmp_path, base_dir='.')
shutil.move(pathlib.Path.cwd() / filename_archive, filepath_archive)

with open(filepath_metadata, 'w', encoding='utf-8') as handle:
Expand All @@ -60,7 +60,7 @@ def _run_monkeypatched_install_sssp(options=None, raises=None):


@pytest.fixture
def run_monkeypatched_install_pseudo_dojo(run_cli_command, get_pseudo_potential_data, monkeypatch, tmpdir):
def run_monkeypatched_install_pseudo_dojo(run_cli_command, get_pseudo_potential_data, monkeypatch, tmp_path):
"""Fixture to monkeypatch the ``aiida_pseudo.cli.install.download_pseudo_dojo`` method and call the install cmd."""

def download_pseudo_dojo(
Expand All @@ -82,25 +82,25 @@ def download_pseudo_dojo(

element = 'Ar'
pseudo = get_pseudo_potential_data(element, entry_point='jthxml')
filepath = tmpdir / pseudo.filename
filepath = tmp_path / pseudo.filename

with pseudo.open(mode='rb') as handle:
md5 = hashlib.md5(handle.read()).hexdigest()
handle.seek(0)
filepath.write_binary(handle.read())
filepath.write_bytes(handle.read())

filename_archive = shutil.make_archive('temparchive', 'gztar', root_dir=tmpdir, base_dir='.')
filename_archive = shutil.make_archive('temparchive', 'gztar', root_dir=tmp_path, base_dir='.')
shutil.move(pathlib.Path.cwd() / filename_archive, filepath_archive)

data = {'hints': {'high': {'ecut': 20.00}, 'low': {'ecut': 20.00}, 'normal': {'ecut': 20.00}}, 'md5': md5}

filepath_djrepo = tmpdir / f'{element}.djrepo'
filepath_djrepo = tmp_path / f'{element}.djrepo'

with open(filepath_djrepo, 'w', encoding='utf-8') as handle:
json.dump(data, handle)
handle.flush()

filename_metadata = shutil.make_archive('tempmetadata', 'gztar', root_dir=tmpdir, base_dir='.')
filename_metadata = shutil.make_archive('tempmetadata', 'gztar', root_dir=tmp_path, base_dir='.')
shutil.move(pathlib.Path.cwd() / filename_metadata, filepath_metadata)

def _run_monkeypatched_install_pseudo_dojo(options=None, raises=None):
Expand Down Expand Up @@ -269,7 +269,7 @@ def test_install_pseudo_dojo_monkeypatched(run_monkeypatched_install_pseudo_dojo
assert family.label == label


@pytest.mark.usefixtures('clear_db', 'chtmpdir')
@pytest.mark.usefixtures('clear_db', 'chdir_tmp_path')
def test_install_sssp_download_only(run_monkeypatched_install_sssp):
"""Test the ``aiida-pseudo install sssp`` command with the ``--download-only`` option."""
options = ['--download-only']
Expand All @@ -279,7 +279,7 @@ def test_install_sssp_download_only(run_monkeypatched_install_sssp):
assert 'written to the current directory.' in result.output


@pytest.mark.usefixtures('clear_db', 'chtmpdir')
@pytest.mark.usefixtures('clear_db', 'chdir_tmp_path')
def test_install_sssp_download_only_exists(run_monkeypatched_install_sssp, get_pseudo_family):
"""Test the ``aiida-pseudo install sssp`` command with the ``--download-only`` option.
Expand All @@ -300,7 +300,7 @@ def test_install_sssp_download_only_exists(run_monkeypatched_install_sssp, get_p
assert 'written to the current directory.' in result.output


@pytest.mark.usefixtures('clear_db', 'chtmpdir')
@pytest.mark.usefixtures('clear_db', 'chdir_tmp_path')
def test_install_pseudo_dojo_download_only(run_monkeypatched_install_pseudo_dojo):
"""Test the ``aiida-pseudo install pseudo-dojo`` command with the ``--download-only`` option."""
options = ['--download-only']
Expand All @@ -310,7 +310,7 @@ def test_install_pseudo_dojo_download_only(run_monkeypatched_install_pseudo_dojo
assert 'written to the current directory.' in result.output


@pytest.mark.usefixtures('clear_db', 'chtmpdir')
@pytest.mark.usefixtures('clear_db', 'chdir_tmp_path')
def test_install_pseudo_dojo_download_only_exists(run_monkeypatched_install_pseudo_dojo, get_pseudo_family):
"""Test the ``aiida-pseudo install pseudo_dojo`` command with the ``--download-only`` option.
Expand Down
8 changes: 4 additions & 4 deletions tests/cli/test_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,19 +25,19 @@ def test_create_family_from_archive(get_pseudo_archive, fmt):


@pytest.mark.usefixtures('clear_db')
def test_create_family_from_archive_incorrect_filetype(tmpdir):
def test_create_family_from_archive_incorrect_filetype(tmp_path):
"""Test the `create_family_from_archive` utility function for incorrect archive filetype."""
with pytest.raises(OSError, match=r'failed to unpack the archive.*'):
create_family_from_archive(PseudoPotentialFamily, 'label', str(tmpdir))
create_family_from_archive(PseudoPotentialFamily, 'label', str(tmp_path))


@pytest.mark.usefixtures('clear_db')
def test_create_family_from_archive_incorrect_format(tmpdir):
def test_create_family_from_archive_incorrect_format(tmp_path):
"""Test the `create_family_from_archive` utility function for invalid archive content."""
with tempfile.NamedTemporaryFile(suffix='.tar.gz') as filepath_archive:

with tarfile.open(filepath_archive.name, 'w:gz') as tar:
tar.add(str(tmpdir), arcname='.')
tar.add(str(tmp_path), arcname='.')

with pytest.raises(OSError, match=r'failed to parse pseudos from.*'):
create_family_from_archive(PseudoPotentialFamily, 'label', filepath_archive.name)
Expand Down
15 changes: 10 additions & 5 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
"""Configuration and fixtures for unit test suite."""
import io
import os
import pathlib
import re
import shutil

Expand All @@ -29,10 +30,14 @@ def ctx():


@pytest.fixture
def chtmpdir(tmpdir):
def chdir_tmp_path(tmp_path):
"""Change the current working directory to a temporary directory."""
with tmpdir.as_cwd():
cwd = pathlib.Path.cwd()
os.chdir(tmp_path)
try:
yield
finally:
os.chdir(cwd)


@pytest.fixture
Expand Down Expand Up @@ -151,7 +156,7 @@ def _generate_cutoffs_dict(family, stringencies=('normal',)):


@pytest.fixture
def get_pseudo_family(tmpdir, filepath_pseudos):
def get_pseudo_family(tmp_path, filepath_pseudos):
"""Return a factory for a ``PseudoPotentialFamily`` instance."""

def _get_pseudo_family(
Expand Down Expand Up @@ -189,9 +194,9 @@ def _get_pseudo_family(

for pseudo in os.listdir(dirpath):
if elements is None or any(pseudo.startswith(element) for element in elements):
shutil.copyfile(os.path.join(dirpath, pseudo), os.path.join(str(tmpdir), pseudo))
shutil.copyfile(os.path.join(dirpath, pseudo), os.path.join(str(tmp_path), pseudo))

family = cls.create_from_folder(str(tmpdir), label, pseudo_type=pseudo_type)
family = cls.create_from_folder(str(tmp_path), label, pseudo_type=pseudo_type)

if cutoffs_dict is not None and isinstance(family, CutoffsPseudoPotentialFamily):
default_stringency = default_stringency or list(cutoffs_dict.keys())[0]
Expand Down
2 changes: 1 addition & 1 deletion tests/data/pseudo/test_pseudo.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ def test_constructor_invalid():
PseudoPotentialData() # pylint: disable=no-value-for-parameter


@pytest.mark.usefixtures('chtmpdir')
@pytest.mark.usefixtures('chdir_tmp_path')
@pytest.mark.parametrize('source_type', ('stream', 'str_absolute', 'str_relative', 'pathlib.Path'))
@pytest.mark.parametrize('implicit', (True, False))
def test_constructor_filename(get_pseudo_potential_data, implicit, source_type):
Expand Down
42 changes: 21 additions & 21 deletions tests/groups/family/test_pseudo.py
Original file line number Diff line number Diff line change
Expand Up @@ -86,12 +86,12 @@ def test_create_from_folder(filepath_pseudos):


@pytest.mark.usefixtures('clear_db')
def test_create_from_folder_nested(filepath_pseudos, tmpdir):
def test_create_from_folder_nested(filepath_pseudos, tmp_path):
"""Test the `PseudoPotentialFamily.create_from_folder` class method when the pseudos are in a subfolder."""
shutil.copytree(filepath_pseudos(), tmpdir / 'subdirectory')
shutil.copytree(filepath_pseudos(), tmp_path / 'subdirectory')

label = 'label'
family = PseudoPotentialFamily.create_from_folder(str(tmpdir), label)
family = PseudoPotentialFamily.create_from_folder(str(tmp_path), label)
assert isinstance(family, PseudoPotentialFamily)
assert family.is_stored
assert family.label == label
Expand Down Expand Up @@ -128,31 +128,31 @@ def test_create_from_folder_deduplicate(filepath_pseudos, deduplicate):


@pytest.mark.usefixtures('clear_db')
def test_create_from_folder_parse_fail(tmpdir):
def test_create_from_folder_parse_fail(tmp_path):
"""Test the `PseudoPotentialFamily.create_from_folder` class method for file that fails to parse.
Since the base pseudo potential class cannot really fail to parse, since there is no parsing, this would be
difficult to test, however, the constructor parses the filename for the element, and that can fail if the filename
has the incorrect format.
"""
with open(os.path.join(str(tmpdir), 'Arr.upf'), 'wb'):
with open(os.path.join(str(tmp_path), 'Arr.upf'), 'wb'):
pass

with pytest.raises(exceptions.ParsingError, match=r'`.*` constructor did not define the element .*'):
PseudoPotentialFamily.create_from_folder(str(tmpdir), 'label')
PseudoPotentialFamily.create_from_folder(str(tmp_path), 'label')


@pytest.mark.usefixtures('clear_db')
def test_create_from_folder_empty(tmpdir):
def test_create_from_folder_empty(tmp_path):
"""Test the `PseudoPotentialFamily.create_from_folder` class method for empty folder."""
with pytest.raises(ValueError, match=r'no pseudo potentials were parsed from.*'):
PseudoPotentialFamily.create_from_folder(str(tmpdir), 'label')
PseudoPotentialFamily.create_from_folder(str(tmp_path), 'label')


@pytest.mark.usefixtures('clear_db')
def test_create_from_folder_duplicate_element(tmpdir, filepath_pseudos):
def test_create_from_folder_duplicate_element(tmp_path, filepath_pseudos):
"""Test the `PseudoPotentialFamily.create_from_folder` class method for folder containing duplicate element."""
dirpath = tmpdir / 'pseudos'
dirpath = tmp_path / 'pseudos'
shutil.copytree(filepath_pseudos(), dirpath)

with open(os.path.join(str(dirpath), 'Ar.UPF'), 'wb'):
Expand All @@ -172,36 +172,36 @@ def test_create_from_folder_duplicate(filepath_pseudos):
PseudoPotentialFamily.create_from_folder(filepath_pseudos(), label)


def test_parse_pseudos_from_directory_non_file(tmpdir):
def test_parse_pseudos_from_directory_non_file(tmp_path):
"""Test the `PseudoPotentialFamily.parse_pseudos_from_directory` class method for folder containing a non-file.
Note that a subdirectory containing the pseudos is fine, but if we find a directory and any other object at the
base path, it should raise.
"""
os.makedirs(os.path.join(str(tmpdir), 'directory'))
with open(os.path.join(str(tmpdir), 'Ar.upf'), 'wb'):
os.makedirs(os.path.join(str(tmp_path), 'directory'))
with open(os.path.join(str(tmp_path), 'Ar.upf'), 'wb'):
pass

with pytest.raises(ValueError, match=r'dirpath `.*` contains at least one entry that is not a file'):
PseudoPotentialFamily.parse_pseudos_from_directory(str(tmpdir))
PseudoPotentialFamily.parse_pseudos_from_directory(str(tmp_path))


def test_parse_pseudos_from_directory_non_file_nested(tmpdir):
def test_parse_pseudos_from_directory_non_file_nested(tmp_path):
"""Test the `PseudoPotentialFamily.parse_pseudos_from_directory` class method for folder containing a non-file.
Note that a subdirectory containing the pseudos is fine, but if we find a directory and any other object at the
base path, it should raise.
"""
os.makedirs(os.path.join(str(tmpdir), 'pseudos', 'directory'))
with open(os.path.join(str(tmpdir), 'pseudos', 'Ar.upf'), 'wb'):
os.makedirs(os.path.join(str(tmp_path), 'pseudos', 'directory'))
with open(os.path.join(str(tmp_path), 'pseudos', 'Ar.upf'), 'wb'):
pass

with pytest.raises(ValueError, match=r'dirpath `.*` contains at least one entry that is not a file'):
PseudoPotentialFamily.parse_pseudos_from_directory(str(tmpdir))
PseudoPotentialFamily.parse_pseudos_from_directory(str(tmp_path))


@pytest.mark.filterwarnings('ignore:no registered entry point for `SomeFamily` so its instances will not be storable.')
def test_parse_pseudos_from_directory_incorrect_pseudo_type(tmpdir):
def test_parse_pseudos_from_directory_incorrect_pseudo_type(tmp_path):
"""Test the `PseudoPotentialFamily.parse_pseudos_from_directory` for invalid ``pseudo_type`` arguments.
It should be in ``cls._pseudo_types`` and if not explicitly defined, ``cls._pseudo_types`` should only contain a
Expand All @@ -215,10 +215,10 @@ class SomeFamily(PseudoPotentialFamily):
_pseudo_types = (PsfData, UpfData)

with pytest.raises(ValueError, match=r'.* supports more than one type, so `pseudo_type` needs to be explicitly .*'):
SomeFamily.parse_pseudos_from_directory(str(tmpdir))
SomeFamily.parse_pseudos_from_directory(str(tmp_path))

with pytest.raises(ValueError, match=r'`.*` is not supported by `.*`'):
SomeFamily.parse_pseudos_from_directory(str(tmpdir), pseudo_type=PsmlData)
SomeFamily.parse_pseudos_from_directory(str(tmp_path), pseudo_type=PsmlData)


@pytest.mark.usefixtures('clear_db')
Expand Down

0 comments on commit 71a154f

Please sign in to comment.