From 6571d3c1becde879a8e6c8ee78436462d5caccc7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20C=2E=20Riven=C3=A6s?= Date: Tue, 24 Oct 2023 13:48:13 +0200 Subject: [PATCH] Convert to pure pyproject.toml setup --- .flake8 | 4 + .github/workflows/ci-fmudataio.yml | 3 +- .github/workflows/fmudataio-publish-pypi.yml | 6 +- .github/workflows/linting.yml | 4 +- .pylintrc | 44 ------ .readthedocs.yml | 1 - README.md | 5 +- pyproject.toml | 145 ++++++++++++++++++- pytest.ini | 10 -- requirements/requirements.txt | 6 - requirements/requirements_docs.txt | 7 - requirements/requirements_setup.txt | 8 - requirements/requirements_test.txt | 3 - requirements/requirements_testx.txt | 7 - scripts/README.txt | 3 - scripts/setup_functions.py | 97 ------------- setup.cfg | 41 ------ setup.py | 69 --------- 18 files changed, 155 insertions(+), 308 deletions(-) create mode 100644 .flake8 delete mode 100644 .pylintrc delete mode 100644 pytest.ini delete mode 100644 requirements/requirements.txt delete mode 100644 requirements/requirements_docs.txt delete mode 100644 requirements/requirements_setup.txt delete mode 100644 requirements/requirements_test.txt delete mode 100644 requirements/requirements_testx.txt delete mode 100644 scripts/README.txt delete mode 100644 scripts/setup_functions.py delete mode 100644 setup.cfg delete mode 100755 setup.py diff --git a/.flake8 b/.flake8 new file mode 100644 index 000000000..51dde5049 --- /dev/null +++ b/.flake8 @@ -0,0 +1,4 @@ +[flake8] +max-line-length = 88 +ignore = W503, E203 +exclude = docs/conf.py, .eggs, version.py diff --git a/.github/workflows/ci-fmudataio.yml b/.github/workflows/ci-fmudataio.yml index 674bf735b..9f70338f8 100644 --- a/.github/workflows/ci-fmudataio.yml +++ b/.github/workflows/ci-fmudataio.yml @@ -27,9 +27,8 @@ jobs: - name: Install fmu-dataio run: > pip install pip -U && - pip install . + pip install .[dev] - name: Full test run: > - pip install -r requirements/requirements_test.txt && pytest --disable-warnings -x diff --git a/.github/workflows/fmudataio-publish-pypi.yml b/.github/workflows/fmudataio-publish-pypi.yml index 07802fcf0..39e9123bb 100644 --- a/.github/workflows/fmudataio-publish-pypi.yml +++ b/.github/workflows/fmudataio-publish-pypi.yml @@ -14,10 +14,10 @@ jobs: uses: actions/setup-python@v4 with: python-version: "3.10" - - name: Install dependencies - run: pip install --upgrade setuptools wheel twine + - name: Install pypa/build + run: python -m pip install build twine - name: Build package - run: python setup.py sdist bdist_wheel + run: python -m build . --sdist --wheel --outdir dist/ - name: Upload deploy env: TWINE_USERNAME: __token__ diff --git a/.github/workflows/linting.yml b/.github/workflows/linting.yml index 30701d5c0..a51fa0a32 100644 --- a/.github/workflows/linting.yml +++ b/.github/workflows/linting.yml @@ -16,8 +16,8 @@ jobs: - name: Check black style and linting run: | pip install black - black --check *.py src tests + black --check src tests pip install flake8 flake8 src tests pip install isort - isort --profile=black *.py src tests + isort --profile=black src tests diff --git a/.pylintrc b/.pylintrc deleted file mode 100644 index 436ae3349..000000000 --- a/.pylintrc +++ /dev/null @@ -1,44 +0,0 @@ - -[MASTER] -ignore=version.py, setup.py, conf.py - -[BASIC] -good-names=logger, version, i, j, k, x, y, z, _ -additional-builtins=_x, _y, _z, _tmp1, _tmp2 -variable-rgx=^[a-z_][_a-z0-9]+((_[a-z0-9]+)*)?$ -argument-rgx=^[a-z_][_a-z0-9]+((_[a-z0-9]+)*)?$ -dummy-variables-rgx=^_+[a-z0-9]*?$|dummy - -[TYPECHECK] -generated-members=np.*, numpy.*, pd.*, pandas.* - -[FORMAT] -max-line-length=88 -max-module-lines=3000 - -[DESIGN] -max-attributes=30 -max-args=20 -max-locals=30 -max-branches=15 -max-bool-expr=8 - -[SIMILARITIES] -min-similarity-lines=40 -ignore-comments=yes -ignore-docstrings=no -ignore-imports=yes - -[MESSAGES CONTROL] -disable= - fixme, - missing-docstring, - protected-access, - C0330, - useless-object-inheritance, - import-outside-toplevel, - import-error, - no-name-in-module, - raise-missing-from, - unspecified-encoding, - wrong-import-order diff --git a/.readthedocs.yml b/.readthedocs.yml index e9631033a..16896c970 100644 --- a/.readthedocs.yml +++ b/.readthedocs.yml @@ -10,7 +10,6 @@ build: python: install: - - requirements: requirements/requirements.txt - method: pip path: .[docs] diff --git a/README.md b/README.md index 5ed659c0b..87991ff5f 100644 --- a/README.md +++ b/README.md @@ -52,10 +52,9 @@ pip install -e . ``` Install requirements for running tests: ```console -pip install -e .[tests,docs] +pip install -e .[dev,docs] ``` -Then run the command: +Then run the command: ```console pytest ``` - diff --git a/pyproject.toml b/pyproject.toml index 9166d65d6..24f7c566a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,4 +1,82 @@ # NOTE: you have to use single-quoted strings in TOML for regular expressions. +[build-system] +requires = ["pip>=19.1.1", "setuptools", "setuptools_scm[toml]>=6.2"] +build-backend = "setuptools.build_meta" + +[project] +name = "fmu-dataio" +description = "Facilitate data io in FMU with rich metadata" +readme = "README.md" +requires-python = ">=3.8" +license = { text = "Apache 2.0" } +authors = [{ name = "Equinor", email = "xxxxx@equinor.com" }] +keywords = ["fmu", "sumo"] + +classifiers = [ + "Development Status :: 5 - Production/Stable", + "Intended Audience :: Developers", + "Intended Audience :: Science/Research", + "License :: OSI Approved :: Apache Software License", + "Natural Language :: English", + "Programming Language :: Python", + "Programming Language :: Python :: 3.8", + "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", + "Topic :: Scientific/Engineering", + "Topic :: Scientific/Engineering :: Physics", + "Topic :: Software Development :: Libraries", + "Topic :: Utilities", +] +dynamic = ["version"] +dependencies = [ + "xtgeo>=2.16", + "PyYAML", + "pyarrow", + "fmu-config>=1.1.0", + "pandas", + "numpy", +] + +[project.urls] +Homepage = "https://github.com/equinor/fmu-dataio" +Repository = "https://github.com/equinor/fmu-dataio" +Issues = "https://github.com/equinor/fmu-dataio/issues" +Documentation = "https://fmu-dataio.readthedocs.io" + +[project.optional-dependencies] +dev = [ + "black", + "coverage>=4.1", + "flake8", + "isort", + "jsonschema", + "hypothesis", + "mypy", + "pylint", + "pytest", + "pytest-cov", + "pydocstyle", + "pytest-runner", + "pytest-mock", + "termcolor", + "rstcheck", +] +docs = [ + "pydocstyle", + "Sphinx<7", + "autoapi", + "sphinx-rtd-theme", + "sphinx-autodoc-typehints<1.23", + "sphinxcontrib-apidoc", + "sphinx-togglebutton", + "urllib3<1.27", +] + +[project.entry-points.ert] +dataio_case_metadata = "fmu.dataio.scripts.create_case_metadata" + + [tool.black] line-length = 88 target-version = ['py38', 'py39', 'py310', 'py311'] @@ -25,5 +103,68 @@ exclude = ''' [tool.isort] profile = "black" -[build-system] -requires = ["pip>=19.1.1", "setuptools>=28", "setuptools_scm>=3.2.0", "pyarrow"] + +[tool.setuptools_scm] +write_to = "src/fmu/dataio/version.py" + +[tool.pytest.ini_options] +minversion = "6.0" +addopts = "--verbose" +log_cli = "False" +log_cli_format = "%(levelname)8s (%(relativeCreated)6.0fms) %(filename)44s [%(funcName)40s()] %(lineno)4d >> %(message)s" +log_cli_level = "INFO" +testpaths = "tests" +markers = ["integration: marks a test as an integration test"] +xfail_strict = true + +[tool.mypy] +ignore_missing_imports = true + +[tool.pydocstyle] +convention = "google" +match = '(?!(test_|_)).*\.py' + +[tool.pylint.MASTER] +ignore = ["version.py", "conf.py"] + +[tool.pylint.BASIC] +additional-builtins = ["_x", "_y", "_z", "_tmp1", "_tmp2"] +good-names = ["logger", "version", "i", "j", "k", "x", "y", "z", "_"] +variable-rgx = "^[a-z_][_a-z0-9]+((_[a-z0-9]+)*)?$" +argument-rgx = "^[a-z_][_a-z0-9]+((_[a-z0-9]+)*)?$" +dummy-variables-rgx = "^_+[a-z0-9]*?$|dummy" + +[tool.pylint.TYPECHECK] +generated-members = ["np.*", "numpy.*", "pd.*", "pandas.*"] + +[tool.pylint.FORMAT] +max-line-length = 88 +max-module-lines = 3000 + +[tool.pylint.DESIGN] +max-attributes = 30 +max-args = 20 +max-locals = 30 +max-branches = 15 +max-bool-expr = 8 + +[tool.pylint.SIMILARITIES] +min-similarity-lines = 40 +ignore-comments = "yes" +ignore-docstrings = "no" +ignore-imports = "yes" + +[tool.pylint."MESSAGES CONTROL"] +disable = """ + fixme, + missing-docstring, + protected-access, + C0330, + useless-object-inheritance, + import-outside-toplevel, + import-error, + no-name-in-module, + raise-missing-from, + unspecified-encoding, + wrong-import-order + """ diff --git a/pytest.ini b/pytest.ini deleted file mode 100644 index dcc2682ea..000000000 --- a/pytest.ini +++ /dev/null @@ -1,10 +0,0 @@ -#pytest tests/test_grid3d/test_grid.py::test_roffbin_import_v2_emerald -o log_cli=true -s - -[pytest] -minversion = 6.0 -addopts = --verbose -log_cli = False -log_cli_format = %(levelname)8s (%(relativeCreated)6.0fms) %(name)37s [%(funcName)42s()] %(lineno)4d >> %(message)s -log_cli_level = INFO -testpaths = - tests diff --git a/requirements/requirements.txt b/requirements/requirements.txt deleted file mode 100644 index 0da7f44e8..000000000 --- a/requirements/requirements.txt +++ /dev/null @@ -1,6 +0,0 @@ -xtgeo>=2.16 -PyYAML -# skip pyarrow for RMS 11 and 12.0 which uses python 3.6.1 and too old numpy 1.13.3 -pyarrow; python_version > "3.6.1" -jsonschema>=3.2.0 -fmu-config>=1.1.0 diff --git a/requirements/requirements_docs.txt b/requirements/requirements_docs.txt deleted file mode 100644 index 36e559a8f..000000000 --- a/requirements/requirements_docs.txt +++ /dev/null @@ -1,7 +0,0 @@ -sphinx<7 -sphinx-rtd-theme -autoapi -sphinx-autodoc-typehints<1.23 -sphinxcontrib-apidoc -sphinx-togglebutton -urllib3<1.27 diff --git a/requirements/requirements_setup.txt b/requirements/requirements_setup.txt deleted file mode 100644 index dfabd0798..000000000 --- a/requirements/requirements_setup.txt +++ /dev/null @@ -1,8 +0,0 @@ -setuptools>=28 -setuptools_scm -pytest-runner -black -pylint -flake8 -types-PyYAML -mypy diff --git a/requirements/requirements_test.txt b/requirements/requirements_test.txt deleted file mode 100644 index 423297925..000000000 --- a/requirements/requirements_test.txt +++ /dev/null @@ -1,3 +0,0 @@ -pytest -fmu-config -termcolor diff --git a/requirements/requirements_testx.txt b/requirements/requirements_testx.txt deleted file mode 100644 index 4e587f336..000000000 --- a/requirements/requirements_testx.txt +++ /dev/null @@ -1,7 +0,0 @@ -# Extras for tests, formatting and linting -black>=20.8b0 -flake8 -isort -pytest-cov -pytest-mock -rstcheck diff --git a/scripts/README.txt b/scripts/README.txt deleted file mode 100644 index fc73810f7..000000000 --- a/scripts/README.txt +++ /dev/null @@ -1,3 +0,0 @@ -Helper functions and extra requirements for setup.py. - -The purpose is to keep setup.py lean and clean diff --git a/scripts/setup_functions.py b/scripts/setup_functions.py deleted file mode 100644 index 194c54227..000000000 --- a/scripts/setup_functions.py +++ /dev/null @@ -1,97 +0,0 @@ -"""Setup helpers for setup.py in fmu.dataio package.""" -import fnmatch -import os -from distutils.command.clean import clean as _clean -from os.path import exists -from shutil import rmtree -from urllib.parse import urlparse - -from pip._internal.req import parse_requirements as parse - - -def _format_requirement(req): - if req.is_editable: - # parse out egg=... fragment from VCS URL - parsed = urlparse(req.requirement) - egg_name = parsed.fragment.partition("egg=")[-1] - without_fragment = parsed._replace(fragment="").geturl() - return f"{egg_name} @ {without_fragment}" - return req.requirement - - -def parse_requirements(fname): - """Turn requirements.txt into a list""" - reqs = parse(fname, session="test") - return [_format_requirement(ir) for ir in reqs] - - -# ====================================================================================== -# Overriding and extending setup commands; here "clean" -# ====================================================================================== - - -class CleanUp(_clean): - """Custom implementation of ``clean`` command. - - Overriding clean in order to get rid if "dist" folder and etc, see setup.py. - """ - - CLEANFOLDERS = ( - "__pycache__", - "pip-wheel-metadata", - ".eggs", - "dist", - "build", - "sdist", - "wheel", - ".pytest_cache", - "docs/apiref", - "docs/_build", - ) - - CLEANFOLDERSRECURSIVE = ["__pycache__", "_tmp_*", "*.egg-info"] - CLEANFILESRECURSIVE = ["*.pyc", "*.pyo"] - - @staticmethod - def ffind(pattern, path): - """Find files.""" - result = [] - for root, _, files in os.walk(path): - for name in files: - if fnmatch.fnmatch(name, pattern): - result.append(os.path.join(root, name)) - return result - - @staticmethod - def dfind(pattern, path): - """Find folders.""" - result = [] - for root, dirs, _ in os.walk(path): - for name in dirs: - if fnmatch.fnmatch(name, pattern): - result.append(os.path.join(root, name)) - return result - - def run(self): - """Execute run. - - After calling the super class implementation, this function removes - the directories specific to scikit-build ++. - """ - super(CleanUp, self).run() - - for dir_ in CleanUp.CLEANFOLDERS: - if exists(dir_): - print(f"Removing: {dir_}") - if not self.dry_run and exists(dir_): - rmtree(dir_) - - for dir_ in CleanUp.CLEANFOLDERSRECURSIVE: - for pdir in self.dfind(dir_, "."): - print(f"Remove folder {pdir}") - rmtree(pdir) - - for fil_ in CleanUp.CLEANFILESRECURSIVE: - for pfil in self.ffind(fil_, "."): - print(f"Remove file {pfil}") - os.unlink(pfil) diff --git a/setup.cfg b/setup.cfg deleted file mode 100644 index a373ef491..000000000 --- a/setup.cfg +++ /dev/null @@ -1,41 +0,0 @@ -[bdist_wheel] -universal = 1 - -[aliases] -test = pytest - -[flake8] -max-line-length = 88 -ignore = E203, W503 - -[tool:pytest] -norecursedirs = - .git - .tox - .env - dist - build - -addopts = - -ra - --strict-markers - --ignore=docs/conf.py - --ignore=setup.py - --ignore=.eggs - -markers = - integration: marks a test as an integration test - -xfail_strict = true - -# [tool:pylint] -# # Module docstrings are not required, there are other means of documenting at -# # that level in subscript -# disable=missing-module-docstring - -# [check-manifest] -# ignore = -# src/subscript/version.py - -# [rstcheck] -# ignore_directives=argparse,automodule diff --git a/setup.py b/setup.py deleted file mode 100755 index edda35d2b..000000000 --- a/setup.py +++ /dev/null @@ -1,69 +0,0 @@ -#!/usr/bin/env python3 -"""Setup for fmu.dataio package.""" -from glob import glob -from os.path import basename, splitext - -import setuptools - -from scripts import setup_functions as sf - -CMDCLASS = {"clean": sf.CleanUp} - -try: - from sphinx.setup_command import BuildDoc - - CMDCLASS.update({"build_sphinx": BuildDoc}) -except ImportError: - # sphinx not installed - do not provide build_sphinx cmd - pass - -REQUIREMENTS = sf.parse_requirements("requirements/requirements.txt") - -SETUP_REQUIREMENTS = sf.parse_requirements("requirements/requirements_setup.txt") -TEST_REQUIREMENTS = sf.parse_requirements("requirements/requirements_test.txt") -TEST_REQUIREMENTS.extend(sf.parse_requirements("requirements/requirements_testx.txt")) -DOCS_REQUIREMENTS = sf.parse_requirements("requirements/requirements_docs.txt") - -EXTRAS_REQUIRE = {"tests": TEST_REQUIREMENTS, "docs": DOCS_REQUIREMENTS} - -setuptools.setup( - name="fmu-dataio", - description="Facilitate data io in FMU with rich metadata", - author="Equinor ASA", - url="https://github.com/equinor/fmu-dataio", - project_urls={ - "Documentation": "https://fmu-dataio.notyet_on_readthedocs.io/", - "Issue Tracker": "https://github.com/equinor/fmu-dataio/issues", - }, - keywords=[], - license="Apache 2.0", - platforms="any", - cmdclass=CMDCLASS, - include_package_data=True, - packages=setuptools.find_packages("src"), - package_dir={"": "src"}, - py_modules=[splitext(basename(path))[0] for path in glob("src/*.py")], - entry_points={ - "ert": [ - "dataio_case_metadata = fmu.dataio.scripts.create_case_metadata", - ], - }, - install_requires=REQUIREMENTS, - setup_requires=SETUP_REQUIREMENTS, - use_scm_version={"write_to": "src/fmu/dataio/version.py"}, - test_suite="tests", - extras_require=EXTRAS_REQUIRE, - classifiers=[ - "Development Status :: 4 - Beta", - "Intended Audience :: Developers", - "License :: OSI Approved :: Apache Software License", - "Natural Language :: English", - "Programming Language :: Python :: 3.8", - "Programming Language :: Python :: 3.9", - "Programming Language :: Python :: 3.10", - "Programming Language :: Python :: 3.11", - "Intended Audience :: Science/Research", - "Topic :: Scientific/Engineering", - "Topic :: Software Development :: Libraries", - ], -)