diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index e7f8d356..36bb502e 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -76,25 +76,16 @@ jobs: with: python-version: 3.9 # This step ensures that everything is installed - - name: Install code cleaning components + - name: Upgrade pip run: | python -m pip install --upgrade pip - python -m pip install -e '.[dev]' - - - name: Lint code - uses: psf/black@stable - - name: Flake code - run: | - python -m flake8 src tests - - - name: Check import ordering - uses: isort/isort-action@master - with: - configuration: --check-only + - name: Run Ruff + uses: astral-sh/ruff-action@v1 - name: Validate pyproject.toml run: | + python -m pip install "validate-pyproject[all]" python -m validate_pyproject pyproject.toml conda-dev-test: diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index d477f46d..83b2201e 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,25 +1,13 @@ repos: - # First, autoflake the code to avoid issues that could be solved quickly - - repo: https://github.com/myint/autoflake - rev: v2.3.1 - hooks: - - id: autoflake - args: ["--in-place", "--remove-all-unused-imports"] - # Then, flake - - repo: https://github.com/PyCQA/flake8 - rev: 7.1.0 - hooks: - - id: flake8 - additional_dependencies: - - "flake8-typing-imports" - - "Flake8-pyproject" - # Next, sort imports - - repo: https://github.com/PyCQA/isort - rev: 5.12.0 - hooks: - - id: isort - # Finally, lint - - repo: https://github.com/psf/black - rev: 23.1.0 - hooks: - - id: black \ No newline at end of file + - repo: https://github.com/astral-sh/ruff-pre-commit + # ruff version + rev: v0.6.2 + hooks: + # run the linter + - id: ruff + # run the formatter + - id: ruff-format + - repo: https://github.com/abravalheri/validate-pyproject + rev: v0.10.1 + hooks: + - id: validate-pyproject \ No newline at end of file diff --git a/bin/lint.sh b/bin/lint.sh index 3d90d260..1cf86826 100755 --- a/bin/lint.sh +++ b/bin/lint.sh @@ -4,11 +4,9 @@ dir=$(dirname "$0") cd "$dir/.." exitCode=0 -black src tests +ruff check code=$?; test $code -eq 0 || exitCode=$code -isort src tests -code=$?; test $code -eq 0 || exitCode=$code -python -m flake8 src tests +ruff format --check code=$?; test $code -eq 0 || exitCode=$code validate-pyproject pyproject.toml code=$?; test $code -eq 0 || exitCode=$code diff --git a/dev-environment.yml b/dev-environment.yml index 9030c5bc..452a3796 100644 --- a/dev-environment.yml +++ b/dev-environment.yml @@ -35,12 +35,6 @@ dependencies: - qtconsole != 5.4.2 - typing_extensions != 4.6.0 # Developer tools - - autopep8 - - black >= 23.1.0 - - flake8 >= 7.1.0 - - flake8-pyproject - - flake8-typing-imports - - isort - myst-parser - pre-commit - pyqt5-sip @@ -49,6 +43,7 @@ dependencies: - pytest-cov - pytest-env - pytest-qt + - ruff - sphinx - sphinx-copybutton - sphinx_rtd_theme diff --git a/pyproject.toml b/pyproject.toml index 3b63f407..feb874e3 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -53,13 +53,7 @@ dependencies = [ # NB: Keep this in sync with dev-environment.yml! # Development tools dev = [ - "autopep8", - "black >= 23.1.0", "build", - "flake8 >= 7.1.0", - "flake8-pyproject", - "flake8-typing-imports", - "isort", "myst-parser", "pre-commit", "pyqt5", @@ -67,6 +61,7 @@ dev = [ "pytest-cov", "pytest-env", "pytest-qt", + "ruff", "sphinx", "sphinx-copybutton", "sphinx-rtd-theme", @@ -91,16 +86,19 @@ include-package-data = true [tool.setuptools.packages.find] where = ["src"] -# Thanks to Flake8-pyproject, we can configure flake8 here! -[tool.flake8] -exclude = ["bin", "build", "docs", "dist"] +# ruff configuration +[tool.ruff] +line-length = 88 +src = ["src", "tests"] +include = ["pyproject.toml", "src/**/*.py", "tests/**/*.py"] +extend-exclude = ["bin", "build", "dist", "doc", "scripts"] + +[tool.ruff.lint] extend-ignore = ["E203"] -# See https://black.readthedocs.io/en/stable/guides/using_black_with_other_tools.html#flake8 -max-line-length = 88 -min_python_version = "3.8" -[tool.isort] -profile = "black" +[tool.ruff.lint.per-file-ignores] +# Ignore `E402` (import violations) in all `__init__.py` files, and in `path/to/file.py`. +"__init__.py" = ["E402", "F401"] [tool.pytest.ini_options] addopts = "-s -p no:faulthandler" diff --git a/src/napari_imagej/types/widget_mappings.py b/src/napari_imagej/types/widget_mappings.py index 0212ad29..e2a2fa8d 100644 --- a/src/napari_imagej/types/widget_mappings.py +++ b/src/napari_imagej/types/widget_mappings.py @@ -22,7 +22,7 @@ def _widget_preference( - func: Callable[["jc.ModuleItem", Union[type, str]], Optional[str]] + func: Callable[["jc.ModuleItem", Union[type, str]], Optional[str]], ) -> Callable[["jc.ModuleItem", Union[type, str]], Optional[str]]: PREFERENCE_FUNCTIONS.append(func) return func diff --git a/tests/utilities/test_module_utils.py b/tests/utilities/test_module_utils.py index daedc3b3..9b268071 100644 --- a/tests/utilities/test_module_utils.py +++ b/tests/utilities/test_module_utils.py @@ -589,17 +589,17 @@ def foo( import inspect assert "a" in args - assert args["a"]["annotation"] == inspect._empty + assert args["a"]["annotation"] is inspect._empty assert args["a"]["options"] == dict(tooltip="We don't use this") assert "value" not in args["a"] assert "b" in args - assert args["b"]["annotation"] == str + assert args["b"]["annotation"] is str assert "options" not in args["b"] assert "value" not in args["b"] assert "c" in args - assert args["c"]["annotation"] == Image + assert args["c"]["annotation"] is Image assert args["c"]["options"] == dict(choices=get_layers) assert "value" not in args["c"] @@ -609,12 +609,12 @@ def foo( assert "value" not in args["d"] assert "e" in args - assert args["e"]["annotation"] == inspect._empty + assert args["e"]["annotation"] is inspect._empty assert "options" not in args["e"] assert args["e"]["value"] == "default" assert "f" in args - assert args["f"]["annotation"] == str + assert args["f"]["annotation"] is str assert "options" not in args["f"] assert args["f"]["value"] == "also default"