From daa1b5a313d0ca8bca5220e9e76aceb4a4097112 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?dni=20=E2=9A=A1?= Date: Wed, 17 Apr 2024 07:36:22 +0200 Subject: [PATCH] chore: adhere to ruff's `RUF` rules, 2nd try (#2420) * chore: adhere to ruff's `RUF` rules, 2nd try closes #2382 --- lnbits/app.py | 12 ++++++------ lnbits/commands.py | 11 ++++++----- lnbits/core/views/payment_api.py | 2 +- lnbits/core/views/public_api.py | 2 +- lnbits/extension_manager.py | 9 +++++---- lnbits/middleware.py | 2 +- lnbits/nodes/lndrest.py | 2 +- lnbits/settings.py | 2 +- lnbits/tasks.py | 6 +++--- lnbits/utils/exchange_rates.py | 2 +- pyproject.toml | 6 ++++-- tests/wallets/fixtures/models.py | 2 +- tests/wallets/helpers.py | 6 +++++- 13 files changed, 36 insertions(+), 28 deletions(-) diff --git a/lnbits/app.py b/lnbits/app.py index a27b49138..b4970421f 100644 --- a/lnbits/app.py +++ b/lnbits/app.py @@ -300,7 +300,7 @@ async def check_installed_extension_files(ext: InstallableExtension) -> bool: zip_files = glob.glob(os.path.join(settings.lnbits_data_folder, "zips", "*.zip")) - if f"./{str(ext.zip_path)}" not in zip_files: + if f"./{ext.zip_path!s}" not in zip_files: await ext.download_archive() ext.extract_archive() @@ -403,7 +403,7 @@ def register_all_ext_routes(app: FastAPI): try: register_ext_routes(app, ext) except Exception as e: - logger.error(f"Could not load extension `{ext.code}`: {str(e)}") + logger.error(f"Could not load extension `{ext.code}`: {e!s}") def initialize_server_logger(): @@ -474,7 +474,7 @@ def register_exception_handlers(app: FastAPI): async def exception_handler(request: Request, exc: Exception): etype, _, tb = sys.exc_info() traceback.print_exception(etype, exc, tb) - logger.error(f"Exception: {str(exc)}") + logger.error(f"Exception: {exc!s}") # Only the browser sends "text/html" request # not fail proof, but everything else get's a JSON response if ( @@ -483,7 +483,7 @@ def register_exception_handlers(app: FastAPI): and "text/html" in request.headers["accept"] ): return template_renderer().TemplateResponse( - request, "error.html", {"err": f"Error: {str(exc)}"} + request, "error.html", {"err": f"Error: {exc!s}"} ) return JSONResponse( @@ -495,7 +495,7 @@ def register_exception_handlers(app: FastAPI): async def validation_exception_handler( request: Request, exc: RequestValidationError ): - logger.error(f"RequestValidationError: {str(exc)}") + logger.error(f"RequestValidationError: {exc!s}") # Only the browser sends "text/html" request # not fail proof, but everything else get's a JSON response @@ -507,7 +507,7 @@ def register_exception_handlers(app: FastAPI): return template_renderer().TemplateResponse( request, "error.html", - {"err": f"Error: {str(exc)}"}, + {"err": f"Error: {exc!s}"}, ) return JSONResponse( diff --git a/lnbits/commands.py b/lnbits/commands.py index 35f9bfa6a..584d0ca4c 100644 --- a/lnbits/commands.py +++ b/lnbits/commands.py @@ -124,7 +124,8 @@ def database_migrate(): async def db_migrate(): - asyncio.create_task(migrate_databases()) + task = asyncio.create_task(migrate_databases()) + await task async def migrate_databases(): @@ -492,7 +493,7 @@ async def extensions_uninstall( click.echo(f"Failed to uninstall '{extension}' Error: '{ex.detail}'.") return False, ex.detail except Exception as ex: - click.echo(f"Failed to uninstall '{extension}': {str(ex)}.") + click.echo(f"Failed to uninstall '{extension}': {ex!s}.") return False, str(ex) @@ -530,7 +531,7 @@ async def install_extension( click.echo(f"Failed to install '{extension}' Error: '{ex.detail}'.") return False, ex.detail except Exception as ex: - click.echo(f"Failed to install '{extension}': {str(ex)}.") + click.echo(f"Failed to install '{extension}': {ex!s}.") return False, str(ex) @@ -582,7 +583,7 @@ async def update_extension( click.echo(f"Failed to update '{extension}' Error: '{ex.detail}.") return False, ex.detail except Exception as ex: - click.echo(f"Failed to update '{extension}': {str(ex)}.") + click.echo(f"Failed to update '{extension}': {ex!s}.") return False, str(ex) @@ -605,7 +606,7 @@ async def _select_release( return latest_repo_releases[source_repo] if len(latest_repo_releases) == 1: - return latest_repo_releases[list(latest_repo_releases.keys())[0]] + return latest_repo_releases[next(iter(latest_repo_releases.keys()))] repos = list(latest_repo_releases.keys()) repos.sort() diff --git a/lnbits/core/views/payment_api.py b/lnbits/core/views/payment_api.py index 19570b831..4b827fe20 100644 --- a/lnbits/core/views/payment_api.py +++ b/lnbits/core/views/payment_api.py @@ -434,6 +434,6 @@ async def api_payments_decode(data: DecodePayment) -> JSONResponse: return JSONResponse(invoice.data) except Exception as exc: return JSONResponse( - {"message": f"Failed to decode: {str(exc)}"}, + {"message": f"Failed to decode: {exc!s}"}, status_code=HTTPStatus.BAD_REQUEST, ) diff --git a/lnbits/core/views/public_api.py b/lnbits/core/views/public_api.py index cd2ae485b..371775754 100644 --- a/lnbits/core/views/public_api.py +++ b/lnbits/core/views/public_api.py @@ -50,7 +50,7 @@ async def api_public_payment_longpolling(payment_hash): cancel_scope.cancel() cancel_scope = asyncio.create_task(payment_info_receiver()) - asyncio.create_task(timeouter(cancel_scope)) + asyncio.create_task(timeouter(cancel_scope)) # noqa: RUF006 if response: return response diff --git a/lnbits/extension_manager.py b/lnbits/extension_manager.py index eaf71d832..62224896e 100644 --- a/lnbits/extension_manager.py +++ b/lnbits/extension_manager.py @@ -491,8 +491,9 @@ class InstallableExtension(BaseModel): settings.lnbits_upgraded_extensions, ) ) - settings.lnbits_upgraded_extensions = clean_upgraded_exts + [ - f"{self.hash}/{self.id}" + settings.lnbits_upgraded_extensions = [ + *clean_upgraded_exts, + f"{self.hash}/{self.id}", ] def clean_extension_files(self): @@ -639,7 +640,7 @@ class InstallableExtension(BaseModel): extension_list += [ext] extension_id_list += [e.id] except Exception as e: - logger.warning(f"Manifest {url} failed with '{str(e)}'") + logger.warning(f"Manifest {url} failed with '{e!s}'") return extension_list @@ -666,7 +667,7 @@ class InstallableExtension(BaseModel): extension_releases.append(explicit_release) except Exception as e: - logger.warning(f"Manifest {url} failed with '{str(e)}'") + logger.warning(f"Manifest {url} failed with '{e!s}'") return extension_releases diff --git a/lnbits/middleware.py b/lnbits/middleware.py index ba2bbbcb2..7079a901a 100644 --- a/lnbits/middleware.py +++ b/lnbits/middleware.py @@ -179,7 +179,7 @@ class ExtensionsRedirectMiddleware: req_tail_path = req_path.split("/")[len(from_path) :] elements = [ - e for e in ([redirect["ext_id"]] + redirect_to + req_tail_path) if e != "" + e for e in ([redirect["ext_id"], *redirect_to, *req_tail_path]) if e != "" ] return "/" + "/".join(elements) diff --git a/lnbits/nodes/lndrest.py b/lnbits/nodes/lndrest.py index a50c89546..6547d60e0 100644 --- a/lnbits/nodes/lndrest.py +++ b/lnbits/nodes/lndrest.py @@ -174,7 +174,7 @@ class LndRestNode(Node): status_code=HTTPStatus.BAD_REQUEST, detail="Channel point required" ) - asyncio.create_task(self._close_channel(point, force)) + asyncio.create_task(self._close_channel(point, force)) # noqa: RUF006 async def get_channels(self) -> list[NodeChannel]: normal, pending, closed = await asyncio.gather( diff --git a/lnbits/settings.py b/lnbits/settings.py index 0bfa27245..a55a37a29 100644 --- a/lnbits/settings.py +++ b/lnbits/settings.py @@ -506,7 +506,7 @@ def send_admin_user_to_saas(): except Exception as e: logger.error( "error sending super_user to saas:" - f" {settings.lnbits_saas_callback}. Error: {str(e)}" + f" {settings.lnbits_saas_callback}. Error: {e!s}" ) diff --git a/lnbits/tasks.py b/lnbits/tasks.py index 284fa5d53..4b5cf8d7a 100644 --- a/lnbits/tasks.py +++ b/lnbits/tasks.py @@ -39,7 +39,7 @@ def create_unique_task(name: str, coro: Coroutine): try: unique_tasks[name].cancel() except Exception as exc: - logger.warning(f"error while cancelling task `{name}`: {str(exc)}") + logger.warning(f"error while cancelling task `{name}`: {exc!s}") task = asyncio.create_task(coro) unique_tasks[name] = task return task @@ -54,12 +54,12 @@ def cancel_all_tasks(): try: task.cancel() except Exception as exc: - logger.warning(f"error while cancelling task: {str(exc)}") + logger.warning(f"error while cancelling task: {exc!s}") for name, task in unique_tasks.items(): try: task.cancel() except Exception as exc: - logger.warning(f"error while cancelling task `{name}`: {str(exc)}") + logger.warning(f"error while cancelling task `{name}`: {exc!s}") async def catch_everything_and_restart(func): diff --git a/lnbits/utils/exchange_rates.py b/lnbits/utils/exchange_rates.py index 7ea0d09da..daa75b938 100644 --- a/lnbits/utils/exchange_rates.py +++ b/lnbits/utils/exchange_rates.py @@ -145,7 +145,7 @@ currencies = { "TJS": "Tajikistani Somoni", "TMT": "Turkmenistani Manat", "TND": "Tunisian Dinar", - "TOP": "Tongan Paʻanga", + "TOP": "Tongan Pa'anga", "TRY": "Turkish Lira", "TTD": "Trinidad and Tobago Dollar", "TWD": "New Taiwan Dollar", diff --git a/pyproject.toml b/pyproject.toml index 26acc78bd..9bfe4df01 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -173,9 +173,11 @@ extend-exclude = [ # C - mccabe # N - naming # UP - pyupgrade -select = ["F", "E", "W", "I", "A", "C", "N", "UP"] +# RUF - ruff specific rules +select = ["F", "E", "W", "I", "A", "C", "N", "UP", "RUF"] # UP007: pyupgrade: use X | Y instead of Optional. (python3.10) -ignore = ["UP007"] +# RUF012: mutable-class-default +ignore = ["UP007", "RUF012"] # Allow autofix for all enabled rules (when `--fix`) is provided. fixable = ["ALL"] diff --git a/tests/wallets/fixtures/models.py b/tests/wallets/fixtures/models.py index 88067a2d1..d0e90acae 100644 --- a/tests/wallets/fixtures/models.py +++ b/tests/wallets/fixtures/models.py @@ -120,7 +120,7 @@ class WalletTest(BaseModel): self.dict() | { "description": f"""{self.description}:{mock.description or ""}""", - "mocks": self.mocks + [mock], + "mocks": [*self.mocks, mock], "skip": self.skip or mock.skip, } ) diff --git a/tests/wallets/helpers.py b/tests/wallets/helpers.py index 8b2d1db1e..6d6734b03 100644 --- a/tests/wallets/helpers.py +++ b/tests/wallets/helpers.py @@ -1,5 +1,7 @@ +import functools import importlib import json +import operator from typing import Dict, List import pytest @@ -24,7 +26,9 @@ def wallet_fixtures_from_json(path) -> List["WalletTest"]: fn_tests = _tests_for_function(funding_sources, fn_name, fn) _merge_dict_of_lists(tests, fn_tests) - all_tests = sum([tests[fs_name] for fs_name in tests], []) + all_tests: list["WalletTest"] = functools.reduce( + operator.iadd, [tests[fs_name] for fs_name in tests], [] + ) return all_tests