diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 90e05c40..95179b06 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -8,4 +8,4 @@ updates: - package-ecosystem: "github-actions" # See documentation for possible values directory: "/" # Location of package manifests schedule: - interval: "weekly" + interval: "monthly" diff --git a/.github/workflows/pypi.yml b/.github/workflows/pypi.yml index bf03e224..5c21e748 100644 --- a/.github/workflows/pypi.yml +++ b/.github/workflows/pypi.yml @@ -10,6 +10,8 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 + with: + fetch-depth: 0 - name: Set up Python uses: actions/setup-python@v4 diff --git a/.github/workflows/pythonapp.yml b/.github/workflows/pythonapp.yml index 6a91417a..a3bf52e1 100644 --- a/.github/workflows/pythonapp.yml +++ b/.github/workflows/pythonapp.yml @@ -64,6 +64,8 @@ jobs: version: '3.11' steps: - uses: actions/checkout@v3 + with: + fetch-depth: 0 - name: Install cp2k if: matrix.special[0] == 'CP2K' @@ -88,11 +90,10 @@ jobs: case "${{ matrix.special[0] }}" in "pre-release") pip install --pre -e .[test] --upgrade --force-reinstall - pip uninstall plams -y; pip install git+https://github.com/SCM-NV/PLAMS@master --upgrade pip install git+https://github.com/NLeSC/noodles@master --upgrade ;; "no optional") - pip install -e .[test_no_optional] + pip install -e .[test-no-optional] ;; *) pip install -e .[test] @@ -133,6 +134,8 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 + with: + fetch-depth: 0 - name: Set up Python uses: actions/setup-python@v4 @@ -140,7 +143,7 @@ jobs: python-version: '3.x' - name: Install linters - run: pip install -r linting_requirements.txt + run: pip install .[lint] - name: Python info run: | @@ -151,7 +154,7 @@ jobs: run: pip list - name: Run flake8 - run: flake8 src test conftest.py setup.py + run: flake8 src test conftest.py - name: Run pydocstyle run: pydocstyle src diff --git a/.gitignore b/.gitignore index 6923337a..180a3695 100644 --- a/.gitignore +++ b/.gitignore @@ -22,6 +22,8 @@ var/ *.egg-info/ .installed.cfg *.egg +src/qmflows/_version.py +qmflows-*/ # PyInstaller # Usually these files are written by a python script from a template diff --git a/MANIFEST.in b/MANIFEST.in index 066ddf83..e4f15e37 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -1,3 +1,7 @@ -exclude test/* +exclude test/** +exclude docs/** +exclude jupyterNotebooks/** +exclude scripts/** +exclude qmflows.png include src/qmflows/py.typed include src/qmflows/data/dictionaries/*yaml diff --git a/linting_requirements.txt b/linting_requirements.txt deleted file mode 100644 index c0a4a28d..00000000 --- a/linting_requirements.txt +++ /dev/null @@ -1,11 +0,0 @@ -pydocstyle[toml]>=6.1 -flake8 -Flake8-pyproject>=1.2.2 - -mypy -numpy>=1.21 -pytest>=6.0 -more_itertools -types-PyYAML -types-setuptools -pyparsing>=3.0.8 diff --git a/pyproject.toml b/pyproject.toml index 218620c9..1fd989ed 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,3 +1,108 @@ +[build-system] +requires = [ + "setuptools>=61.0", + "wheel>=0.21", + "setuptools_scm[toml]>=6.2", +] +build-backend = "setuptools.build_meta" + +[project] +name = "qmflows" +dynamic = [ + "version", + "readme", +] +description = "Automation of computations in quantum chemistry." +license = { file = "LICENSE.md" } +authors = [ + { name = "Felipe Zapata", email = "f.zapata@esciencecenter.nl" }, +] +keywords = [ + "chemistry", + "workflows", + "simulation", + "materials", +] +classifiers = [ + "License :: OSI Approved :: GNU Lesser General Public License v3 (LGPLv3)", + "Intended Audience :: Science/Research", + "Programming Language :: Python", + "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3 :: Only", + "Programming Language :: Python :: 3.8", + "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", + "Development Status :: 5 - Production/Stable", + "Intended Audience :: Science/Research", + "Topic :: Scientific/Engineering :: Chemistry", + "Typing :: Typed", +] +requires-python = ">=3.8" +dependencies = [ + "more-itertools", + "h5py", + "numpy>=1.21", + "pandas", + "noodles>=0.3.3", + "plams==1.5.1", + "pyparsing!=3.0.0,<3.1.0", + "pyyaml>=5.1", + "filelock", + "packaging>=1.16.8", +] + +[project.urls] +Homepage = "https://github.com/SCM-NV/qmflows" +"Bug Tracker" = "https://github.com/SCM-NV/qmflows/issues" +Documentation = "https://qmflows.readthedocs.io/en/latest/" + +[project.optional-dependencies] +doc = [ + "sphinx>=2.1,!=3.1.1", + "sphinx-autodoc-typehints", + "sphinx_rtd_theme", + "nbsphinx", + "jupyter", + "pandoc", +] +lint = [ + "flake8", + "pydocstyle[toml]>=6.1", + "Flake8-pyproject>=1.2.2", + "mypy", + "types-PyYAML", + "types-setuptools", + "pytest>=6.0", +] +test = [ + "qmflows[test-no-optional]", + "rdkit>=2018.03.1", +] +test-no-optional = [ + "assertionlib>=3.1.0", + "pytest>=6.0", + "pytest-cov", + "pytest-mock", + "typing_extensions", +] + +[tool.setuptools.packages.find] +where = ["src"] +include = ["qmflows*"] + +[tool.setuptools.package-data] +FOX = [ + "data/dictionaries/*yaml", + "py.typed", +] + +[tool.setuptools.dynamic] +readme = { file = ["README.rst"], content-type = "text/x-rst" } + +[tool.setuptools_scm] +write_to = "src/qmflows/_version.py" + [tool.mypy] plugins = "numpy.typing.mypy_plugin" show_error_codes = true diff --git a/setup.py b/setup.py deleted file mode 100755 index 4239860b..00000000 --- a/setup.py +++ /dev/null @@ -1,98 +0,0 @@ -#!/usr/bin/env python - -from setuptools import setup -import os - -version_file = os.path.abspath(os.path.join( - os.path.dirname(__file__), - 'src', - 'qmflows', - '_version.py', -)) -version: "dict[str, str]" = {} -with open(version_file, 'r', encoding='utf8') as f: - exec(f.read(), version) - - -def readme() -> str: - """Load the readme file.""" - with open('README.rst', 'r', encoding='utf8') as f: - return f.read() - - -docs_require = [ - 'sphinx>=2.1,!=3.1.1', - 'sphinx-autodoc-typehints', - 'sphinx_rtd_theme', - 'nbsphinx', - 'jupyter', - 'pandoc', -] - -tests_no_optional_require = [ - 'assertionlib>=3.1.0', - 'pytest>=6.0', - 'pytest-cov', - 'pytest-mock', - 'typing_extensions' -] - -tests_require = tests_no_optional_require.copy() -tests_require.append("rdkit>=2018.03.1") - -setup( - name='qmflows', - version=version['__version__'], - description='Automation of computations in quantum chemistry', - license='LGPLv3', - url='https://github.com/SCM-NV/qmflows', - author='Felipe Zapata', - author_email='f.zapata@esciencecenter.nl', - keywords='chemistry workflows simulation materials', - long_description=readme(), - package_dir={'': 'src'}, - packages=["qmflows", - "qmflows.components", - "qmflows.data", - "qmflows.data.dictionaries", - "qmflows.examples", - "qmflows.examples.Conditional_workflows", - "qmflows.examples.Constrained_and_TS_optimizations", - "qmflows.packages", - "qmflows.parsers", - "qmflows.templates"], - package_data={ - "qmflows": ['data/dictionaries/*yaml', - 'py.typed'] - }, - python_requires='>=3.8', - classifiers=[ - 'License :: OSI Approved :: GNU Lesser General Public License v3 (LGPLv3)', - 'Intended Audience :: Science/Research', - 'Programming Language :: Python :: 3.8', - 'Programming Language :: Python :: 3.9', - 'Programming Language :: Python :: 3.10', - 'Programming Language :: Python :: 3.11', - 'Development Status :: 5 - Production/Stable', - 'Intended Audience :: Science/Research', - 'Topic :: Scientific/Engineering :: Chemistry', - 'Typing :: Typed', - ], - install_requires=[ - 'more-itertools', - 'h5py', - 'numpy', - 'pandas', - 'noodles>=0.3.3', - 'plams>=1.5.1', - 'pyparsing!=3.0.0,<3.1.0', - 'pyyaml>=5.1', - 'filelock', - 'packaging>=1.16.8', - ], - extras_require={ - 'test': tests_require, - 'test_no_optional': tests_no_optional_require, - 'doc': docs_require, - } -) diff --git a/src/qmflows/__init__.py b/src/qmflows/__init__.py index 3478236f..409b0fde 100644 --- a/src/qmflows/__init__.py +++ b/src/qmflows/__init__.py @@ -7,8 +7,7 @@ import sys from typing import TYPE_CHECKING -from ._version import __version__ as __version__ -from ._version_info import version_info as version_info +from ._version import __version__, __version_tuple__ from ._logger import logger @@ -28,6 +27,7 @@ _RDKIT_EX = None __all__ = [ + '__verion__', '__version_tuple__', 'logger', 'InitRestart', 'Angle', 'Dihedral', 'Distance', 'Settings', diff --git a/src/qmflows/_version.py b/src/qmflows/_version.py deleted file mode 100644 index 5e12247a..00000000 --- a/src/qmflows/_version.py +++ /dev/null @@ -1,3 +0,0 @@ -"""The QMFlows version.""" - -__version__ = "1.0.0b2.dev0" diff --git a/src/qmflows/_version_info.py b/src/qmflows/_version_info.py deleted file mode 100644 index 7835490a..00000000 --- a/src/qmflows/_version_info.py +++ /dev/null @@ -1,40 +0,0 @@ -from typing import NamedTuple, Final - -from packaging.version import Version - -from ._version import __version__ - -__all__ = ["version_info"] - - -class VersionInfo(NamedTuple): - """A :func:`~collections.namedtuple` representing the version of a package.""" - - #: :class:`int`: The semantic_ major version. - major: int = 0 - - #: :class:`int`: The semantic_ minor version. - minor: int = 0 - - #: :class:`int`: The semantic_ micro version. - micro: int = 0 - - @property - def patch(self) -> int: - """:class:`int`: An alias for :attr:`VersionInfo.micro`.""" - return self.micro - - @property - def maintenance(self) -> int: - """:class:`int`: An alias for :attr:`VersionInfo.micro`.""" - return self.micro - - @property - def bug(self) -> int: - """:class:`int`: An alias for :attr:`VersionInfo.micro`.""" - return self.micro - - -VERSION = Version(__version__) - -version_info: Final = VersionInfo._make(VERSION.release[:3]) diff --git a/test/test_version.py b/test/test_version.py deleted file mode 100644 index f27c7bef..00000000 --- a/test/test_version.py +++ /dev/null @@ -1,16 +0,0 @@ -import pytest -from assertionlib import assertion -from packaging.version import Version - -from qmflows import version_info, __version__ - - -def test_pep_440() -> None: - assertion.assert_(Version, __version__) - - -@pytest.mark.parametrize("name", ["major", "minor", "micro", "patch", "bug", "maintenance"]) -def test_version_info(name: str) -> None: - attr: int = getattr(version_info, name) - assertion.isinstance(attr, int) - assertion.ge(attr, 0)