diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 8a8ab1f4..fdd5a3bb 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -86,7 +86,6 @@ repos: rev: 5.0.4 hooks: - id: flake8 - args: ["--config", "tox.ini"] additional_dependencies: - flake8-docstrings - flake8-colors @@ -97,6 +96,7 @@ repos: - pycodestyle - pyflakes - flake8-rst-docstrings + - flake8-pyproject - flake8-use-fstring # Check for known security vulnerabilities: @@ -107,18 +107,6 @@ repos: args: ["-c", "pyproject.toml"] additional_dependencies: ["bandit[toml]"] - # # Use type annotations to check types - # - repo: https://github.com/pre-commit/mirrors-mypy - # rev: v0.990 - # hooks: - # - id: mypy - # additional_dependencies: - # - pytest - # - types-jinja2 - # - types-setuptools - ## - pandas-stubs - # args: ["--strict"] - # Check for errors in restructuredtext (.rst) files under the doc hierarchy - repo: https://github.com/PyCQA/doc8 rev: v1.0.0 diff --git a/docs/release_notes.rst b/docs/release_notes.rst index 276855ea..1cc8c2fa 100644 --- a/docs/release_notes.rst +++ b/docs/release_notes.rst @@ -73,6 +73,8 @@ What's New? facility has storage, storage can be charged by the constrained excess. * Added ``compare_hist`` argument to :meth:`.DispatchModel.plot_period` which creates panel plot showing both historical dispatch and redispatch for the period. +* Cleanup of configuration and packaging files. Contents of ``setup.cfg`` and + ``tox.ini`` moved to ``pyproject.toml``. Bug Fixes ^^^^^^^^^ diff --git a/pyproject.toml b/pyproject.toml index b90bf063..19f8cd1d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -2,35 +2,146 @@ requires = ["setuptools<66", "setuptools_scm[toml]>=3.5.0"] build-backend = "setuptools.build_meta" +[project] +name = "rmi.dispatch" +description = "A simple and efficient dispatch model." +license = {file = "LICENSE.txt"} +readme = "README.rst" +dynamic = ["version"] +classifiers = [ + "Natural Language :: English", + "Operating System :: OS Independent", + "Programming Language :: Python", + "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3 :: Only", + "Programming Language :: Python :: 3.10", +] +requires-python = ">=3.10,<3.11" +dependencies = [ + "bottleneck >= 1.3,<1.3.6", + "numba >= 0.55.1,<0.57", + "numexpr >= 2.8, <2.8.4", + "numpy >= 1.18.5,<2", + "pandas >= 1.4,< 1.6", + "pandera ~= 0.12", + "pyarrow>=7, <11", + "rmi.etoolbox @ git+https://github.com/rmi-electricity/etoolbox.git", +] + +[project.optional-dependencies] +dev = [ + "black[jupyter] >= 22,<23", + "isort>=5.0,<5.11", + "tox>=3.20,<3.28", +] +doc = [ + "doc8>=0.9,<1.1", + "furo>=2022.4.7", + "sphinx>=4,!=5.1.0,<5.3.1", + "sphinx-autoapi>=1.8,<2.1", + "sphinx-issues>=1.2,<3.1", + "sphinx-autodoc-typehints>1.19,<=1.19.5", + "sphinxcontrib-mermaid>0.7,<=0.7.1", +] +tests = [ + "bandit>=1.6,<1.8", + "coverage>=5.3,<6.6", + "doc8>=0.9,<1.1", + "flake8>=4.0,<5.1", + "flake8-builtins>=1.5,<2.1", + "flake8-docstrings>=1.5,<1.7", + "flake8-pyproject>1.0,<=1.2", + "flake8-rst-docstrings>=0.2,<0.3", + "flake8-use-fstring>=1.0,<1.5", + "mccabe>=0.6,<0.8", + "mypy>=0.942,<0.991", + "pep8-naming>=0.12,<0.14", + "pre-commit>=2.9,<2.21", + "pydocstyle>=5.1,<6.2", + "pytest>=6.2,<7.3", + "pytest-console-scripts>=1.1,<1.4", + "pytest-cov>=2.10,<4.1", + "rstcheck[sphinx,toml]>=5.0,<6.2", + "tox>=3.20,<3.28", +] +viz = [ + "plotly>5.10,<=5.11", + "kaleido>0.2,<=0.2.1", +] + [tool.setuptools_scm] write_to = "src/dispatch/_version.py" -[tool.black] -line-length = 88 -target-version = ["py39", "py310", "py311"] -include = "\\.pyi?$" +[tool.setuptools] +package-dir = {"" = "src"} -[tool.isort] -profile = "black" -known_first_party = ["dispatch"] +[tool.setuptools.packages.find] +where = ["src"] + +[tool.setuptools.dynamic] +version = {attr = "dispatch._version.__version__"} [tool.bandit] exclude_dirs = ["tests"] skips = ["B101"] -[tool.mypy] -python_version = "3.10" -warn_return_any = true -warn_unused_configs = true -plugins = "numpy.typing.mypy_plugin" +[tool.black] +line-length = 88 +target-version = ["py39", "py310", "py311"] +include = "\\.pyi?$" -[[tool.mypy.overrides]] -module = [ - "numpy.*", - "pandas.*", - "numba.*" +[tool.doc8] +max-line-length = 88 +ignore-path = "docs/_build" + +[tool.flake8] +extend-ignore = [ + # * W503, W504: Line break before / after binary operator. + "W503", "W504", + "D401", # * D401: Imperative mood. + "E501", # * E501: Overlong line + "E203", # * E203: Space before ':' (black recommends to ignore) + # * RST201,RST203,RST301: Google docstrings aren't RST until after being processed by + # Napoleon. See https://github.com/peterjc/flake8-rst-docstrings/issues/17 + "RST201", "RST203", "RST301", + "D105", + "C901" # We have a backlog of complex functions being skipped with noqa: C901 +] +max-complexity = 10 +inline-quotes = "double" +max-line-length = 88 +docstring-convention = "google" +# Files and directories that should not be subject to linting +extend-exclude = [ + ".env_tox", + ".eggs", + "build", +] +rst-roles =[ + "attr", + "class", + "doc", + "func", + "meth", + "mod", + "obj", + "py:const", + "ref", + "user", +] +rst-directives =[ + "envvar", + "exception", ] -ignore_missing_imports = true +percent-greedy = 2 +format-greedy = 2 +per-file-ignores = [ + "__init__.py:F401" +] + +[tool.isort] +profile = "black" +known_first_party = ["dispatch"] [tool.pytest.ini_options] testpaths = ["."] @@ -45,12 +156,69 @@ filterwarnings = [ "ignore:Creating a LegacyVersion:DeprecationWarning:pkg_resources[.*]", ] -[tool.doc8] -max-line-length = 88 -ignore-path = "docs/_build" - [tool.rstcheck] report_level = "WARNING" ignore_roles = ["pr", "issue", "user", "include"] ignore_messages = '(Hyperlink target .* is not referenced\.$|Duplicate implicit target name:|An `AttributeError` error occured.*)' ignore_directives = ["bibliography", "todo", "include"] + +[tool.tox] +legacy_tox_ini = """ +[tox] +envlist = + linters + docs + tests +isolated_build = True + +[testenv] +extras = + tests + doc + viz +allowlist_externals = + bash + coverage + sphinx-build +skip_install = false +covargs = --cov={envsitepackagesdir}/dispatch --cov-append --cov-report=lcov:coverage.info +covreport = coverage report --sort=cover + +[testenv:linters] +description = Run the pre-commit, flake8, rstcheck, doc8 and bandit linters. +commands = + pre-commit run --all-files --show-diff-on-failure python-no-eval + pre-commit run --all-files --show-diff-on-failure python-no-log-warn + pre-commit run --all-files --show-diff-on-failure python-check-blanket-noqa + pre-commit run --all-files --show-diff-on-failure check-merge-conflict + pre-commit run --all-files --show-diff-on-failure check-yaml + pre-commit run --all-files --show-diff-on-failure check-case-conflict + pre-commit run --all-files --show-diff-on-failure debug-statements + pre-commit run --all-files --show-diff-on-failure name-tests-test + bandit -c pyproject.toml -r src/dispatch/ + flake8 + bash -c 'rm -rf docs/_build' + doc8 docs/ README.rst + rstcheck --config pyproject.toml --recursive ./ + +[testenv:docs] +description = Build the HTML docs from scratch using Sphinx. +commands = + bash -c 'rm -rf docs/_build' + sphinx-build -b html docs docs/_build + +[testenv:tests] +description = Run all tests & generate test coverage. +recreate = true +commands = + coverage erase + pytest {posargs} {[testenv]covargs} --doctest-modules {envsitepackagesdir}/dispatch tests + {[testenv]covreport} + +[testenv:build] +description = Prepare Python source and binary packages for release. +basepython = python3 +commands = + bash -c 'rm -rf build/* dist/*' + python -m build --sdist --wheel +""" diff --git a/setup.cfg b/setup.cfg deleted file mode 100644 index 79bc7ec8..00000000 --- a/setup.cfg +++ /dev/null @@ -1,85 +0,0 @@ -[metadata] -name = rmi.dispatch -description = A simple and efficient dispatch model. -;long_description = file: README.rst, CHANGELOG.rst, LICENSE.rst -keywords = one, two -license = BSD 3-Clause License -classifiers = - Natural Language :: English - Operating System :: OS Independent - Programming Language :: Python - Programming Language :: Python :: 3 - Programming Language :: Python :: 3 :: Only - Programming Language :: Python :: 3.10 - -[options] -package_dir= - =src -packages=find: -python_requires = >=3.10,<3.11 -install_requires = - bottleneck >= 1.3,<1.3.6 - numba >= 0.55.1,<0.57 - numexpr >= 2.8, <2.8.4 - numpy >= 1.18.5,<2 - pandas >= 1.4,< 1.6 - pandera ~= 0.12 - pyarrow>=7, <11 - rmi.etoolbox @ git+https://github.com/rmi-electricity/etoolbox.git - -[options.packages.find] -where=src - -[options.extras_require] -dev = - black[jupyter] >= 22,<23 - isort>=5.0,<5.11 - tox>=3.20,<3.28 -doc = - doc8>=0.9,<1.1 - furo>=2022.4.7 - sphinx>=4,!=5.1.0,<5.3.1 - sphinx-autoapi>=1.8,<2.1 - sphinx-issues>=1.2,<3.1 - sphinx-autodoc-typehints>1.19,<=1.19.5 - sphinxcontrib-mermaid>0.7,<=0.7.1 -tests = - ; Checks code for security issues - bandit>=1.6,<1.8 - ; Lets us track what code is being tested - coverage>=5.3,<6.6 - ; Ensures clean documentation formatting - doc8>=0.9,<1.1 - ; A framework for linting & static analysis - flake8>=4.0,<5.1 - ; Avoid shadowing Python built-in names - flake8-builtins>=1.5,<2.1 - ; Ensure docstrings are formatted well - flake8-docstrings>=1.5,<1.7 - ; Allow use of ReST in docstrings - flake8-rst-docstrings>=0.2,<0.3 - ; Highlight use of old-style string formatting - flake8-use-fstring>=1.0,<1.5 - ; Checks that code isn't overly complicated - mccabe>=0.6,<0.8 - ; Static type checking - mypy>=0.942,<0.991 - ; Require PEP8 compliant variable names - pep8-naming>=0.12,<0.14 - ; Allow us to run pre-commit hooks in testing - pre-commit>=2.9,<2.21 - ; Style guidelines for Python documentation - pydocstyle>=5.1,<6.2 - pytest>=6.2,<7.3 - ; Allow automatic testing of scripts - pytest-console-scripts>=1.1,<1.4 - ; Pytest plugin for working with coverage - pytest-cov>=2.10,<4.1 - ; ReStructuredText linter - rstcheck[sphinx,toml]>=5.0,<6.2 - ; Python test environment manager - tox>=3.20,<3.28 -; pandas-stubs -viz = - plotly>5.10,<=5.11 - kaleido>0.2,<=0.2.1 diff --git a/tox.ini b/tox.ini deleted file mode 100644 index 0ba611c3..00000000 --- a/tox.ini +++ /dev/null @@ -1,219 +0,0 @@ -[tox] -envlist = ci -isolated_build = True - -[testenv] -allowlist_externals = - bash - coverage - sphinx-build - twine -# shared directory for re-used packages -envdir = {toxinidir}/.env_tox -passenv = - CI - CONDA_PREFIX - GITHUB_* - GOOGLE_APPLICATION_CREDENTIALS - HOME - SQLALCHEMY_WARN_20 -covargs = --cov={envsitepackagesdir}/dispatch --cov-append --cov-report=lcov:coverage.info -covreport = coverage report --sort=cover - -####################################################################################### -# Code and Documentation Linters -####################################################################################### -[testenv:flake8] -description = Run the full suite of flake8 linters & static code analysis -skip_install = false -extras = - tests -commands = - flake8 --config tox.ini - -[testenv:rstcheck] -description = Check formatting and syntax of RST files. -skip_install = false -extras = - tests -commands = - rstcheck --config pyproject.toml --recursive ./ - -[testenv:pre_commit] -description = Run git pre-commit hooks not covered by the other linters. -skip_install = false -extras = - tests -commands = - pre-commit run --all-files --show-diff-on-failure python-no-eval - pre-commit run --all-files --show-diff-on-failure python-no-log-warn - pre-commit run --all-files --show-diff-on-failure python-check-blanket-noqa - pre-commit run --all-files --show-diff-on-failure check-merge-conflict - pre-commit run --all-files --show-diff-on-failure check-yaml - pre-commit run --all-files --show-diff-on-failure check-case-conflict - pre-commit run --all-files --show-diff-on-failure debug-statements - pre-commit run --all-files --show-diff-on-failure name-tests-test - -[testenv:bandit] -description = Check the codebase for common insecure code patterns. -skip_install = false -extras = - tests -commands = - bandit -c pyproject.toml -r src/dispatch/ - -;[testenv:mypy] -;description = Run mypy type checking on the codebase. -;skip_install = false -;extras = -; tests -; types -;commands = -; mypy --strict src tests - -[testenv:linters] -description = Run the pre-commit, flake8 and bandit linters. -skip_install = false -extras = - {[testenv:pre_commit]extras} - {[testenv:bandit]extras} - {[testenv:rstcheck]extras} - {[testenv:flake8]extras} -; {[testenv:mypy]extras} -commands = - {[testenv:pre_commit]commands} - {[testenv:bandit]commands} - {[testenv:rstcheck]commands} - {[testenv:flake8]commands} -; {[testenv:mypy]commands} - -####################################################################################### -# Lint and Build the Docs -####################################################################################### -[testenv:doc8] -description = Check the documentation input files for syntactical correctness. -skip_install = false -extras = - doc -commands = - doc8 docs/ README.rst - -[testenv:docs] -description = Build the HTML docs from scratch using Sphinx. -skip_install = false -extras = - {[testenv:doc8]extras} - {[testenv:rstcheck]extras} -commands = - bash -c 'rm -rf docs/_build' - {[testenv:doc8]commands} - {[testenv:rstcheck]commands} -; sphinx-build -W -b html docs docs/_build/html - sphinx-build -b html docs docs/_build - - - -####################################################################################### -# Test the code -####################################################################################### -[testenv:unit] -description = Run all the software unit tests. -extras = - tests - viz -commands = - pytest {posargs} {[testenv]covargs} \ - --doctest-modules {envsitepackagesdir}/dispatch \ - tests - -[testenv:ci] -description = Run all continuous integration (CI) checks & generate test coverage. -skip_install = false -recreate = true -extras = - {[testenv:linters]extras} - {[testenv:docs]extras} - {[testenv:unit]extras} -; {[testenv:integration]extras} -commands = - coverage erase - {[testenv:linters]commands} - {[testenv:docs]commands} - {[testenv:unit]commands} -; {[testenv:integration]commands} - {[testenv]covreport} - -####################################################################################### -# Software Package Build & Release -####################################################################################### -[testenv:build] -description = Prepare Python source and binary packages for release. -basepython = python3 -skip_install = false -commands = - bash -c 'rm -rf build/* dist/*' - python setup.py sdist bdist_wheel - -;[testenv:testrelease] -;description = Do a dry run of Python package release using the PyPI test server. -;basepython = python3 -;skip_install = false -;extras = -; dev -;commands = -; {[testenv:build]commands} -; twine check dist/* -; twine upload --sign --verbose --repository testpypi --skip-existing dist/* - -;[testenv:release] -;description = Release the package to the production PyPI server. -;basepython = python3 -;skip_install = true -;extras = -; dev -;commands = -; {[testenv:build]commands} -; twine check dist/* -; twine upload --sign --verbose --skip-existing dist/* - -####################################################################################### -# Configuration for various tools. -####################################################################################### - -[flake8] -# A few linter errors and warnings that we are currently ignoring: -# * W503, W504: Line break before / after binary operator. -# * D401: Imperative mood. -# * E501: Overlong line -# * E203: Space before ':' (black recommends to ignore) -# * RST201,RST203,RST301: Google docstrings aren't RST until after being processed by -# Napoleon. See https://github.com/peterjc/flake8-rst-docstrings/issues/17 -extend-ignore = W503,W504,D401,E501,E203,RST201,RST203,RST301,D105,C901 -inline-quotes = double -max-line-length = 88 -docstring-convention = google -# Files and directories that should not be subject to linting -extend-exclude = - .env_tox, - .eggs, - build, -# We have a backlog of complex functions being skipped with noqa: C901 -max-complexity = 10 -rst-roles = - attr, - class, - doc, - func, - meth, - mod, - obj, - py:const, - ref, - user, -rst-directives = - envvar, - exception, -percent-greedy = 2 -format-greedy = 2 -per-file-ignores = - __init__.py:F401