From eddcf1078d73d6b477eabc88bf895c88ab5b6fa6 Mon Sep 17 00:00:00 2001 From: Daniel Hollas Date: Wed, 15 May 2024 01:22:47 +0100 Subject: [PATCH] User ruff linter and formatter (#166) --- .github/dependabot.yml | 2 +- .pre-commit-config.yaml | 28 ++++++++-------------------- home/app_manager.py | 28 ++++++++++++++++++++-------- home/app_store.py | 12 ++++-------- home/start_page.py | 6 +++--- home/utils.py | 6 +++--- home/widgets.py | 3 +-- pyproject.toml | 31 +++++++++++++++++++++++++++++++ setup.py | 2 +- 9 files changed, 72 insertions(+), 46 deletions(-) create mode 100644 pyproject.toml diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 23a311e..ce0d77c 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -5,7 +5,7 @@ updates: - package-ecosystem: github-actions directory: / schedule: - interval: daily + interval: monthly groups: gha-dependencies: patterns: diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 473a502..1938ed9 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -13,31 +13,19 @@ repos: - id: trailing-whitespace exclude: miscellaneous/structures/SiO2.xyz + - repo: https://github.com/astral-sh/ruff-pre-commit + rev: v0.3.5 + hooks: + - id: ruff-format + exclude: ^docs/.* + - id: ruff + args: [--fix, --exit-non-zero-on-fix, --show-fixes] + - repo: https://github.com/jumanjihouse/pre-commit-hook-yamlfmt rev: 0.2.3 hooks: - id: yamlfmt - - repo: https://github.com/psf/black - rev: 24.3.0 - hooks: - - id: black - language_version: python3 # Should be a command that runs python3.6+ - - - repo: https://github.com/PyCQA/flake8 - rev: 7.0.0 - hooks: - - id: flake8 - args: [--count, --show-source, --statistics] - additional_dependencies: - - flake8-bugbear - - - repo: https://github.com/pycqa/isort - rev: 5.13.2 - hooks: - - id: isort - args: [--profile, black, --filter-files] - - repo: https://github.com/asottile/setup-cfg-fmt rev: v2.5.0 hooks: diff --git a/home/app_manager.py b/home/app_manager.py index 31c805e..a18b9e7 100644 --- a/home/app_manager.py +++ b/home/app_manager.py @@ -1,5 +1,5 @@ -# -*- coding: utf-8 -*- """Module that contains widgets for managing AiiDAlab applications.""" + from subprocess import CalledProcessError import ipywidgets as ipw @@ -207,7 +207,7 @@ def __init__(self, app, minimalistic=False): self.app.observe( self._refresh_prereleases, names=["has_prereleases", "installed_version"] ) - self._refresh_prereleases(change=dict(owner=self.app)) # initialize + self._refresh_prereleases(change={"owner": self.app}) # initialize children = [ ipw.HBox([self.header_warning]), @@ -347,19 +347,25 @@ def _refresh_widget_state(self, _=None): self.install_button.icon = ( "" if can_install and not detached - else warn_or_ban_icon if can_install else "" + else warn_or_ban_icon + if can_install + else "" ) if self.app.compatible: self.install_button.tooltip = ( "" if can_install and not detached - else tooltip_danger if can_install else "" + else tooltip_danger + if can_install + else "" ) else: self.install_button.tooltip = ( "" if installed and not detached - else tooltip_danger if installed else tooltip_incompatible + else tooltip_danger + if installed + else tooltip_incompatible ) self.install_button.description = ( "Install" @@ -376,7 +382,9 @@ def _refresh_widget_state(self, _=None): self.uninstall_button.tooltip = ( "" if can_uninstall and not detached - else tooltip_danger if can_uninstall else "" + else tooltip_danger + if can_uninstall + else "" ) # Update the update button state. @@ -390,13 +398,17 @@ def _refresh_widget_state(self, _=None): self.update_button.icon = ( "arrow-circle-up" if can_update and not detached - else warn_or_ban_icon if can_update else "" + else warn_or_ban_icon + if can_update + else "" ) self.update_button.button_style = "success" if can_update else "" self.update_button.tooltip = ( "" if can_update and not detached - else tooltip_danger if can_update else "" + else tooltip_danger + if can_update + else "" ) # Update the version_selector widget state. diff --git a/home/app_store.py b/home/app_store.py index f159f3f..e040229 100644 --- a/home/app_store.py +++ b/home/app_store.py @@ -1,5 +1,5 @@ -# -*- coding: utf-8 -*- """AiiDAlab app store.""" + import logging import ipywidgets as ipw @@ -21,7 +21,7 @@ def __init__(self): self.index = load_app_registry_index() except RuntimeError as error: logger.warning(error) - self.index = dict(apps=[], categories=[]) + self.index = {"apps": [], "categories": []} self.output = ipw.Output() # Apps per page. @@ -120,12 +120,8 @@ def change_vis_list(self, _=None): if self.category_filter.value: all_apps = self.apps_to_display - self.apps_to_display = ( - [] - ) # clear the array that contains all the apps to be displayed - self.app_corresponding_categories = ( - [] - ) # create a parallel array that contains corresponding category names + self.apps_to_display = [] # clear the array that contains all the apps to be displayed + self.app_corresponding_categories = [] # create a parallel array that contains corresponding category names # iterate over all categories for category in self.category_filter.value: category_key = self.category_title_key_mapping[category] diff --git a/home/start_page.py b/home/start_page.py index a384b77..f67d126 100644 --- a/home/start_page.py +++ b/home/start_page.py @@ -61,7 +61,7 @@ class AiidaLabHome: def __init__(self): self.config_fn = ".launcher.json" self.output = ipw.Output() - self._app_widgets = dict() + self._app_widgets = {} def _create_app_widget(self, name): """Create the widget representing the app on the home screen.""" @@ -93,7 +93,7 @@ def write_config(self, config): def read_config(self): if path.exists(self.config_fn): - return json.load(open(self.config_fn, "r")) + return json.load(open(self.config_fn)) return {"order": [], "hidden": []} # default config def render(self): @@ -125,7 +125,7 @@ def load_apps(self): apps.sort(key=lambda x: order.index(x) if x in order else -1) config["order"] = apps self.write_config(config) - return ["home"] + apps + return ["home", *apps] def move_updown(self, name, delta): """Move the app up/down on the start page.""" diff --git a/home/utils.py b/home/utils.py index 71ca51d..6bdfe49 100644 --- a/home/utils.py +++ b/home/utils.py @@ -33,7 +33,7 @@ def load_start_py(name): except TypeError: return mod.get_start_widget(appbase=appbase, jupbase=jupbase) except Exception: # pylint: disable=broad-except - return ipw.HTML("
{}
".format(sys.exc_info())) + return ipw.HTML(f"
{sys.exc_info()}
") def load_start_md(name): @@ -41,7 +41,7 @@ def load_start_md(name): fname = path.join(AIIDALAB_APPS, name, "start.md") try: md_src = open(fname).read() - md_src = md_src.replace("](./", "](../{}/".format(name)) + md_src = md_src.replace("](./", f"](../{name}/") html = markdown(md_src) # open links in new window/tab @@ -52,7 +52,7 @@ def load_start_md(name): return ipw.HTML(html) except Exception as exc: # pylint: disable=broad-except - return ipw.HTML("Could not load start.md: {}".format(str(exc))) + return ipw.HTML(f"Could not load start.md: {exc!s}") def load_logo(app): diff --git a/home/widgets.py b/home/widgets.py index a0ac4cc..64dd0f9 100644 --- a/home/widgets.py +++ b/home/widgets.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- """AiiDAlab basic widgets.""" from threading import Timer @@ -104,7 +103,7 @@ class AppStatusInfoWidget(ipw.HTML): "and avoid compatibility isssues." ) - MESSAGES_UPDATES = { + MESSAGES_UPDATES = { # noqa: RUF012 AppStatus.CANNOT_REACH_REGISTRY: f'
' f'{Theme.ICONS.APP_UPDATE_AVAILABLE_UNKNOWN} ' "Cannot reach server.
", diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..b3563e9 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,31 @@ +[build-system] +# this version is required to support reading of version in setup.cfg +requires = ["setuptools>=46.4.0"] +build-backend = "setuptools.build_meta" + +[tool.ruff] +line-length = 88 +show-fixes = true +target-version = "py38" + +[tool.ruff.lint] +ignore = ["E501", "E402", "B904", "TRY003"] +select = [ + "A", # flake8-builtins + "ARG", # flake8-unused-arguments + "B", # flake8-bugbear + "C4", # flake8-comprehensions + "E", # pycodestyle + "F", # pyflakes + "I", # isort + "N", # pep8-naming + "PLE", # pylint error rules + "PLW", # pylint warning rules + "PLC", # pylint convention rules + "RUF", # ruff-specific rules + "TRY", # Tryceratops + "UP" # pyupgrade +] + +[tool.ruff.lint.per-file-ignores] +"tests/*" = ["ARG001"] diff --git a/setup.py b/setup.py index 59b746b..63e14cb 100644 --- a/setup.py +++ b/setup.py @@ -1,5 +1,5 @@ -# -*- coding: utf8 -*- """This file is required for editable installs of the package.""" + from setuptools import setup setup()