From 912114b9b3f5432c56748db499d22fc5830d3c66 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 16 Jan 2023 20:38:17 +0000 Subject: [PATCH 1/3] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/pre-commit/pre-commit-hooks: v4.2.0 → v4.4.0](https://github.com/pre-commit/pre-commit-hooks/compare/v4.2.0...v4.4.0) - [github.com/pre-commit/pygrep-hooks: v1.9.0 → v1.10.0](https://github.com/pre-commit/pygrep-hooks/compare/v1.9.0...v1.10.0) - [github.com/asottile/pyupgrade: v2.32.0 → v3.3.1](https://github.com/asottile/pyupgrade/compare/v2.32.0...v3.3.1) - [github.com/asottile/reorder_python_imports: v3.0.1 → v3.9.0](https://github.com/asottile/reorder_python_imports/compare/v3.0.1...v3.9.0) - [github.com/asottile/setup-cfg-fmt: v1.20.1 → v2.2.0](https://github.com/asottile/setup-cfg-fmt/compare/v1.20.1...v2.2.0) - https://github.com/myint/docformatter → https://github.com/PyCQA/docformatter - [github.com/PyCQA/docformatter: v1.3.1 → v1.5.1](https://github.com/PyCQA/docformatter/compare/v1.3.1...v1.5.1) - [github.com/psf/black: 22.3.0 → 22.12.0](https://github.com/psf/black/compare/22.3.0...22.12.0) - [github.com/PyCQA/flake8: 4.0.1 → 6.0.0](https://github.com/PyCQA/flake8/compare/4.0.1...6.0.0) - [github.com/executablebooks/mdformat: 0.7.14 → 0.7.16](https://github.com/executablebooks/mdformat/compare/0.7.14...0.7.16) - [github.com/codespell-project/codespell: v2.1.0 → v2.2.2](https://github.com/codespell-project/codespell/compare/v2.1.0...v2.2.2) - [github.com/pre-commit/mirrors-mypy: v0.931 → v0.991](https://github.com/pre-commit/mirrors-mypy/compare/v0.931...v0.991) - [github.com/mgedmin/check-manifest: 0.48 → 0.49](https://github.com/mgedmin/check-manifest/compare/0.48...0.49) --- .pre-commit-config.yaml | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 8165d18..1773eef 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,6 +1,6 @@ repos: - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v4.2.0 + rev: v4.4.0 hooks: - id: check-added-large-files args: ['--maxkb=25'] @@ -16,7 +16,7 @@ repos: args: [--branch, main] - id: trailing-whitespace - repo: https://github.com/pre-commit/pygrep-hooks - rev: v1.9.0 # Use the ref you want to point at + rev: v1.10.0 # Use the ref you want to point at hooks: - id: python-check-blanket-noqa - id: python-check-mock-methods @@ -25,30 +25,30 @@ repos: - id: python-use-type-annotations - id: text-unicode-replacement-char - repo: https://github.com/asottile/pyupgrade - rev: v2.32.0 + rev: v3.3.1 hooks: - id: pyupgrade args: [--py37-plus] - repo: https://github.com/asottile/reorder_python_imports - rev: v3.0.1 + rev: v3.9.0 hooks: - id: reorder-python-imports args: [--py37-plus, --add-import, 'from __future__ import annotations'] - repo: https://github.com/asottile/setup-cfg-fmt - rev: v1.20.1 + rev: v2.2.0 hooks: - id: setup-cfg-fmt -- repo: https://github.com/myint/docformatter - rev: v1.3.1 +- repo: https://github.com/PyCQA/docformatter + rev: v1.5.1 hooks: - id: docformatter args: [--in-place, --wrap-summaries, "88", --wrap-descriptions, "88", --blank] - repo: https://github.com/psf/black - rev: 22.3.0 + rev: 22.12.0 hooks: - id: black - repo: https://github.com/PyCQA/flake8 - rev: 4.0.1 + rev: 6.0.0 hooks: - id: flake8 types: [python] @@ -74,7 +74,7 @@ repos: - id: interrogate args: [-v, --fail-under=40, src, tests] - repo: https://github.com/executablebooks/mdformat - rev: 0.7.14 + rev: 0.7.16 hooks: - id: mdformat additional_dependencies: [ @@ -83,11 +83,11 @@ repos: ] args: [--wrap, "88"] - repo: https://github.com/codespell-project/codespell - rev: v2.1.0 + rev: v2.2.2 hooks: - id: codespell - repo: https://github.com/pre-commit/mirrors-mypy - rev: 'v0.931' + rev: 'v0.991' hooks: - id: mypy args: [ @@ -102,7 +102,7 @@ repos: pass_filenames: false language_version: "3.9" - repo: https://github.com/mgedmin/check-manifest - rev: "0.48" + rev: "0.49" hooks: - id: check-manifest args: [--no-build-isolation] From d3294874c7c7c053064e5e51e925abbfb3d7de55 Mon Sep 17 00:00:00 2001 From: Tobias Raabe Date: Sat, 21 Jan 2023 13:16:24 +0100 Subject: [PATCH 2/3] Update hooks. --- .pre-commit-config.yaml | 108 ++++++++++++------------ pyproject.toml | 40 +++++++++ setup.cfg | 4 - src/pytask_stata/collect.py | 12 +-- src/pytask_stata/parametrize.py | 5 +- tests/test_collect.py | 8 +- tests/test_config.py | 2 +- tests/test_execute.py | 18 ++-- tests/test_normal_execution_w_plugin.py | 2 +- tests/test_parallel.py | 16 ++-- tests/test_parametrize.py | 8 +- 11 files changed, 127 insertions(+), 96 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index b2852cd..1fe7cd5 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -3,7 +3,8 @@ repos: rev: v4.4.0 hooks: - id: check-added-large-files - args: ['--maxkb=25'] + args: + - --maxkb=25 - id: check-case-conflict - id: check-merge-conflict - id: check-vcs-permalinks @@ -13,7 +14,9 @@ repos: - id: fix-byte-order-marker - id: mixed-line-ending - id: no-commit-to-branch - args: [--branch, main] + args: + - --branch + - main - id: trailing-whitespace - repo: https://github.com/pre-commit/pygrep-hooks rev: v1.10.0 @@ -24,90 +27,89 @@ repos: - id: python-no-log-warn - id: python-use-type-annotations - id: text-unicode-replacement-char -- repo: https://github.com/asottile/pyupgrade - rev: v3.3.1 - hooks: - - id: pyupgrade - args: [--py37-plus] - repo: https://github.com/asottile/reorder_python_imports rev: v3.9.0 hooks: - id: reorder-python-imports - args: [--py37-plus, --add-import, 'from __future__ import annotations'] + args: + - --py37-plus + - --add-import + - from __future__ import annotations - repo: https://github.com/asottile/setup-cfg-fmt rev: v2.2.0 hooks: - id: setup-cfg-fmt - repo: https://github.com/PyCQA/docformatter - rev: v1.5.1 + rev: v1.6.0.rc1 hooks: - id: docformatter - args: [--in-place, --wrap-summaries, "88", --wrap-descriptions, "88", --blank] + args: + - --in-place + - --wrap-summaries + - '88' + - --wrap-descriptions + - '88' + - --blank - repo: https://github.com/psf/black rev: 22.12.0 hooks: - id: black -- repo: https://github.com/PyCQA/flake8 - rev: 6.0.0 +- repo: https://github.com/charliermarsh/ruff-pre-commit + rev: v0.0.228 + hooks: + - id: ruff +- repo: https://github.com/dosisod/refurb + rev: v1.10.0 hooks: - - id: flake8 - types: [python] - additional_dependencies: [ - flake8-alfred, - flake8-bugbear, - flake8-builtins, - flake8-comprehensions, - flake8-docstrings, - flake8-eradicate, - flake8-print, - flake8-pytest-style, - flake8-todo, - flake8-typing-imports, - flake8-unused-arguments, - pep8-naming, - pydocstyle, - Pygments, - ] + - id: refurb + args: + - --ignore + - FURB126 - repo: https://github.com/econchick/interrogate rev: 1.5.0 hooks: - id: interrogate - args: [-v, --fail-under=40, src, tests] + args: + - -v + - --fail-under=40 + - src + - tests - repo: https://github.com/executablebooks/mdformat rev: 0.7.16 hooks: - id: mdformat - additional_dependencies: [ - mdformat-gfm, - mdformat-black, - ] - args: [--wrap, "88"] -- repo: https://github.com/codespell-project/codespell - rev: v2.2.2 - hooks: + additional_dependencies: + - mdformat-gfm + - mdformat-black + args: + - --wrap + - '88' +- repo: https://github.com/codespell-project/codespell + rev: v2.2.2 + hooks: - id: codespell - repo: https://github.com/pre-commit/mirrors-mypy - rev: 'v0.991' + rev: v0.991 hooks: - id: mypy - args: [ - --no-strict-optional, - --ignore-missing-imports, - ] - additional_dependencies: [ - attrs, - click, - types-setuptools - ] + args: + - --no-strict-optional + - --ignore-missing-imports + additional_dependencies: + - attrs + - click + - types-setuptools pass_filenames: false - repo: https://github.com/mgedmin/check-manifest - rev: "0.49" + rev: '0.49' hooks: - id: check-manifest - args: [--no-build-isolation] - additional_dependencies: [setuptools-scm, toml] + args: + - --no-build-isolation + additional_dependencies: + - setuptools-scm + - toml - repo: meta hooks: - id: check-hooks-apply - id: check-useless-excludes - # - id: identity # Prints all files passed to pre-commits. Debugging. diff --git a/pyproject.toml b/pyproject.toml index 35ff30f..f040661 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -22,3 +22,43 @@ warn_unused_ignores = true module = "tests.*" disallow_untyped_defs = false ignore_errors = true + + +[tool.ruff] +target-version = "py37" +select = ["ALL"] +fix = true +extend-ignore = [ + # Numpy docstyle + "D107", + "D203", + "D212", + "D213", + "D402", + "D413", + "D415", + "D416", + "D417", + # Others. + "D404", # Do not start module docstring with "This". + "RET504", # unnecessary variable assignment before return. + "S101", # raise errors for asserts. + "B905", # strict parameter for zip that was implemented in py310. + "I", # ignore isort + "ANN101", # type annotating self + "ANN102", # type annotating cls + "FBT", # flake8-boolean-trap + "EM", # flake8-errmsg + "ANN401", # flake8-annotate typing.Any + "PD", # pandas-vet + "COM812", # trailing comma missing, but black takes care of that +] + + +[tool.ruff.per-file-ignores] +"tests/*" = ["D", "ANN"] +"__init__.py" = ["D104"] + + +[tool.ruff.pydocstyle] +convention = "numpy" diff --git a/setup.cfg b/setup.cfg index 80e72bb..d955ee9 100644 --- a/setup.cfg +++ b/setup.cfg @@ -15,10 +15,6 @@ classifiers = Operating System :: OS Independent Programming Language :: Python :: 3 Programming Language :: Python :: 3 :: Only - Programming Language :: Python :: 3.7 - Programming Language :: Python :: 3.8 - Programming Language :: Python :: 3.9 - Programming Language :: Python :: 3.10 project_urls = Documentation = https://github.com/pytask-dev/pytask-stata Github = https://github.com/pytask-dev/pytask-stata diff --git a/src/pytask_stata/collect.py b/src/pytask_stata/collect.py index 0621b6a..4c2ae24 100644 --- a/src/pytask_stata/collect.py +++ b/src/pytask_stata/collect.py @@ -63,7 +63,7 @@ def pytask_collect_task( task = Task( base_name=name, path=path, - function=_copy_func(run_stata_script), # type: ignore + function=_copy_func(run_stata_script), # type: ignore[arg-type] depends_on=dependencies, produces=products, markers=markers, @@ -97,20 +97,14 @@ def pytask_collect_task( task.function = stata_function return task - else: - return None + return None def _parse_stata_mark(mark: Mark) -> Mark: """Parse a Stata mark.""" script, options = stata(**mark.kwargs) - parsed_kwargs = {} - for arg_name, value, default in [ # type: ignore - ("script", script, None), - ("options", options, []), - ]: - parsed_kwargs[arg_name] = value if value else default + parsed_kwargs = {"script": script or None, "options": options or []} mark = Mark("stata", (), parsed_kwargs) return mark diff --git a/src/pytask_stata/parametrize.py b/src/pytask_stata/parametrize.py index d2f49bf..3afec0e 100644 --- a/src/pytask_stata/parametrize.py +++ b/src/pytask_stata/parametrize.py @@ -11,6 +11,5 @@ @hookimpl def pytask_parametrize_kwarg_to_marker(obj: Callable[..., Any], kwargs: Any) -> None: """Attach parametrized stata arguments to the function with a marker.""" - if callable(obj): - if "stata" in kwargs: - pytask.mark.stata(**kwargs.pop("stata"))(obj) + if callable(obj) and "stata" in kwargs: + pytask.mark.stata(**kwargs.pop("stata"))(obj) diff --git a/tests/test_collect.py b/tests/test_collect.py index ea5102d..c4c87bc 100644 --- a/tests/test_collect.py +++ b/tests/test_collect.py @@ -8,9 +8,9 @@ from pytask_stata.collect import stata -@pytest.mark.unit +@pytest.mark.unit() @pytest.mark.parametrize( - "args, kwargs, expectation, expected", + ("args", "kwargs", "expectation", "expected"), [ ( (), @@ -32,9 +32,9 @@ def test_stata(args, kwargs, expectation, expected): assert options == expected -@pytest.mark.unit +@pytest.mark.unit() @pytest.mark.parametrize( - "mark, expectation, expected", + ("mark", "expectation", "expected"), [ ( Mark("stata", (), {"script": "script.do"}), diff --git a/tests/test_config.py b/tests/test_config.py index 479db98..95a1121 100644 --- a/tests/test_config.py +++ b/tests/test_config.py @@ -4,7 +4,7 @@ from pytask import main -@pytest.mark.end_to_end +@pytest.mark.end_to_end() def test_marker_is_configured(tmp_path): session = main({"paths": tmp_path}) diff --git a/tests/test_execute.py b/tests/test_execute.py index 5fb4a1b..5a94850 100644 --- a/tests/test_execute.py +++ b/tests/test_execute.py @@ -18,9 +18,9 @@ from tests.conftest import needs_stata -@pytest.mark.unit +@pytest.mark.unit() @pytest.mark.parametrize( - "stata, expectation", + ("stata", "expectation"), [(executable, does_not_raise()) for executable in STATA_COMMANDS] + [(None, pytest.raises(RuntimeError, match="Stata is needed"))], ) @@ -42,7 +42,7 @@ def test_pytask_execute_task_setup_raise_error(stata, platform, expectation): @needs_stata -@pytest.mark.end_to_end +@pytest.mark.end_to_end() def test_run_do_file(runner, tmp_path): task_source = """ import pytask @@ -72,7 +72,7 @@ def task_run_do_file(): @needs_stata -@pytest.mark.end_to_end +@pytest.mark.end_to_end() def test_run_do_file_w_task_decorator(runner, tmp_path): task_source = """ import pytask @@ -102,7 +102,7 @@ def run_do_file(): assert tmp_path.joinpath("script.log").exists() -@pytest.mark.end_to_end +@pytest.mark.end_to_end() def test_raise_error_if_stata_is_not_found(tmp_path, monkeypatch): task_source = """ import pytask @@ -117,7 +117,7 @@ def task_run_do_file(): # Hide Stata if available. monkeypatch.setattr( - "pytask_stata.config.shutil.which", lambda x: None # noqa: U100 + "pytask_stata.config.shutil.which", lambda x: None # noqa: ARG005 ) session = main({"paths": tmp_path}) @@ -127,7 +127,7 @@ def task_run_do_file(): @needs_stata -@pytest.mark.end_to_end +@pytest.mark.end_to_end() def test_run_do_file_w_wrong_cmd_option(runner, tmp_path): """Apparently, Stata simply discards wrong cmd options.""" task_source = """ @@ -152,7 +152,7 @@ def task_run_do_file(): @needs_stata -@pytest.mark.end_to_end +@pytest.mark.end_to_end() def test_run_do_file_by_passing_path(runner, tmp_path): """Replicates example under "Command Line Arguments" in Readme.""" task_source = """ @@ -178,7 +178,7 @@ def task_run_do_file(): @needs_stata -@pytest.mark.end_to_end +@pytest.mark.end_to_end() def test_run_do_file_fails_with_multiple_marks(runner, tmp_path): task_source = """ import pytask diff --git a/tests/test_normal_execution_w_plugin.py b/tests/test_normal_execution_w_plugin.py index 4bd592e..346d228 100644 --- a/tests/test_normal_execution_w_plugin.py +++ b/tests/test_normal_execution_w_plugin.py @@ -7,7 +7,7 @@ from pytask import cli -@pytest.mark.end_to_end +@pytest.mark.end_to_end() @pytest.mark.parametrize( "dependencies", [[], ["in.txt"], ["in_1.txt", "in_2.txt"]], diff --git a/tests/test_parallel.py b/tests/test_parallel.py index b7044cf..750411e 100644 --- a/tests/test_parallel.py +++ b/tests/test_parallel.py @@ -24,7 +24,7 @@ @needs_stata -@pytest.mark.end_to_end +@pytest.mark.end_to_end() def test_parallel_parametrization_over_source_files_w_parametrize(runner, tmp_path): source = """ import pytask @@ -52,7 +52,7 @@ def task_execute_do_file(): assert result.exit_code == ExitCode.OK duration_normal = time.time() - start - for name in ["1.dta", "2.dta"]: + for name in ("1.dta", "2.dta"): tmp_path.joinpath(name).unlink() start = time.time() @@ -64,7 +64,7 @@ def task_execute_do_file(): @needs_stata -@pytest.mark.end_to_end +@pytest.mark.end_to_end() def test_parallel_parametrization_over_source_files_w_loop(runner, tmp_path): source = """ import pytask @@ -98,7 +98,7 @@ def task_execute_do_file(): assert result.exit_code == ExitCode.OK duration_normal = time.time() - start - for name in ["1.dta", "2.dta"]: + for name in ("1.dta", "2.dta"): tmp_path.joinpath(name).unlink() start = time.time() @@ -110,7 +110,7 @@ def task_execute_do_file(): @needs_stata -@pytest.mark.end_to_end +@pytest.mark.end_to_end() def test_parallel_parametrization_over_source_file_w_parametrize(runner, tmp_path): source = """ import pytask @@ -140,7 +140,7 @@ def task_execute_do_file(): assert result.exit_code == ExitCode.OK duration_normal = time.time() - start - for name in ["output_1.dta", "output_2.dta"]: + for name in ("output_1.dta", "output_2.dta"): tmp_path.joinpath(name).unlink() start = time.time() @@ -152,7 +152,7 @@ def task_execute_do_file(): @needs_stata -@pytest.mark.end_to_end +@pytest.mark.end_to_end() def test_parallel_parametrization_over_source_file_w_loop(runner, tmp_path): source = """ import pytask @@ -180,7 +180,7 @@ def task_execute_do_file(): assert result.exit_code == ExitCode.OK duration_normal = time.time() - start - for name in ["output_1.dta", "output_2.dta"]: + for name in ("output_1.dta", "output_2.dta"): tmp_path.joinpath(name).unlink() start = time.time() diff --git a/tests/test_parametrize.py b/tests/test_parametrize.py index 917f460..9ac0009 100644 --- a/tests/test_parametrize.py +++ b/tests/test_parametrize.py @@ -11,7 +11,7 @@ @needs_stata -@pytest.mark.end_to_end +@pytest.mark.end_to_end() def test_parametrized_execution_of_do_file_w_parametrize(runner, tmp_path): task_source = """ import pytask @@ -41,7 +41,7 @@ def task_execute_do_file(): @needs_stata -@pytest.mark.end_to_end +@pytest.mark.end_to_end() def test_parametrized_execution_of_do_file_w_loop(runner, tmp_path): source = """ import pytask @@ -71,7 +71,7 @@ def task_execute_do_file(): @needs_stata -@pytest.mark.end_to_end +@pytest.mark.end_to_end() def test_parametrize_command_line_options_w_parametrize(runner, tmp_path): task_source = """ import pytask @@ -114,7 +114,7 @@ def task_execute_do_file(): @needs_stata -@pytest.mark.end_to_end +@pytest.mark.end_to_end() def test_parametrize_command_line_options_w_loop(runner, tmp_path): task_source = """ import pytask From d64d35557eae43c547ea27fe2cdd7f93f0f9c690 Mon Sep 17 00:00:00 2001 From: Tobias Raabe Date: Sat, 21 Jan 2023 13:17:01 +0100 Subject: [PATCH 3/3] Update changelog. --- CHANGES.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGES.md b/CHANGES.md index 325c37f..7d86f66 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -7,6 +7,7 @@ releases are available on [PyPI](https://pypi.org/project/pytask-stata) and ## 0.3.0 - 2023-xx-xx +- {pull}`24` adds ruff and refurb. - {pull}`25` adds docformatter. - {pull}`26` adds Python 3.11 to CI. - {pull}`28` aligns the package with pytask v0.3.