diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 715999e..d518f9d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -37,10 +37,13 @@ jobs: - name: Install the workflow call library run: | python3 -m pip install .[docs,lint,tests] - - name: Run flake8 + - name: Clean build files run: | - python3 -m flake8 . - python3 -m nbqa flake8 . + git clean -xdf + - name: Run ruff + run: | + python3 -m ruff . + python3 -m nbqa ruff . - name: Run isort run: | python3 -m isort --check --diff . diff --git a/open_in_cloud_workflow/add_installation_cells.py b/open_in_cloud_workflow/add_installation_cells.py index d62686b..bcfbd83 100644 --- a/open_in_cloud_workflow/add_installation_cells.py +++ b/open_in_cloud_workflow/add_installation_cells.py @@ -98,7 +98,7 @@ def _package_is_imported(package_import: str, cell: nbformat.NotebookNode) -> bo return f"import {package_import}" in cell.source or f"from {package_import}" in cell.source -def __main__( +def __main__( # noqa: N807 work_dir: str, nb_pattern: str, cloud_provider: str, fem_on_cloud_packages: str, pip_packages: str ) -> None: """Add installation cells on top of every notebook in the work directory matching the prescribed pattern.""" diff --git a/open_in_cloud_workflow/replace_images_in_markdown.py b/open_in_cloud_workflow/replace_images_in_markdown.py index 6cefc24..7c7c523 100644 --- a/open_in_cloud_workflow/replace_images_in_markdown.py +++ b/open_in_cloud_workflow/replace_images_in_markdown.py @@ -32,7 +32,7 @@ def replace_images_in_markdown( return updated_nb_cells -def __main__(work_dir: str, nb_pattern: str) -> None: +def __main__(work_dir: str, nb_pattern: str) -> None: # noqa: N807 """Replace images in every notebook in the work directory matching the prescribed pattern.""" images_as_base64 = glob_images(work_dir) diff --git a/open_in_cloud_workflow/replace_links_in_markdown.py b/open_in_cloud_workflow/replace_links_in_markdown.py index 60d3f91..b5d2f9a 100644 --- a/open_in_cloud_workflow/replace_links_in_markdown.py +++ b/open_in_cloud_workflow/replace_links_in_markdown.py @@ -44,7 +44,7 @@ def replace_links_in_markdown( return updated_nb_cells -def __main__( +def __main__( # noqa: N807 work_dir: str, nb_pattern: str, cloud_provider: str, publisher: typing.Union[str, PublishOnBaseClass] ) -> None: """Replace links in every notebook in the work directory matching the prescribed pattern.""" diff --git a/pyproject.toml b/pyproject.toml index 1d756d1..2ff290c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -47,14 +47,9 @@ docs = [ "sphinx" ] lint = [ - "flake8", - "flake8-annotations", - "flake8-docstrings", - "flake8-import-restrictions", - "flake8-isort", - "Flake8-pyproject", - "flake8-quotes", + "isort", "mypy", + "ruff", "yamllint" ] tests = [ @@ -65,21 +60,6 @@ tests = [ "requests" ] -[tool.flake8] -max-line-length = 120 -show-source = true -docstring-convention = "numpy" -inline-quotes = "double" -imr241_exclude = ["open_in_cloud_workflow", "open_in_cloud_workflow.*"] -imr245_include = "*" -imr245_exclude = ["open_in_cloud_workflow", "open_in_cloud_workflow.*"] -ignore = ["ANN101", "W503"] -exclude = [".eggs", "build", "dist"] -per-file-ignores = [ - "open_in_cloud_workflow/__init__.py: F401", - "tests/data/**/*.py: D100, I004" -] - [tool.isort] line_length = 120 multi_line_output = 4 @@ -90,7 +70,6 @@ combine_as_imports = true check_untyped_defs = true disallow_any_unimported = true disallow_untyped_defs = true -exclude = "(^\\.eggs|^build|^dist|conftest\\.py$)" no_implicit_optional = true pretty = true show_error_codes = true @@ -105,3 +84,18 @@ ignore_missing_imports = true [[tool.mypy.overrides]] module = "requests" ignore_missing_imports = true + +[tool.ruff] +line-length = 120 +select = ["ANN", "D", "E", "F", "ICN", "N", "Q", "RUF", "W"] +ignore = ["ANN101"] + +[tool.ruff.per-file-ignores] +"open_in_cloud_workflow/__init__.py" = ["F401"] +"tests/data/**/*.py" = ["D100"] + +[tool.ruff.pycodestyle] +max-doc-length = 120 + +[tool.ruff.pydocstyle] +convention = "numpy" diff --git a/tests/conftest.py b/tests/conftest.py index 1819132..bd71aaa 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -25,34 +25,34 @@ def root_directory() -> str: @pytest.fixture def open_notebook(root_directory: str) -> typing.Callable[[str, str, typing.Optional[str]], nbformat.NotebookNode]: """Return a fixture to open a local notebook.""" - def _(local_directory: str, filename: str, data_directory: str = None) -> nbformat.NotebookNode: + def _( local_directory: str, filename: str, data_directory: typing.Optional[str] = None) -> nbformat.NotebookNode: """Open notebook with nbformat.""" if data_directory is None: data_directory = os.path.join(root_directory, "tests", "data") filename = os.path.join(data_directory, local_directory, filename + ".ipynb") with open(filename, "r") as f: - nb = nbformat.read(f, as_version=4) + nb = nbformat.read(f, as_version=4) # type: ignore[no-untyped-call] nb._filename = filename - return nb + return nb # type: ignore[no-any-return] return _ @pytest.fixture def publish_on_artifact() -> PublishOnArtifact: """Return an artifact publisher.""" - return publish_on("artifact@open-in-colab") + return publish_on("artifact@open-in-colab") # type: ignore[return-value] @pytest.fixture def publish_on_drive() -> PublishOnDrive: """Return a Google Drive publisher.""" - return publish_on("drive@GitHub/open_in_colab_workflow") + return publish_on("drive@GitHub/open_in_colab_workflow") # type: ignore[return-value] @pytest.fixture def publish_on_github() -> PublishOnGitHub: """Return a GitHub publisher.""" - return publish_on("github@fem-on-colab/open-in-colab-workflow@open-in-colab") + return publish_on("github@fem-on-colab/open-in-colab-workflow@open-in-colab") # type: ignore[return-value] @pytest.fixture(params=["publish_on_artifact", "publish_on_drive", "publish_on_github"]) @@ -60,4 +60,4 @@ def publisher(request: _pytest.fixtures.SubRequest) -> PublishOnBaseClass: """Parameterize over publishers.""" if request.param == "publish_on_drive" and "RCLONE_CONFIG_DRIVE_TOKEN" not in os.environ: pytest.skip("Missing rclone environment variables") - return request.getfixturevalue(request.param) + return request.getfixturevalue(request.param) # type: ignore[no-any-return] diff --git a/tests/data/add_installation_cells/from_numpy_import.ipynb b/tests/data/add_installation_cells/from_numpy_import.ipynb index c8f1b3e..62ea680 100644 --- a/tests/data/add_installation_cells/from_numpy_import.ipynb +++ b/tests/data/add_installation_cells/from_numpy_import.ipynb @@ -7,7 +7,7 @@ "metadata": {}, "outputs": [], "source": [ - "from numpy import * # noqa: F401, F403, IMR241, IMR243, IMR245" + "from numpy import * # noqa: F403" ] } ], diff --git a/tests/data/add_installation_cells/import_mpi4py_numpy.ipynb b/tests/data/add_installation_cells/import_mpi4py_numpy.ipynb index c5edbf3..da527c9 100644 --- a/tests/data/add_installation_cells/import_mpi4py_numpy.ipynb +++ b/tests/data/add_installation_cells/import_mpi4py_numpy.ipynb @@ -8,7 +8,7 @@ "outputs": [], "source": [ "import mpi4py # type: ignore[import-not-found] # noqa: F401\n", - "import numpy # noqa: F401" + "import numpy as np # noqa: F401" ] } ], diff --git a/tests/data/add_installation_cells/import_numpy.ipynb b/tests/data/add_installation_cells/import_numpy.ipynb index d038790..e0eeba2 100644 --- a/tests/data/add_installation_cells/import_numpy.ipynb +++ b/tests/data/add_installation_cells/import_numpy.ipynb @@ -7,7 +7,7 @@ "metadata": {}, "outputs": [], "source": [ - "import numpy # noqa: F401" + "import numpy as np # noqa: F401" ] } ], diff --git a/tests/data/add_installation_cells/import_numpy_markdown.ipynb b/tests/data/add_installation_cells/import_numpy_markdown.ipynb index a0f7f8a..26eec52 100644 --- a/tests/data/add_installation_cells/import_numpy_markdown.ipynb +++ b/tests/data/add_installation_cells/import_numpy_markdown.ipynb @@ -15,7 +15,7 @@ "metadata": {}, "outputs": [], "source": [ - "import numpy # noqa: F401" + "import numpy as np # noqa: F401" ] } ], diff --git a/tests/data/add_installation_cells/import_numpy_scipy.ipynb b/tests/data/add_installation_cells/import_numpy_scipy.ipynb index 386b404..b4f4b0e 100644 --- a/tests/data/add_installation_cells/import_numpy_scipy.ipynb +++ b/tests/data/add_installation_cells/import_numpy_scipy.ipynb @@ -7,7 +7,7 @@ "metadata": {}, "outputs": [], "source": [ - "import numpy # noqa: F401\n", + "import numpy as np # noqa: F401\n", "import scipy # type: ignore[import-not-found] # noqa: F401" ] } diff --git a/tests/data/replace_images_in_markdown/image_and_code.ipynb b/tests/data/replace_images_in_markdown/image_and_code.ipynb index 873c24b..8218541 100644 --- a/tests/data/replace_images_in_markdown/image_and_code.ipynb +++ b/tests/data/replace_images_in_markdown/image_and_code.ipynb @@ -16,7 +16,7 @@ "metadata": {}, "outputs": [], "source": [ - "import numpy # noqa: F401" + "import numpy as np # noqa: F401" ] } ], diff --git a/tests/data/replace_links_in_markdown/link_and_code.ipynb b/tests/data/replace_links_in_markdown/link_and_code.ipynb index 91c5d82..4e5da16 100644 --- a/tests/data/replace_links_in_markdown/link_and_code.ipynb +++ b/tests/data/replace_links_in_markdown/link_and_code.ipynb @@ -15,7 +15,7 @@ "metadata": {}, "outputs": [], "source": [ - "import numpy # noqa: F401" + "import numpy as np # noqa: F401" ] } ],