From 88033afb2146b58a037e82103b05b4d74a2289a1 Mon Sep 17 00:00:00 2001 From: "Douglas Cerna (Soy Douglas)" Date: Mon, 27 May 2024 19:22:05 +0200 Subject: [PATCH 1/3] Add ruff to pre-commit configuration --- .flake8 | 18 ------------------ .pre-commit-config.yaml | 26 +++++--------------------- 2 files changed, 5 insertions(+), 39 deletions(-) delete mode 100644 .flake8 diff --git a/.flake8 b/.flake8 deleted file mode 100644 index 24bed2f..0000000 --- a/.flake8 +++ /dev/null @@ -1,18 +0,0 @@ -[flake8] -exclude = .tox, .git, __pycache__, .cache, build, dist, *.pyc, *.egg-info, .eggs -# Error codes: -# - https://flake8.pycqa.org/en/latest/user/error-codes.html -# - https://pycodestyle.pycqa.org/en/latest/intro.html#error-codes -# - https://github.com/PyCQA/flake8-bugbear#list-of-warnings -# -# E203: whitespace before `,`, `;` or `:` -# E402: module level import not at top of file -# E501: line too long -# W503: line break before binary operator -# F811: redefinition of unused name from line N -ignore = - E203, - E402, - E501, - W503, - F811 diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index b00d653..1bc1cd6 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -3,25 +3,9 @@ repos: rev: v4.6.0 hooks: - id: end-of-file-fixer -- repo: https://github.com/asottile/pyupgrade - rev: v3.15.2 +- repo: https://github.com/astral-sh/ruff-pre-commit + rev: v0.4.5 hooks: - - id: pyupgrade - args: [--py38-plus] -- repo: https://github.com/asottile/reorder_python_imports - rev: v3.12.0 - hooks: - - id: reorder-python-imports - args: [--py38-plus] -- repo: https://github.com/psf/black - rev: "23.12.1" - hooks: - - id: black - args: [--safe, --quiet] -- repo: https://github.com/pycqa/flake8 - rev: "7.0.0" - hooks: - - id: flake8 - additional_dependencies: - - flake8-bugbear==24.2.6 - - flake8-comprehensions==3.14.0 + - id: ruff + args: [--fix, --exit-non-zero-on-fix] + - id: ruff-format From a5c33e50c7d62f06d3d61c7ddc2edbc8bf245c1e Mon Sep 17 00:00:00 2001 From: "Douglas Cerna (Soy Douglas)" Date: Mon, 27 May 2024 19:32:11 +0200 Subject: [PATCH 2/3] Add Ruff configuration file --- ruff.toml | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 ruff.toml diff --git a/ruff.toml b/ruff.toml new file mode 100644 index 0000000..65e7364 --- /dev/null +++ b/ruff.toml @@ -0,0 +1,20 @@ +[lint] +# Rule reference: https://docs.astral.sh/ruff/rules/ +select = [ + "B", + "C4", + "E", + "F", + "I", + "UP", + "W", +] +ignore = [ + "B904", + "E501", + "F811", + "UP031", +] + +[lint.isort] +force-single-line = true From b4b11d8ed22df2a994c4cf7a85495d30786da45d Mon Sep 17 00:00:00 2001 From: "Douglas Cerna (Soy Douglas)" Date: Mon, 27 May 2024 19:32:36 +0200 Subject: [PATCH 3/3] Run pre-commit --- amuser/am_api_ability.py | 2 +- amuser/am_browser_ability.py | 6 +-- amuser/am_browser_auth_ability.py | 2 +- amuser/am_browser_file_explorer_ability.py | 10 ++-- amuser/am_browser_ingest_ability.py | 9 ++-- amuser/am_browser_jobs_tasks_ability.py | 6 +-- ...m_browser_preservation_planning_ability.py | 22 +++----- amuser/am_browser_ss_ability.py | 10 ++-- amuser/am_browser_transfer_ability.py | 6 +-- amuser/am_browser_transfer_ingest_ability.py | 18 +++---- amuser/am_docker_ability.py | 22 +++----- amuser/am_localfs_ability.py | 2 +- amuser/am_mets_ability.py | 13 +++-- amuser/am_ssh_ability.py | 43 +++++---------- amuser/amuser.py | 6 +-- amuser/base.py | 1 + amuser/selenium_ability.py | 2 +- amuser/utils.py | 2 +- features/steps/aip_encryption_steps.py | 53 ++++++------------- features/steps/black_box_steps.py | 44 ++++++--------- features/steps/capture_output_steps.py | 2 +- features/steps/cca_dip_steps.py | 2 +- features/steps/indexless_steps.py | 20 +++---- features/steps/infinite_aips.py | 2 +- features/steps/manual_normalization_steps.py | 2 +- features/steps/mediaconch_steps.py | 46 ++++++++-------- features/steps/mets_steps.py | 18 +++---- .../performance_stdout_no_write_steps.py | 8 +-- features/steps/pid_binding_steps.py | 7 ++- features/steps/steps.py | 10 ++-- features/steps/utils.py | 37 ++++++------- features/steps/uuids_for_directories_steps.py | 26 ++++----- simplebrowsertest.py | 1 - 33 files changed, 176 insertions(+), 284 deletions(-) diff --git a/amuser/am_api_ability.py b/amuser/am_api_ability.py index dc725b6..87f967c 100644 --- a/amuser/am_api_ability.py +++ b/amuser/am_api_ability.py @@ -3,6 +3,7 @@ This module contains the ``ArchivematicaAPIAbility`` class, which represents a user's ability to use Archivematica's APIs to interact with Archivematica. """ + import logging import os import time @@ -11,7 +12,6 @@ from . import base - logger = logging.getLogger("amuser.api") diff --git a/amuser/am_browser_ability.py b/amuser/am_browser_ability.py index 5a85b6c..0505730 100644 --- a/amuser/am_browser_ability.py +++ b/amuser/am_browser_ability.py @@ -5,6 +5,7 @@ Archivematica. This class provides an interface to Selenium for opening browser windows and interacting with Archivematica's GUIs. """ + import logging import time @@ -24,7 +25,6 @@ from . import base from . import constants as c - logger = logging.getLogger("amuser.browser") @@ -183,8 +183,8 @@ def initiate_reingest(self, aip_uuid, reingest_type="metadata-only"): }.get(reingest_type) if not type_selector: raise ArchivematicaBrowserAbilityError( - "Unable to initiate a reingest of type {} on AIP" - " {}".format(reingest_type, aip_uuid) + f"Unable to initiate a reingest of type {reingest_type} on AIP" + f" {aip_uuid}" ) while True: type_input_el = self.driver.find_element(By.CSS_SELECTOR, type_selector) diff --git a/amuser/am_browser_auth_ability.py b/amuser/am_browser_auth_ability.py index 94e6ba4..39a2db9 100644 --- a/amuser/am_browser_auth_ability.py +++ b/amuser/am_browser_auth_ability.py @@ -1,4 +1,5 @@ """Archivematica Authentication Ability""" + import logging from selenium.common.exceptions import TimeoutException @@ -8,7 +9,6 @@ from . import selenium_ability - logger = logging.getLogger("amuser.authentication") diff --git a/amuser/am_browser_file_explorer_ability.py b/amuser/am_browser_file_explorer_ability.py index 3624b49..98b6695 100644 --- a/amuser/am_browser_file_explorer_ability.py +++ b/amuser/am_browser_file_explorer_ability.py @@ -1,4 +1,5 @@ """Archivematica Browser File Explorer Ability""" + import logging import time @@ -13,7 +14,6 @@ from . import constants as c from . import selenium_ability - logger = logging.getLogger("amuser.fileexplorer") @@ -245,10 +245,10 @@ def get_xpath_matches_folder_text(folder_text): """ return ( "div[contains(@class, 'tree-label') and" - " descendant::span[starts-with(normalize-space(text()), '{0}') and" + f" descendant::span[starts-with(normalize-space(text()), '{folder_text}') and" " starts-with(normalize-space(substring-after(" "normalize-space(text())," - " '{0}')), '(')]]".format(folder_text) + f" '{folder_text}')), '(')]]" ) @@ -256,9 +256,7 @@ def folder_label2icon_xpath(folder_label_xpath): """Given XPATH for TS folder label, return XPATH for its folder icon. """ - return "{}/preceding-sibling::i[@class='tree-branch-head']".format( - folder_label_xpath - ) + return f"{folder_label_xpath}/preceding-sibling::i[@class='tree-branch-head']" def folder_label2children_xpath(folder_label_xpath): diff --git a/amuser/am_browser_ingest_ability.py b/amuser/am_browser_ingest_ability.py index 636e2e6..e27df79 100644 --- a/amuser/am_browser_ingest_ability.py +++ b/amuser/am_browser_ingest_ability.py @@ -1,4 +1,5 @@ """Archivematica Ingest Tab Ability""" + import logging import os import tempfile @@ -105,7 +106,7 @@ def get_mets(self, transfer_name, sip_uuid=None, parse_xml=True): self.am_url, sip_uuid ) self.navigate(aip_preview_url) - mets_path = "storeAIP/{0}-{1}/METS.{1}.xml".format(transfer_name, sip_uuid) + mets_path = f"storeAIP/{transfer_name}-{sip_uuid}/METS.{sip_uuid}.xml" handles_before = self.driver.window_handles self.navigate_to_aip_directory_and_click(mets_path) self.wait_for_new_window(handles_before) @@ -116,10 +117,8 @@ def get_mets(self, transfer_name, sip_uuid=None, parse_xml=True): while self.driver.current_url.strip() == "about:blank": if attempts > self.max_check_mets_loaded_attempts: msg = ( - "Exceeded maximum allowable attempts ({}) for checking" - " if the METS file has loaded.".format( - self.max_check_mets_loaded_attempts - ) + f"Exceeded maximum allowable attempts ({self.max_check_mets_loaded_attempts}) for checking" + " if the METS file has loaded." ) logger.warning(msg) raise ArchivematicaBrowserMETSAbilityError(msg) diff --git a/amuser/am_browser_jobs_tasks_ability.py b/amuser/am_browser_jobs_tasks_ability.py index 0f8bfb5..4845c5c 100644 --- a/amuser/am_browser_jobs_tasks_ability.py +++ b/amuser/am_browser_jobs_tasks_ability.py @@ -1,4 +1,5 @@ """Archivematica Browser Jobs & Tasks Ability""" + import logging import sys import time @@ -10,7 +11,6 @@ from . import selenium_ability from . import utils - logger = logging.getLogger("amuser.jobstasks") @@ -197,9 +197,7 @@ def get_job_uuid( # The job is taking a long time to complete. Half the # amount of checking to avoid stack-overflow. logger.warning( - "Recursion limit close to being reached: level: {} <= {}".format( - level, sys.getrecursionlimit() - ) + f"Recursion limit close to being reached: level: {level} <= {sys.getrecursionlimit()}" ) time.sleep(self.quick_wait) else: diff --git a/amuser/am_browser_preservation_planning_ability.py b/amuser/am_browser_preservation_planning_ability.py index 37ca5f7..e4f2ad4 100644 --- a/amuser/am_browser_preservation_planning_ability.py +++ b/amuser/am_browser_preservation_planning_ability.py @@ -1,4 +1,5 @@ """Archivematica Browser Preservation Planning Ability""" + import logging from selenium.common.exceptions import NoSuchElementException @@ -7,7 +8,6 @@ from . import selenium_ability - logger = logging.getLogger("amuser.preservationplanning") @@ -157,8 +157,8 @@ def save_policy_check_command(self, policy_command, description): option.click() break self.driver.find_element(By.ID, "id_description").send_keys(description) - js_script = 'document.getElementById("id_command").value =' " `{}`;".format( - policy_command + js_script = ( + 'document.getElementById("id_command").value =' f" `{policy_command}`;" ) self.driver.execute_script(js_script) self.driver.find_element(By.ID, "id_script_type").send_keys("Python") @@ -213,9 +213,7 @@ def search_for_fpr_rule(self, purpose, format_, command_description): description. Uses the FPR asynchronous search input. """ terse_format = format_.split(":")[2].strip() - search_term = '"{}" "{}" "{}"'.format( - purpose, terse_format, command_description - ) + search_term = f'"{purpose}" "{terse_format}" "{command_description}"' self.search_rules(search_term) def ensure_fpr_rule_enabled(self, purpose, format_, command_description): @@ -234,17 +232,13 @@ def ensure_fpr_rule_enabled(self, purpose, format_, command_description): ] if not disabled_rules: logger.info( - 'Tried to enable FPR rule with purpose "{}" that runs command "{}"' - ' against files with format "{}" but did not find it'.format( - purpose, command_description, format_ - ) + f'Tried to enable FPR rule with purpose "{purpose}" that runs command "{command_description}"' + f' against files with format "{format_}" but did not find it' ) return assert len(disabled_rules) == 1, ( - 'Expected to enable one FPR rule with purpose "{}" that runs command "{}"' - ' against files with format "{}" but found {} disabled rules'.format( - purpose, command_description, format_, len(disabled_rules) - ) + f'Expected to enable one FPR rule with purpose "{purpose}" that runs command "{command_description}"' + f' against files with format "{format_}" but found {len(disabled_rules)} disabled rules' ) rule = disabled_rules[0] rule.find_element(By.CSS_SELECTOR, "td:nth-child(6) a:nth-child(3)").click() diff --git a/amuser/am_browser_ss_ability.py b/amuser/am_browser_ss_ability.py index a8ad4e6..34f52b9 100644 --- a/amuser/am_browser_ss_ability.py +++ b/amuser/am_browser_ss_ability.py @@ -1,4 +1,5 @@ """Archivematica Browser Storage Service Ability""" + import logging import pprint import time @@ -11,7 +12,6 @@ from . import selenium_ability from . import utils - logger = logging.getLogger("amuser.ss") @@ -43,8 +43,8 @@ def approve_aip_delete_request(self, aip_uuid): matching_rows.append(row_el) if len(matching_rows) != 1: raise ArchivematicaBrowserStorageServiceAbilityError( - "More than one delete request row {} matches AIP" - " {}".format(len(matching_rows), aip_uuid) + f"More than one delete request row {len(matching_rows)} matches AIP" + f" {aip_uuid}" ) matching_rows[0].find_element(By.TAG_NAME, "textarea").send_keys("Cuz wanna") matching_rows[0].find_element(By.CSS_SELECTOR, 'input[name="approve"]').click() @@ -318,9 +318,9 @@ def add_replicator_to_default_aip_stor_loc(self, replicator_location_uuid): break if not found_replicator: raise ArchivematicaBrowserStorageServiceAbilityError( - "Unable to find replicator location {} as a possible replicator" + f"Unable to find replicator location {replicator_location_uuid} as a possible replicator" " for the default AIP Storage" - " location".format(replicator_location_uuid) + " location" ) self.driver.find_element(By.CSS_SELECTOR, "input[type=submit]").click() diff --git a/amuser/am_browser_transfer_ability.py b/amuser/am_browser_transfer_ability.py index 294526a..d161e89 100644 --- a/amuser/am_browser_transfer_ability.py +++ b/amuser/am_browser_transfer_ability.py @@ -1,4 +1,5 @@ """Archivematica Transfer Tab Ability""" + import logging import os import time @@ -11,7 +12,6 @@ from . import constants as c from . import selenium_ability - logger = logging.getLogger("amuser.transfer") @@ -249,9 +249,7 @@ def approve_transfer( re-click the micro-service
to make the hidden