diff --git a/.docs/md/generate_classes.md b/.docs/md/generate_classes.md index 7056918174..a7b466194e 100644 --- a/.docs/md/generate_classes.md +++ b/.docs/md/generate_classes.md @@ -97,7 +97,3 @@ $ python -m flopy.mf6.utils.generate_classes --dfnpath ../your/dfn/path Branch names, commit hashes, or tags may be provided to `ref`. By default, a backup is made of FloPy's package classes before rewriting them. To disable backups, use `--no-backup` from command-line, or `backup=False` with the Python function. - -## Testing class generation - -Tests for the `generate_classes()` utility are located in `test_generate_classes.py`. The tests depend on [`pytest-virtualenv`](https://pypi.org/project/pytest-virtualenv/) and will be skipped if run in parallel without the `--dist loadfile` option for `pytest-xdist`. diff --git a/.github/workflows/commit.yml b/.github/workflows/commit.yml index 7765c4fd6c..ba88366f2b 100644 --- a/.github/workflows/commit.yml +++ b/.github/workflows/commit.yml @@ -151,7 +151,7 @@ jobs: fail-fast: false matrix: os: [ ubuntu-latest, macos-latest, windows-latest ] - python-version: [ 3.8, 3.9, "3.10", "3.11" ] + python-version: [ 3.8, 3.9, "3.10", "3.11", "3.12" ] exclude: # avoid shutil.copytree infinite recursion bug # https://github.com/python/cpython/pull/17098 @@ -193,13 +193,6 @@ jobs: bash powershell - - name: Install Python dependencies - shell: bash -l {0} - if: runner.os == 'Windows' - run: | - pip install xmipy - pip install . - - name: Install Modflow-related executables uses: modflowpy/install-modflow-action@v1 diff --git a/autotest/conftest.py b/autotest/conftest.py index b85458c044..6549d99e36 100644 --- a/autotest/conftest.py +++ b/autotest/conftest.py @@ -1,18 +1,8 @@ -import importlib -import os import re -import socket -import sys from importlib import metadata -from os import environ -from os.path import basename, normpath from pathlib import Path from platform import system -from shutil import copytree, which -from subprocess import PIPE, Popen -from typing import List, Optional -from urllib import request -from warnings import warn +from typing import List import matplotlib.pyplot as plt import pytest @@ -28,7 +18,7 @@ SHAPEFILE_EXTENSIONS = ["prj", "shx", "dbf"] -# misc utilities +# path utilities def get_project_root_path() -> Path: @@ -43,7 +33,7 @@ def get_flopy_data_path() -> Path: return get_project_root_path() / "flopy" / "data" -# path fixtures +# fixtures @pytest.fixture(scope="session") @@ -66,11 +56,9 @@ def example_shapefiles(example_data_path) -> List[Path]: return [f.resolve() for f in (example_data_path / "prj_test").glob("*")] -# fixture to automatically close any plots (or optionally show them) - - @pytest.fixture(autouse=True) def close_plot(request): + # fixture to automatically close any plots (or optionally show them) yield # plots only shown if requested via CLI flag, @@ -118,14 +106,6 @@ def pytest_addoption(parser): "but automated tests should probably also check patch collections or figure & axis properties.)", ) - # for test_generate_classes.py - parser.addoption( - "--ref", - action="append", - type=str, - help="Include extra refs to test. Useful for testing branches on a fork, e.g. /modflow6/.", - ) - def pytest_report_header(config): """Header for pytest to show versions of packages.""" diff --git a/autotest/test_generate_classes.py b/autotest/test_generate_classes.py deleted file mode 100644 index cff9a37f31..0000000000 --- a/autotest/test_generate_classes.py +++ /dev/null @@ -1,138 +0,0 @@ -import sys -from datetime import datetime -from os import environ -from pathlib import Path -from pprint import pprint -from typing import Iterable -from warnings import warn - -import pytest -from modflow_devtools.misc import get_current_branch - -branch = get_current_branch() - - -def nonempty(itr: Iterable): - for x in itr: - if x: - yield x - - -def pytest_generate_tests(metafunc): - # defaults - owner = "MODFLOW-USGS" - repo = "modflow6" - ref = [ - f"{owner}/{repo}/develop", - f"{owner}/{repo}/master", - f"{owner}/{repo}/6.4.1", - f"{owner}/{repo}/4458f9f", - f"{owner}/{repo}/4458f9f7a6244182e6acc2430a6996f9ca2df367", - ] - - # refs provided as env vars override the defaults - ref_env = environ.get("TEST_GENERATE_CLASSES_REF") - if ref_env: - ref = nonempty(ref_env.strip().split(",")) - - # refs given as CLI options override everything - ref_opt = metafunc.config.getoption("--ref") - if ref_opt: - ref = nonempty([o.strip() for o in ref_opt]) - - # drop duplicates - ref = list(dict.fromkeys(ref)) - - # drop and warn refs with invalid format - # i.e. not "owner/repo/branch" - for r in ref: - spl = r.split("/") - if len(spl) != 3 or not all(spl): - warn(f"Skipping invalid ref: {r}") - ref.remove(r) - - key = "ref" - if key in metafunc.fixturenames: - metafunc.parametrize(key, ref, scope="session") - - -@pytest.mark.mf6 -@pytest.mark.slow -@pytest.mark.regression -@pytest.mark.skipif( - branch == "master" or branch.startswith("v"), - reason="skip on master and release branches", -) -def test_generate_classes_from_github_refs( - request, virtualenv, project_root_path, ref, worker_id -): - argv = ( - request.config.workerinput["mainargv"] - if hasattr(request.config, "workerinput") - else [] - ) - if worker_id != "master" and "loadfile" not in argv: - pytest.skip("can't run in parallel") - - python = virtualenv.python - venv = Path(python).parent - print( - f"Using temp venv at {venv} with python {python} to test class generation from {ref}" - ) - - # install flopy/dependencies - pprint(virtualenv.run(f"pip install {project_root_path}")) - for dependency in ["modflow-devtools"]: - pprint(virtualenv.run(f"pip install {dependency}")) - - # get creation time of files - flopy_path = ( - venv.parent - / "lib" - / f"python{sys.version_info.major}.{sys.version_info.minor}" - / "site-packages" - / "flopy" - ) - assert flopy_path.is_dir() - mod_files = list((flopy_path / "mf6" / "modflow").rglob("*")) + list( - (flopy_path / "mf6" / "data" / "dfn").rglob("*") - ) - mod_file_times = [Path(mod_file).stat().st_mtime for mod_file in mod_files] - pprint(mod_files) - - # split ref into owner, repo, ref name - spl = ref.split("/") - owner = spl[0] - repo = spl[1] - ref = spl[2] - - # generate classes - pprint( - virtualenv.run( - "python -m flopy.mf6.utils.generate_classes " - f"--owner {owner} --repo {repo} --ref {ref} --no-backup" - ) - ) - - def get_mtime(f): - try: - return Path(f).stat().st_mtime - except: - return 0 # if file not found - - # make sure files were regenerated - modified_files = [ - mod_files[i] - for i, (before, after) in enumerate( - zip( - mod_file_times, - [get_mtime(f) for f in mod_files], - ) - ) - if after > 0 and after > before - ] - assert any(modified_files) - print(f"{len(modified_files)} files were modified:") - pprint(modified_files) - - # todo checkout mf6 and test with dfnpath? test with backups? diff --git a/etc/environment.yml b/etc/environment.yml index d4a6b62a55..592e4cad0f 100644 --- a/etc/environment.yml +++ b/etc/environment.yml @@ -27,7 +27,6 @@ dependencies: - pytest-cases - pytest-cov - pytest-dotenv - - pytest-virtualenv - pytest-xdist - virtualenv @@ -52,4 +51,4 @@ dependencies: - pymetis # MODFLOW API dependencies - - bmipy + - xmipy diff --git a/pyproject.toml b/pyproject.toml index 95ecd5ac78..7acafa0b3a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -55,7 +55,6 @@ test = [ "pytest-cases", "pytest-cov", "pytest-dotenv", - "pytest-virtualenv", "pytest-xdist", "virtualenv" ]