diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 108edf8ed..fff552d58 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -1,14 +1,6 @@ name: CI on: - push: - branches: - - "main" - - "maintenance/.*" - pull_request: - branches: - - "main" - - "maintenance/.*" schedule: # Nightly tests run on main by default: # Scheduled workflows run on the latest commit on the default or base branch. @@ -41,7 +33,6 @@ jobs: env: OE_LICENSE: ${{ github.workspace }}/oe_license.txt - PACKAGE: openff PYTEST_ARGS: -r fE --tb=short -nauto COV: --cov=openff/toolkit --cov-config=setup.cfg --cov-append --cov-report=xml diff --git a/.github/workflows/conda.yml b/.github/workflows/conda.yml index 4e0d33b1d..57e578fd7 100644 --- a/.github/workflows/conda.yml +++ b/.github/workflows/conda.yml @@ -1,6 +1,7 @@ name: Conda latest on: + push: release: types: - released @@ -20,59 +21,43 @@ jobs: strategy: fail-fast: false matrix: - os: [ubuntu-latest, macos-latest] - python-version: ["3.9", "3.10"] + os: [ubuntu-latest] + python-version: ["3.11"] openeye: ["true", "false"] env: - CI_OS: ${{ matrix.os }} OPENEYE: ${{ matrix.openeye }} - PYVER: ${{ matrix.python-version }} OE_LICENSE: ${{ github.workspace }}/oe_license.txt - PACKAGE: openff-toolkit + PYTEST_ARGS: -r fE --tb=short steps: - - uses: actions/checkout@v4 - - name: Vanilla install from conda uses: mamba-org/setup-micromamba@v1 - if: ${{ matrix.openeye == 'false' }} - with: - environment-file: devtools/conda-envs/conda.yaml - create-args: >- - python=${{ matrix.python-version }} - - name: Install from conda with OpenEye - uses: mamba-org/setup-micromamba@v1 - if: ${{ matrix.openeye == 'true' }} with: - environment-file: devtools/conda-envs/conda_oe.yaml + environment-name: latest-deployment create-args: >- python=${{ matrix.python-version }} + openff-toolkit-examples + pytest-xdist + pytest-rerunfailures - - name: Additional info about the build - run: | - uname -a - df -h - ulimit -a + - name: Install OpenEye Toolkits + if: ${{ matrix.openeye == 'true' }} + run: micromamba install openeye-toolkits -c openeye - name: Make oe_license.txt file from GH org secret "OE_LICENSE" + if: ${{ matrix.openeye == 'true' }} env: OE_LICENSE_TEXT: ${{ secrets.OE_LICENSE }} run: | echo "${OE_LICENSE_TEXT}" > ${OE_LICENSE} - name: Environment Information - run: | - conda info - conda list + run: micromamba info && micromamba list - name: Check installed toolkits run: | - # Checkout the state of the repo as of the last release (including RCs) export LATEST_TAG=$(git ls-remote --tags https://github.com/openforcefield/openff-toolkit.git | cut -f2 | grep -E "([0-9]+)\.([0-9]+)\.([0-9]+)$" | sort --version-sort | tail -1 | sed 's/refs\/tags\///') - git fetch --tags - git checkout tags/$LATEST_TAG - git log -1 | cat if [[ "$OPENEYE" == true ]]; then python -c "from openff.toolkit.utils.toolkits import OPENEYE_AVAILABLE; assert OPENEYE_AVAILABLE, 'OpenEye unavailable'" @@ -86,9 +71,6 @@ jobs: - name: Check that correct OFFTK version was installed run: | - # Go up one directory to ensure that we don't just load the OFFTK from the checked-out repo - cd ../ - export LATEST_TAG=$(git ls-remote --tags https://github.com/openforcefield/openff-toolkit.git | cut -f2 | grep -E "([0-9]+)\.([0-9]+)\.([0-9]+)$" | sort --version-sort | tail -1 | sed 's/refs\/tags\///') export FOUND_VER=$(python -c "import openff.toolkit; print(openff.toolkit.__version__)") @@ -102,20 +84,14 @@ jobs: exit 1 fi - cd openff-toolkit - - name: Test the package run: | - python -m pip install utilities/test_plugins - - pwd - ls - if [[ "$OPENEYE" == true ]]; then python -c "import openff.toolkit; print(openff.toolkit.__file__)" python -c "import openeye; print(openeye.oechem.OEChemIsLicensed())" fi - PYTEST_ARGS=" -r fE --tb=short --runslow openff/toolkit/_tests/conftest.py" - PYTEST_ARGS+=" --ignore=openff/toolkit/_tests/test_links.py" - pytest $PYTEST_ARGS openff + # PYTEST_ARGS+=" --runslow -x" + # PYTEST_ARGS+=" --ignore=openff/toolkit/_tests/test_links.py" + + python -m pytest --pyargs "openff.toolkit" $PYTEST_ARGS $COV --trace-config diff --git a/.github/workflows/examples.yml b/.github/workflows/examples.yml index d03bc2ec2..d2fc904d4 100644 --- a/.github/workflows/examples.yml +++ b/.github/workflows/examples.yml @@ -1,14 +1,6 @@ name: Examples on: - push: - branches: - - "main" - - "maintenance/.+" - pull_request: - branches: - - "main" - - "maintenance/.+" schedule: - cron: "0 0 * * *" @@ -66,24 +58,13 @@ jobs: create-args: >- python=${{ matrix.python-version }} - - name: Additional info about the build - run: | - uname -a - df -h - ulimit -a - - name: Make oe_license.txt file from GH org secret "OE_LICENSE" env: OE_LICENSE_TEXT: ${{ secrets.OE_LICENSE }} - run: | - echo "${OE_LICENSE_TEXT}" > ${OE_LICENSE} + run: echo "${OE_LICENSE_TEXT}" > ${OE_LICENSE} - name: Install package - run: | - # Maybe remove the packaged openff-toolkit, installed as a dependency of openmmforcefields - # and/or Interchange - micromamba remove --force openff-toolkit-base - python -m pip install . + run: python -m pip install . - name: Remove undesired toolkits run: | @@ -92,7 +73,7 @@ jobs: # so don't remove it. if [ ! -z "${{ env.PACKAGES_TO_REMOVE }}" ]; then for cpkg in ${{ env.PACKAGES_TO_REMOVE }}; do - if [[ $(conda list | grep $cpkg) ]]; then micromamba remove --force $cpkg --yes ; fi + if [[ $(micromamba list | grep $cpkg) ]]; then micromamba remove --force $cpkg --yes ; fi done fi @@ -119,10 +100,11 @@ jobs: python -c "from openff.toolkit.utils.toolkits import ${TK}_AVAILABLE; assert not ${TK}_AVAILABLE, '${TK} available'" done fi + - name: Environment Information run: | - conda info - conda list + micromamba info + micromamba list - name: Run example scripts run: | diff --git a/devtools/conda-envs/conda.yaml b/devtools/conda-envs/conda.yaml deleted file mode 100644 index ec34886aa..000000000 --- a/devtools/conda-envs/conda.yaml +++ /dev/null @@ -1,9 +0,0 @@ -name: latest-deployment -channels: - - conda-forge -dependencies: - # Base depends - - openff-toolkit-examples - # Tests - - pytest=7.4 - - pytest-rerunfailures diff --git a/devtools/conda-envs/conda_oe.yaml b/devtools/conda-envs/conda_oe.yaml deleted file mode 100644 index d379d4cb2..000000000 --- a/devtools/conda-envs/conda_oe.yaml +++ /dev/null @@ -1,11 +0,0 @@ -name: latest-deployment -channels: - - conda-forge - - openeye -dependencies: - # Base depends - - openff-toolkit-examples - # Tests - - openeye-toolkits - - pytest=7.4 - - pytest-rerunfailures diff --git a/openff/toolkit/_tests/test_forcefield.py b/openff/toolkit/_tests/test_forcefield.py index e7b836491..3fcf99e42 100644 --- a/openff/toolkit/_tests/test_forcefield.py +++ b/openff/toolkit/_tests/test_forcefield.py @@ -6,6 +6,7 @@ import copy import itertools import os +import re from tempfile import NamedTemporaryFile import numpy as np @@ -899,31 +900,33 @@ def test_create_forcefield_from_file(self, force_field): assert force_field.aromaticity_model == "OEAroModel_MDL" def test_load_bad_string(self): - with pytest.raises(IOError) as exception_info: + # This exception is a multi-line string, and `.*` by default doesn't + # consider newlines, so need to copmile with re.DOTALL flag + with pytest.raises( + IOError, + match=re.compile( + "Source '1234' could not be read.*" + "openforcefield.*" + "SMIRNOFFParseError.*" + "syntax error", + flags=re.DOTALL, + ), + ): ForceField("1234") - # This may need to be updated if the `openforcefields` package changes name; - # searching through `site-packages/` and other paths is probably unrelaiable - for match in [ - "Source '1234' could not be read", - "SMIRNOFFParseError", - "syntax error", - "openforcefields", - ]: - assert match in str(exception_info.value) - def test_load_bad_bytes(self): - with pytest.raises(IOError) as exception_info: + with pytest.raises( + IOError, + match=re.compile( + "Source 'b'the holy grail.*" + "could not be read.*" + "SMIRNOFFParseError.*" + "syntax error.*", + flags=re.DOTALL, + ), + ) as exception_info: ForceField(b"the holy grail of computational chemistry") - for match in [ - "Source 'b'the holy grail", - "could not be read", - "SMIRNOFFParseError", - "syntax error", - ]: - assert match in str(exception_info.value) - # See note in test_load_bad_string assert "openforcefields" not in str(exception_info.value) @@ -933,13 +936,12 @@ def test_load_filelike_object(self): def test_load_bad_filelike_object(self): with open(get_data_file_path("test_forcefields/mangled.offxml")) as f: - with pytest.raises(IOError) as exception_info: + with pytest.raises( + IOError, + match="while trying to parse source as an object", + ): ForceField(f) - assert "while trying to parse source as an object" in str( - exception_info.value - ) - def test_create_forcefield_from_xml_string(self): forcefield = ForceField(xml_simple_ff) assert len(forcefield._parameter_handlers["Bonds"]._parameters) == 3 diff --git a/openff/toolkit/typing/engines/smirnoff/forcefield.py b/openff/toolkit/typing/engines/smirnoff/forcefield.py index b4adc8c5c..27b0be4e6 100644 --- a/openff/toolkit/typing/engines/smirnoff/forcefield.py +++ b/openff/toolkit/typing/engines/smirnoff/forcefield.py @@ -797,9 +797,12 @@ def parse_sources(self, sources, allow_cosmetic_attributes=True): # TODO: If a non-first source fails here, the force field might be partially modified for source in sources: smirnoff_data = self.parse_smirnoff_from_source(source) - self._load_smirnoff_data( - smirnoff_data, allow_cosmetic_attributes=allow_cosmetic_attributes - ) + try: + self._load_smirnoff_data( + smirnoff_data, allow_cosmetic_attributes=allow_cosmetic_attributes + ) + except Exception as error: + raise TypeError(f"{smirnoff_data=}\n{source=}\n{sources=}\n") from error def _to_smirnoff_data(self, discard_cosmetic_attributes=False) -> dict: """