From 7b012862e8e547f7e6c24a7522b91c607b9e87f1 Mon Sep 17 00:00:00 2001 From: Tobias Raabe Date: Mon, 21 Mar 2022 11:25:39 +0100 Subject: [PATCH 1/8] Upgrade package to work with pytask v0.2. --- .pre-commit-config.yaml | 2 + environment.yml | 10 +---- pyproject.toml | 1 + src/pytask_environment/__init__.py | 2 +- src/pytask_environment/config.py | 70 +++++++++++++++++++++++++----- src/pytask_environment/database.py | 2 +- src/pytask_environment/logging.py | 11 ++--- src/pytask_environment/plugin.py | 2 +- tests/test_logging.py | 21 ++++----- 9 files changed, 81 insertions(+), 40 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index eb264d4..13a8149 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -90,6 +90,8 @@ repos: rev: "0.48" hooks: - id: check-manifest + args: [--no-build-isolation] + additional_dependencies: [setuptools-scm, toml] - repo: meta hooks: - id: check-hooks-apply diff --git a/environment.yml b/environment.yml index 6d13e82..3dd388a 100644 --- a/environment.yml +++ b/environment.yml @@ -10,17 +10,9 @@ dependencies: - setuptools_scm - toml - # Conda - - anaconda-client - - conda-build - - conda-verify - # Package dependencies - pytask >= 0.0.7 # Misc - - bumpversion - - jupyterlab - - pdbpp - - pre-commit + - pytest - pytest-cov diff --git a/pyproject.toml b/pyproject.toml index 6e40e05..51b714f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,5 +1,6 @@ [build-system] requires = ["setuptools>=45", "wheel", "setuptools_scm[toml]>=6.0"] +build-backend = "setuptools.build_meta" [tool.setuptools_scm] diff --git a/src/pytask_environment/__init__.py b/src/pytask_environment/__init__.py index f493641..dcc8e73 100644 --- a/src/pytask_environment/__init__.py +++ b/src/pytask_environment/__init__.py @@ -2,7 +2,7 @@ try: from ._version import version as __version__ -except ImportError: +except ImportError: # pragma: no cover # broken installation, we don't even try unknown only works because we do poor mans # version compare __version__ = "unknown" diff --git a/src/pytask_environment/config.py b/src/pytask_environment/config.py index 70fa747..d96065f 100644 --- a/src/pytask_environment/config.py +++ b/src/pytask_environment/config.py @@ -1,13 +1,14 @@ from __future__ import annotations +from typing import Any +from typing import Callable + import click -from _pytask.config import hookimpl -from _pytask.shared import convert_truthy_or_falsy_to_bool -from _pytask.shared import get_first_non_none_value +from pytask import hookimpl @hookimpl -def pytask_extend_command_line_interface(cli): +def pytask_extend_command_line_interface(cli: click.Group) -> None: """Extend the cli.""" cli.commands["build"].params.append( click.Option( @@ -20,25 +21,72 @@ def pytask_extend_command_line_interface(cli): @hookimpl -def pytask_parse_config(config, config_from_file, config_from_cli): +def pytask_parse_config( + config: dict[str, Any], + config_from_file: dict[str, Any], + config_from_cli: dict[str, Any], +) -> None: """Parse the configuration.""" - config["check_python_version"] = get_first_non_none_value( + config["check_python_version"] = _get_first_non_none_value( config_from_file, key="check_python_version", default=True, - callback=convert_truthy_or_falsy_to_bool, + callback=_convert_truthy_or_falsy_to_bool, ) - config["check_environment"] = get_first_non_none_value( + config["check_environment"] = _get_first_non_none_value( config_from_file, key="check_environment", default=True, - callback=convert_truthy_or_falsy_to_bool, + callback=_convert_truthy_or_falsy_to_bool, ) - config["update_environment"] = get_first_non_none_value( + config["update_environment"] = _get_first_non_none_value( config_from_cli, key="update_environment", default=False, - callback=convert_truthy_or_falsy_to_bool, + callback=_convert_truthy_or_falsy_to_bool, ) + + +def _get_first_non_none_value( + *configs: dict[str, Any], + key: str, + default: Any | None = None, + callback: Callable[..., Any] | None = None, +) -> Any: + """Get the first non-None value for a key from a list of dictionaries. + + This function allows to prioritize information from many configurations by changing + the order of the inputs while also providing a default. + + Examples + -------- + >>> _get_first_non_none_value({"a": None}, {"a": 1}, key="a") + 1 + >>> _get_first_non_none_value({"a": None}, {"a": None}, key="a", default="default") + 'default' + >>> _get_first_non_none_value({}, {}, key="a", default="default") + 'default' + >>> _get_first_non_none_value({"a": None}, {"a": "b"}, key="a") + 'b' + + """ + callback = (lambda x: x) if callback is None else callback # noqa: E731 + processed_values = (callback(config.get(key)) for config in configs) + return next((value for value in processed_values if value is not None), default) + + +def _convert_truthy_or_falsy_to_bool(x: bool | str | None) -> bool: + """Convert truthy or falsy value in .ini to Python boolean.""" + if x in [True, "True", "true", "1"]: + out = True + elif x in [False, "False", "false", "0"]: + out = False + elif x in [None, "None", "none"]: + out = None + else: + raise ValueError( + f"Input {x!r} is neither truthy (True, true, 1) or falsy (False, false, 0)." + ) + return out diff --git a/src/pytask_environment/database.py b/src/pytask_environment/database.py index cc0c1a4..a70b3df 100644 --- a/src/pytask_environment/database.py +++ b/src/pytask_environment/database.py @@ -1,7 +1,7 @@ from __future__ import annotations -from _pytask.database import db from pony import orm +from pytask import db class Environment(db.Entity): diff --git a/src/pytask_environment/logging.py b/src/pytask_environment/logging.py index 7076839..6c2ead0 100644 --- a/src/pytask_environment/logging.py +++ b/src/pytask_environment/logging.py @@ -2,9 +2,10 @@ import sys -from _pytask.config import hookimpl -from _pytask.console import console from pony import orm +from pytask import console +from pytask import hookimpl +from pytask import Session from pytask_environment.database import Environment @@ -16,7 +17,7 @@ @hookimpl(trylast=True) -def pytask_log_session_header(session) -> None: +def pytask_log_session_header(session: Session) -> None: """Check environment and python version. The solution is hacky. Exploit the first entry-point in the build process after the @@ -70,7 +71,7 @@ def pytask_log_session_header(session) -> None: @orm.db_session -def retrieve_package(name): +def retrieve_package(name: str) -> str: """Return booleans indicating whether the version or path of a package changed.""" try: package = Environment[name] @@ -80,7 +81,7 @@ def retrieve_package(name): @orm.db_session -def create_or_update_state(name, version, path): +def create_or_update_state(name: str, version: str, path: str) -> None: """Create or update a state.""" try: package_in_db = Environment[name] diff --git a/src/pytask_environment/plugin.py b/src/pytask_environment/plugin.py index 3ab9081..fe15957 100644 --- a/src/pytask_environment/plugin.py +++ b/src/pytask_environment/plugin.py @@ -1,7 +1,7 @@ """Entry-point for the plugin.""" from __future__ import annotations -from _pytask.config import hookimpl +from pytask import hookimpl from pytask_environment import config from pytask_environment import database from pytask_environment import logging diff --git a/tests/test_logging.py b/tests/test_logging.py index 913412f..f38b1df 100644 --- a/tests/test_logging.py +++ b/tests/test_logging.py @@ -4,9 +4,10 @@ import textwrap import pytest -from _pytask.database import db from pony import orm from pytask import cli +from pytask import db +from pytask import ExitCode from pytask_environment.database import Environment @@ -19,7 +20,7 @@ def test_existence_of_python_executable_in_db(tmp_path, runner): result = runner.invoke(cli, [tmp_path.as_posix()]) - assert result.exit_code == 0 + assert result.exit_code == ExitCode.OK with orm.db_session: python = Environment["python"] @@ -32,10 +33,6 @@ def test_existence_of_python_executable_in_db(tmp_path, runner): orm.delete(e for e in entity) -@pytest.mark.skipif( - sys.platform == "win32" and sys.version_info[:2] == (3, 6), - reason="Error on Windows with Python 3.6", -) @pytest.mark.end_to_end def test_flow_when_python_version_has_changed(monkeypatch, tmp_path, runner): """Test the whole use-case. @@ -61,14 +58,14 @@ def test_flow_when_python_version_has_changed(monkeypatch, tmp_path, runner): # Run without knowing the python version and without updating the environment. result = runner.invoke(cli, [tmp_path.as_posix()]) - assert result.exit_code == 0 + assert result.exit_code == ExitCode.OK assert "Updating the information" in result.output # Run with a fake version and not updating the environment. monkeypatch.setattr("pytask_environment.logging.sys.version", fake_version) result = runner.invoke(cli) - assert result.exit_code == 1 + assert result.exit_code == ExitCode.FAILED with orm.db_session: python = Environment["python"] @@ -80,8 +77,8 @@ def test_flow_when_python_version_has_changed(monkeypatch, tmp_path, runner): monkeypatch.setattr("pytask_environment.logging.sys.version", fake_version) monkeypatch.setattr("pytask_environment.logging.sys.executable", "new_path") - result = runner.invoke(cli, ["--update-environment"]) - assert result.exit_code == 0 + result = runner.invoke(cli, ["--update-environment", tmp_path.as_posix()]) + assert result.exit_code == ExitCode.OK with orm.db_session: python = Environment["python"] @@ -112,7 +109,7 @@ def test_python_version_changed( # Run without knowing the python version and without updating the environment. result = runner.invoke(cli, [tmp_path.as_posix()]) - assert result.exit_code == 0 + assert result.exit_code == ExitCode.OK assert "Updating the information" in result.output # Run with a fake version and not updating the environment. @@ -141,7 +138,7 @@ def test_environment_changed( # Run without knowing the python version and without updating the environment. result = runner.invoke(cli, [tmp_path.as_posix()]) - assert result.exit_code == 0 + assert result.exit_code == ExitCode.OK assert "Updating the information" in result.output # Run with a fake version and not updating the environment. From b4f133fa772960e0f98b33945a15ab0f87e7531e Mon Sep 17 00:00:00 2001 From: Tobias Raabe Date: Mon, 21 Mar 2022 11:33:49 +0100 Subject: [PATCH 2/8] remove setup.py. --- environment.yml | 1 + setup.py | 7 ------- 2 files changed, 1 insertion(+), 7 deletions(-) delete mode 100644 setup.py diff --git a/environment.yml b/environment.yml index 3dd388a..38bd026 100644 --- a/environment.yml +++ b/environment.yml @@ -14,5 +14,6 @@ dependencies: - pytask >= 0.0.7 # Misc + - pre-commit - pytest - pytest-cov diff --git a/setup.py b/setup.py deleted file mode 100644 index c21a9ee..0000000 --- a/setup.py +++ /dev/null @@ -1,7 +0,0 @@ -from __future__ import annotations - -from setuptools import setup - - -if __name__ == "__main__": - setup() From 53532119db51a815466bdd202af58ef803cb4430 Mon Sep 17 00:00:00 2001 From: Tobias Raabe Date: Mon, 21 Mar 2022 11:44:14 +0100 Subject: [PATCH 3/8] FIx version. --- CHANGES.rst | 6 ++++++ LICENSE | 2 +- environment.yml | 2 +- setup.cfg | 2 +- 4 files changed, 9 insertions(+), 3 deletions(-) diff --git a/CHANGES.rst b/CHANGES.rst index 484ff0e..24bd371 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -7,6 +7,12 @@ reverse chronological order. Releases follow `semantic versioning `_. +0.2.0 - 2022-xx-xx +------------------ + +- :gh:`15` aligns pytask-environment with pytask v0.2.0. + + 0.1.1 - 2022-02-08 ------------------ diff --git a/LICENSE b/LICENSE index 4c96cf3..f4c44ec 100644 --- a/LICENSE +++ b/LICENSE @@ -1,4 +1,4 @@ -Copyright 2020-2021 Tobias Raabe +Copyright 2020 Tobias Raabe Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software diff --git a/environment.yml b/environment.yml index 38bd026..e87d693 100644 --- a/environment.yml +++ b/environment.yml @@ -11,7 +11,7 @@ dependencies: - toml # Package dependencies - - pytask >= 0.0.7 + - pytask >=0.2 # Misc - pre-commit diff --git a/setup.cfg b/setup.cfg index 0f11477..f236170 100644 --- a/setup.cfg +++ b/setup.cfg @@ -30,7 +30,7 @@ packages = find: install_requires = click pony - pytask>=0.1.7 + pytask>=0.2 python_requires = >=3.7 include_package_data = True package_dir = =src From e08a20a628096077819a586a185a31f63677a6c6 Mon Sep 17 00:00:00 2001 From: Tobias Raabe Date: Sat, 16 Apr 2022 17:59:47 +0200 Subject: [PATCH 4/8] fix. --- .github/ISSUE_TEMPLATE/bug_report.md | 18 ++--- .github/ISSUE_TEMPLATE/documentation.md | 10 +-- .github/ISSUE_TEMPLATE/enhancement.md | 14 ++-- .github/ISSUE_TEMPLATE/question.md | 16 ++-- .github/pull_request_template.md | 2 +- .pre-commit-config.yaml | 21 +++--- CHANGES.md | 44 +++++++++++ CHANGES.rst | 63 ---------------- MANIFEST.in | 4 +- README.md | 66 +++++++++++++++++ README.rst | 97 ------------------------- setup.cfg | 6 +- 12 files changed, 150 insertions(+), 211 deletions(-) create mode 100644 CHANGES.md delete mode 100644 CHANGES.rst create mode 100644 README.md delete mode 100644 README.rst diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index 8f6d25b..a70f143 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -1,11 +1,9 @@ ---- +______________________________________________________________________ -name: Bug Report -about: Create a bug report to help us improve pytask-environment -title: "BUG:" -labels: "bug" +name: Bug Report about: Create a bug report to help us improve pytask-environment title: +"BUG:" labels: "bug" ---- +______________________________________________________________________ - [ ] I have checked that this issue has not already been reported. @@ -14,11 +12,11 @@ labels: "bug" - [ ] (optional) I have confirmed this bug exists on the `main` branch of pytask-environment. ---- +______________________________________________________________________ -**Note**: Please read [this -guide](https://matthewrocklin.com/blog/work/2018/02/28/minimal-bug-reports) detailing -how to provide the necessary information for us to reproduce your bug. +**Note**: Please read +[this guide](https://matthewrocklin.com/blog/work/2018/02/28/minimal-bug-reports) +detailing how to provide the necessary information for us to reproduce your bug. #### Code Sample, a copy-pastable example diff --git a/.github/ISSUE_TEMPLATE/documentation.md b/.github/ISSUE_TEMPLATE/documentation.md index 7019681..ced6381 100644 --- a/.github/ISSUE_TEMPLATE/documentation.md +++ b/.github/ISSUE_TEMPLATE/documentation.md @@ -1,11 +1,9 @@ ---- +______________________________________________________________________ -name: Documentation Improvement -about: Report wrong or missing documentation -title: "DOC:" -labels: "documentation" +name: Documentation Improvement about: Report wrong or missing documentation title: +"DOC:" labels: "documentation" ---- +______________________________________________________________________ #### Location of the documentation diff --git a/.github/ISSUE_TEMPLATE/enhancement.md b/.github/ISSUE_TEMPLATE/enhancement.md index 67f20d4..252db46 100644 --- a/.github/ISSUE_TEMPLATE/enhancement.md +++ b/.github/ISSUE_TEMPLATE/enhancement.md @@ -1,16 +1,14 @@ ---- +______________________________________________________________________ -name: Enhancement -about: Suggest an idea for pytask-environment -title: "ENH:" -labels: "enhancement" +name: Enhancement about: Suggest an idea for pytask-environment title: "ENH:" labels: +"enhancement" ---- +______________________________________________________________________ #### Is your feature request related to a problem? -Provide a description of what the problem is, e.g. "I wish I could use pytask-environment -to do [...]". +Provide a description of what the problem is, e.g. "I wish I could use +pytask-environment to do \[...\]". #### Describe the solution you'd like diff --git a/.github/ISSUE_TEMPLATE/question.md b/.github/ISSUE_TEMPLATE/question.md index 2052eee..f5d97c3 100644 --- a/.github/ISSUE_TEMPLATE/question.md +++ b/.github/ISSUE_TEMPLATE/question.md @@ -1,17 +1,15 @@ ---- +______________________________________________________________________ -name: Submit Question -about: Ask a general question about pytask-environment -title: "QST:" -labels: "question" +name: Submit Question about: Ask a general question about pytask-environment title: +"QST:" labels: "question" ---- +______________________________________________________________________ #### Question about pytask-environment -**Note**: If you'd still like to submit a question, please read [this guide]( -https://matthewrocklin.com/blog/work/2018/02/28/minimal-bug-reports) detailing how to -provide the necessary information for us to reproduce your question. +**Note**: If you'd still like to submit a question, please read +[this guide](https://matthewrocklin.com/blog/work/2018/02/28/minimal-bug-reports) +detailing how to provide the necessary information for us to reproduce your question. ```python # Your code here, if applicable diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index 1817a2f..b627f37 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -6,4 +6,4 @@ Provide a description and/or bullet points to describe the changes in this PR. - [ ] Reference issues which can be closed due to this PR with "Closes #x". - [ ] Review whether the documentation needs to be updated. -- [ ] Document PR in docs/changes.rst. +- [ ] Document PR in CHANGES.md. diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index f864946..6b5ed6c 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -24,9 +24,6 @@ repos: - id: python-no-eval - id: python-no-log-warn - id: python-use-type-annotations - - id: rst-backticks - - id: rst-directive-colons - - id: rst-inline-touching-normal - id: text-unicode-replacement-char - repo: https://github.com/asottile/pyupgrade rev: v2.32.0 @@ -42,11 +39,6 @@ repos: rev: 22.3.0 hooks: - id: black -- repo: https://github.com/asottile/blacken-docs - rev: v1.12.1 - hooks: - - id: blacken-docs - additional_dependencies: [black] - repo: https://github.com/PyCQA/flake8 rev: 4.0.1 hooks: @@ -68,10 +60,6 @@ repos: pydocstyle, Pygments, ] -- repo: https://github.com/PyCQA/doc8 - rev: 0.11.1 - hooks: - - id: doc8 - repo: https://github.com/asottile/setup-cfg-fmt rev: v1.20.1 hooks: @@ -81,6 +69,15 @@ repos: hooks: - id: interrogate args: [-v, --fail-under=40, src, tests] +- repo: https://github.com/executablebooks/mdformat + rev: 0.7.14 + hooks: + - id: mdformat + additional_dependencies: [ + mdformat-gfm, + mdformat-black, + ] + args: [--wrap, "88"] - repo: https://github.com/codespell-project/codespell rev: v2.1.0 hooks: diff --git a/CHANGES.md b/CHANGES.md new file mode 100644 index 0000000..f2c54b8 --- /dev/null +++ b/CHANGES.md @@ -0,0 +1,44 @@ +# Changes + +This is a record of all past pytask-environment releases and what went into them in +reverse chronological order. Releases follow [semantic versioning](https://semver.org/) +and all releases are available on +[Anaconda.org](https://anaconda.org/conda-forge/pytask-environment). + +## 0.2.0 - 2022-xx-xx + +- {pull}`15` aligns pytask-environment with pytask v0.2.0. + +## 0.1.1 - 2022-02-08 + +- {pull}`13` deprecates Python 3.6 and adds support for Python 3.10. + +## 0.1.0 - 2022-01-25 + +- {pull}`10` replaces the input prompts with configuration values and flags, removes the + conda recipe, and abort simultaneously running builds. + +## 0.0.6 - 2021-07-23 + +- {pull}`8` replaces versioneer with setuptools-scm. + +## 0.0.5 - 2021-07-23 + +- {pull}`7` adds some pre-commit updates. + +## 0.0.4 - 2021-03-05 + +- {pull}`6` fixes the version number which is displayed during execution. + +## 0.0.3 - 2021-03-03 + +- {pull}`5` adds dependencies to `setup.py` and missing `README.rst` to package. + +## 0.0.2 - 2021-02-27 + +- {pull}`3` prepares pytask-environment to be published on PyPI, adds versioneer, and + more. + +## 0.0.1 - 2020-10-04 + +- Release v0.0.1. diff --git a/CHANGES.rst b/CHANGES.rst deleted file mode 100644 index 24bd371..0000000 --- a/CHANGES.rst +++ /dev/null @@ -1,63 +0,0 @@ -Changes -======= - -This is a record of all past pytask-environment releases and what went into them in -reverse chronological order. Releases follow `semantic versioning -`_ and all releases are available on `Anaconda.org -`_. - - -0.2.0 - 2022-xx-xx ------------------- - -- :gh:`15` aligns pytask-environment with pytask v0.2.0. - - -0.1.1 - 2022-02-08 ------------------- - -- :gh:`13` deprecates Python 3.6 and adds support for Python 3.10. - - -0.1.0 - 2022-01-25 ------------------- - -- :gh:`10` replaces the input prompts with configuration values and flags, removes the - conda recipe, and abort simultaneously running builds. - - -0.0.6 - 2021-07-23 ------------------- - -- :gh:`8` replaces versioneer with setuptools-scm. - - -0.0.5 - 2021-07-23 ------------------- - -- :gh:`7` adds some pre-commit updates. - - -0.0.4 - 2021-03-05 ------------------- - -- :gh:`6` fixes the version number which is displayed during execution. - - -0.0.3 - 2021-03-03 ------------------- - -- :gh:`5` adds dependencies to ``setup.py`` and missing ``README.rst`` to package. - - -0.0.2 - 2021-02-27 ------------------- - -- :gh:`3` prepares pytask-environment to be published on PyPI, adds versioneer, and - more. - - -0.0.1 - 2020-10-04 ------------------- - -- Release v0.0.1. diff --git a/MANIFEST.in b/MANIFEST.in index f450948..61f5ebe 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -1,11 +1,11 @@ prune tests -exclude *.rst +exclude *.md exclude *.yml exclude *.yaml exclude tox.ini -include README.rst +include README.md include LICENSE recursive-include _static *.png diff --git a/README.md b/README.md new file mode 100644 index 0000000..57ec388 --- /dev/null +++ b/README.md @@ -0,0 +1,66 @@ +# pytask-environment + +[![PyPI](https://img.shields.io/pypi/v/pytask-environment?color=blue)](https://pypi.org/project/pytask-environment) +[![PyPI - Python Version](https://img.shields.io/pypi/pyversions/pytask-environment)](https://pypi.org/project/pytask-environment) +[![image](https://img.shields.io/conda/vn/conda-forge/pytask-environment.svg)](https://anaconda.org/conda-forge/pytask-environment) +[![image](https://img.shields.io/conda/pn/conda-forge/pytask-environment.svg)](https://anaconda.org/conda-forge/pytask-environment) +[![PyPI - License](https://img.shields.io/pypi/l/pytask-environment)](https://pypi.org/project/pytask-environment) +[![image](https://img.shields.io/github/workflow/status/pytask-dev/pytask-environment/Continuous%20Integration%20Workflow/main)](https://github.com/pytask-dev/pytask-environment/actions?query=branch%3Amain) +[![image](https://codecov.io/gh/pytask-dev/pytask-environment/branch/main/graph/badge.svg)](https://codecov.io/gh/pytask-dev/pytask-environment) +[![pre-commit.ci status](https://results.pre-commit.ci/badge/github/pytask-dev/pytask-environment/main.svg)](https://results.pre-commit.ci/latest/github/pytask-dev/pytask-environment/main) +[![image](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black) + +______________________________________________________________________ + +pytask-environment allows you to detect changes in your pytask environment and abort a +project build. + +## Installation + +pytask-environment is available on [PyPI](https://pypi.org/project/pytask-environment) +and [Anaconda.org](https://anaconda.org/conda-forge/pytask-environment). Install it with + +```console +$ pip install pytask-environment + +# or + +$ conda install -c conda-forge pytask-environment +``` + +## Usage + +If the user attempts to build the project with `pytask build` and the Python version has +been cached in the database in a previous run, an invocation with a different +environment will produce the following command line output. + +![image](_static/error.png) + +Running + +```console +$ pytask --update-environment +``` + +will update the information on the environment. + +To disable either checking the path or the version, set the following configuration to a +falsy value. + +```ini +# Content of pytask.ini, setup.cfg, or tox.ini + +check_python_version = false # true by default + +check_environment = false # true by default +``` + +## Future development + +The plugin might be further extended to compare the current environment against an +`environment.yml` or a list of packages and versions to ensure that the environment is +not altered. + +## Changes + +Consult the [release notes](CHANGES.md) to find out about what is new. diff --git a/README.rst b/README.rst deleted file mode 100644 index 6a599ce..0000000 --- a/README.rst +++ /dev/null @@ -1,97 +0,0 @@ -.. image:: https://img.shields.io/pypi/v/pytask-environment?color=blue - :alt: PyPI - :target: https://pypi.org/project/pytask-environment - -.. image:: https://img.shields.io/pypi/pyversions/pytask-environment - :alt: PyPI - Python Version - :target: https://pypi.org/project/pytask-environment - -.. image:: https://img.shields.io/conda/vn/conda-forge/pytask-environment.svg - :target: https://anaconda.org/conda-forge/pytask-environment - -.. image:: https://img.shields.io/conda/pn/conda-forge/pytask-environment.svg - :target: https://anaconda.org/conda-forge/pytask-environment - -.. image:: https://img.shields.io/pypi/l/pytask-environment - :alt: PyPI - License - :target: https://pypi.org/project/pytask-environment - -.. image:: https://img.shields.io/github/workflow/status/pytask-dev/pytask-environment/Continuous%20Integration%20Workflow/main - :target: https://github.com/pytask-dev/pytask-environment/actions?query=branch%3Amain - -.. image:: https://codecov.io/gh/pytask-dev/pytask-environment/branch/main/graph/badge.svg - :target: https://codecov.io/gh/pytask-dev/pytask-environment - -.. image:: https://results.pre-commit.ci/badge/github/pytask-dev/pytask-environment/main.svg - :target: https://results.pre-commit.ci/latest/github/pytask-dev/pytask-environment/main - :alt: pre-commit.ci status - -.. image:: https://img.shields.io/badge/code%20style-black-000000.svg - :target: https://github.com/psf/black - ------- - -pytask-environment -================== - -pytask-environment allows you to detect changes in your pytask environment and abort a -project build. - - -Installation ------------- - -pytask-environment is available on `PyPI `_ -and `Anaconda.org `_. Install it -with - -.. code-block:: console - - $ pip install pytask-environment - - # or - - $ conda install -c conda-forge pytask-environment - - -Usage ------ - -If the user attempts to build the project with ``pytask build`` and the Python version -has been cached in the database in a previous run, an invocation with a different -environment will produce the following command line output. - -.. image:: _static/error.png - -Running - -.. code-block:: console - - $ pytask --update-environment - -will update the information on the environment. - -To disable either checking the path or the version, set the following configuration to a -falsy value. - -.. code-block:: ini - - # Content of pytask.ini, setup.cfg, or tox.ini - - check_python_version = false # true by default - - check_environment = false # true by default - - -Future development ------------------- - -The plugin might be further extended to compare the current environment against an -``environment.yml`` or a list of packages and versions to ensure that the environment is -not altered. - - -Changes -------- - -Consult the `release notes `_ to find out about what is new. diff --git a/setup.cfg b/setup.cfg index f236170..9dbd2aa 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,8 +1,8 @@ [metadata] name = pytask_environment description = Detect changes in your pytask environment and abort a project build. -long_description = file: README.rst -long_description_content_type = text/x-rst +long_description = file: README.md +long_description_content_type = text/markdown url = https://github.com/pytask-dev/pytask-environment author = Tobias Raabe author_email = raabe@posteo.de @@ -20,7 +20,7 @@ classifiers = Programming Language :: Python :: 3.9 Programming Language :: Python :: 3.10 project_urls = - Changelog = https://github.com/pytask-dev/pytask-environment/blob/main/CHANGES.rst + Changelog = https://github.com/pytask-dev/pytask-environment/blob/main/CHANGES.md Documentation = https://github.com/pytask-dev/pytask-environment Github = https://github.com/pytask-dev/pytask-environment Tracker = https://github.com/pytask-dev/pytask-environment/issues From aad176be8a4858a3e01135f3ed970bfcb4bcf03a Mon Sep 17 00:00:00 2001 From: Tobias Raabe Date: Sat, 16 Apr 2022 18:04:38 +0200 Subject: [PATCH 5/8] Fix readme. --- .../continuous-integration-workflow.yml | 46 ------------------- README.md | 5 +- setup.cfg | 2 +- tox.ini | 5 -- 4 files changed, 3 insertions(+), 55 deletions(-) delete mode 100644 .github/workflows/continuous-integration-workflow.yml diff --git a/.github/workflows/continuous-integration-workflow.yml b/.github/workflows/continuous-integration-workflow.yml deleted file mode 100644 index 60a90e2..0000000 --- a/.github/workflows/continuous-integration-workflow.yml +++ /dev/null @@ -1,46 +0,0 @@ -name: Continuous Integration Workflow -on: - push: - branches: - - main - pull_request: - branches: - - '*' - -concurrency: - group: ${{ github.head_ref || github.run_id }} - cancel-in-progress: true - -jobs: - - run-tests: - - name: Run tests for ${{ matrix.os }} on ${{ matrix.python-version }} - runs-on: ${{ matrix.os }} - - strategy: - fail-fast: false - matrix: - os: ['ubuntu-latest', 'macos-latest', 'windows-latest'] - python-version: ['3.7', '3.8', '3.9', '3.10'] - - steps: - - uses: actions/checkout@v2 - - uses: r-lib/actions/setup-tinytex@v1 - - uses: conda-incubator/setup-miniconda@v2 - with: - auto-update-conda: true - python-version: ${{ matrix.python-version }} - - - name: Install core dependencies. - shell: bash -l {0} - run: conda install -c conda-forge tox-conda coverage - - - name: Run end-to-end tests. - shell: bash -l {0} - run: tox -e pytest -- -m end_to_end --cov=./ --cov-report=xml - - - name: Upload coverage reports of end-to-end tests. - if: runner.os == 'Linux' && matrix.python-version == '3.9' - shell: bash -l {0} - run: bash <(curl -s https://codecov.io/bash) -F end_to_end -c diff --git a/README.md b/README.md index 57ec388..30b733c 100644 --- a/README.md +++ b/README.md @@ -47,9 +47,8 @@ will update the information on the environment. To disable either checking the path or the version, set the following configuration to a falsy value. -```ini -# Content of pytask.ini, setup.cfg, or tox.ini - +```toml +[tool.pytask.ini_options] check_python_version = false # true by default check_environment = false # true by default diff --git a/setup.cfg b/setup.cfg index 9dbd2aa..b576a98 100644 --- a/setup.cfg +++ b/setup.cfg @@ -10,7 +10,7 @@ license = MIT license_file = LICENSE platforms = any classifiers = - Development Status :: 3 - Alpha + Development Status :: 4 - Beta License :: OSI Approved :: MIT License Operating System :: OS Independent Programming Language :: Python :: 3 diff --git a/tox.ini b/tox.ini index 15c3f82..ef14721 100644 --- a/tox.ini +++ b/tox.ini @@ -4,7 +4,6 @@ skipsdist = True skip_missing_interpreters = True [testenv] -passenv = GITHUB_ACTIONS basepython = python [testenv:pytest] @@ -19,10 +18,6 @@ commands = pip install -e . pytest {posargs} -[doc8] -ignore = D002, D004 -max-line-length = 88 - [flake8] docstring-convention = numpy ignore = From 082fe37318f158316285ab0bcfb6129f5a4ee2c9 Mon Sep 17 00:00:00 2001 From: Tobias Raabe Date: Sat, 16 Apr 2022 18:10:44 +0200 Subject: [PATCH 6/8] Rename workflow and fix tests. --- .github/workflows/main.yml | 47 ++++++++++++++++++++++++++++++++++++++ tests/test_logging.py | 36 +++++++++++++++++++++-------- 2 files changed, 73 insertions(+), 10 deletions(-) create mode 100644 .github/workflows/main.yml diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml new file mode 100644 index 0000000..b36095b --- /dev/null +++ b/.github/workflows/main.yml @@ -0,0 +1,47 @@ +name: main + +on: + push: + branches: + - main + pull_request: + branches: + - '*' + +concurrency: + group: ${{ github.head_ref || github.run_id }} + cancel-in-progress: true + +jobs: + + run-tests: + + name: Run tests for ${{ matrix.os }} on ${{ matrix.python-version }} + runs-on: ${{ matrix.os }} + + strategy: + fail-fast: false + matrix: + os: ['ubuntu-latest', 'macos-latest', 'windows-latest'] + python-version: ['3.7', '3.8', '3.9', '3.10'] + + steps: + - uses: actions/checkout@v2 + - uses: r-lib/actions/setup-tinytex@v1 + - uses: conda-incubator/setup-miniconda@v2 + with: + auto-update-conda: true + python-version: ${{ matrix.python-version }} + + - name: Install core dependencies. + shell: bash -l {0} + run: conda install -c conda-forge tox-conda coverage + + - name: Run end-to-end tests. + shell: bash -l {0} + run: tox -e pytest -- -m end_to_end --cov=./ --cov-report=xml + + - name: Upload coverage reports of end-to-end tests. + if: runner.os == 'Linux' && matrix.python-version == '3.9' + shell: bash -l {0} + run: bash <(curl -s https://codecov.io/bash) -F end_to_end -c diff --git a/tests/test_logging.py b/tests/test_logging.py index f38b1df..a65afd4 100644 --- a/tests/test_logging.py +++ b/tests/test_logging.py @@ -34,7 +34,13 @@ def test_existence_of_python_executable_in_db(tmp_path, runner): @pytest.mark.end_to_end -def test_flow_when_python_version_has_changed(monkeypatch, tmp_path, runner): +@pytest.mark.parametrize( + "config_file, content", + [("pytask.ini", "[pytask]"), ("pyproject.toml", "[tool.pytask.ini_options]")], +) +def test_flow_when_python_version_has_changed( + monkeypatch, tmp_path, runner, config_file, content +): """Test the whole use-case. 1. Run a simple task to cache the Python version and path. @@ -51,7 +57,7 @@ def test_flow_when_python_version_has_changed(monkeypatch, tmp_path, runner): "[MSC v.1916 64 bit (AMD64)]" ) - tmp_path.joinpath("pytask.ini").write_text("[pytask]") + tmp_path.joinpath(config_file).write_text(content) source = "def task_dummy(): pass" task_path = tmp_path.joinpath("task_dummy.py") task_path.write_text(textwrap.dedent(source)) @@ -92,17 +98,22 @@ def test_flow_when_python_version_has_changed(monkeypatch, tmp_path, runner): @pytest.mark.end_to_end +@pytest.mark.parametrize( + "config_file, content", + [ + ("pytask.ini", "[pytask]\ncheck_python_version = {}"), + ("pyproject.toml", "[tool.pytask.ini_options]\ncheck_python_version = {}"), + ], +) @pytest.mark.parametrize("check_python_version, expected", [("true", 1), ("false", 0)]) def test_python_version_changed( - monkeypatch, tmp_path, runner, check_python_version, expected + monkeypatch, tmp_path, runner, config_file, content, check_python_version, expected ): fake_version = ( "2.7.8 | packaged by conda-forge | (default, Jul 31 2020, 01:53:57) " "[MSC v.1916 64 bit (AMD64)]" ) - tmp_path.joinpath("pytask.ini").write_text( - f"[pytask]\ncheck_python_version = {check_python_version}" - ) + tmp_path.joinpath(config_file).write_text(content.format(check_python_version)) source = "def task_dummy(): pass" task_path = tmp_path.joinpath("task_dummy.py") task_path.write_text(textwrap.dedent(source)) @@ -125,13 +136,18 @@ def test_python_version_changed( @pytest.mark.end_to_end +@pytest.mark.parametrize( + "config_file, content", + [ + ("pytask.ini", "[pytask]\ncheck_environment = {}"), + ("pyproject.toml", "[tool.pytask.ini_options]\ncheck_environment = {}"), + ], +) @pytest.mark.parametrize("check_python_version, expected", [("true", 1), ("false", 0)]) def test_environment_changed( - monkeypatch, tmp_path, runner, check_python_version, expected + monkeypatch, tmp_path, runner, config_file, content, check_python_version, expected ): - tmp_path.joinpath("pytask.ini").write_text( - f"[pytask]\ncheck_environment = {check_python_version}" - ) + tmp_path.joinpath(config_file).write_text(content.format(check_python_version)) source = "def task_dummy(): pass" task_path = tmp_path.joinpath("task_dummy.py") task_path.write_text(textwrap.dedent(source)) From 04550c83ec70327f4b40b9548b44ca1e37edda8b Mon Sep 17 00:00:00 2001 From: Tobias Raabe Date: Sat, 16 Apr 2022 18:22:59 +0200 Subject: [PATCH 7/8] fix. --- .github/workflows/main.yml | 2 +- src/pytask_environment/config.py | 11 ----------- 2 files changed, 1 insertion(+), 12 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index b36095b..e6b29ef 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -39,7 +39,7 @@ jobs: - name: Run end-to-end tests. shell: bash -l {0} - run: tox -e pytest -- -m end_to_end --cov=./ --cov-report=xml + run: tox -e pytest -- tests -m end_to_end --cov=./ --cov-report=xml - name: Upload coverage reports of end-to-end tests. if: runner.os == 'Linux' && matrix.python-version == '3.9' diff --git a/src/pytask_environment/config.py b/src/pytask_environment/config.py index d96065f..20f1ffe 100644 --- a/src/pytask_environment/config.py +++ b/src/pytask_environment/config.py @@ -60,17 +60,6 @@ def _get_first_non_none_value( This function allows to prioritize information from many configurations by changing the order of the inputs while also providing a default. - Examples - -------- - >>> _get_first_non_none_value({"a": None}, {"a": 1}, key="a") - 1 - >>> _get_first_non_none_value({"a": None}, {"a": None}, key="a", default="default") - 'default' - >>> _get_first_non_none_value({}, {}, key="a", default="default") - 'default' - >>> _get_first_non_none_value({"a": None}, {"a": "b"}, key="a") - 'b' - """ callback = (lambda x: x) if callback is None else callback # noqa: E731 processed_values = (callback(config.get(key)) for config in configs) From 3547ae453cc50ee8897c88ba3af1f726c635eb57 Mon Sep 17 00:00:00 2001 From: Tobias Raabe Date: Sat, 16 Apr 2022 18:34:08 +0200 Subject: [PATCH 8/8] fix changes. --- CHANGES.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGES.md b/CHANGES.md index f2c54b8..02ccda0 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -5,7 +5,7 @@ reverse chronological order. Releases follow [semantic versioning](https://semve and all releases are available on [Anaconda.org](https://anaconda.org/conda-forge/pytask-environment). -## 0.2.0 - 2022-xx-xx +## 0.2.0 - 2022-16-04 - {pull}`15` aligns pytask-environment with pytask v0.2.0.